mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-22 18:07:55 +00:00
Merge branch 'philipc/kdeconnect-android-philipc/file-transfer-docs'
This commit is contained in:
commit
1000453081
@ -28,6 +28,8 @@ import org.kde.kdeconnect.NetworkPacket;
|
|||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import androidx.annotation.WorkerThread;
|
||||||
|
|
||||||
|
|
||||||
public abstract class BaseLink {
|
public abstract class BaseLink {
|
||||||
|
|
||||||
@ -88,5 +90,6 @@ public abstract class BaseLink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TO OVERRIDE, should be sync
|
//TO OVERRIDE, should be sync
|
||||||
|
@WorkerThread
|
||||||
public abstract boolean sendPacket(NetworkPacket np, Device.SendPacketStatusCallback callback);
|
public abstract boolean sendPacket(NetworkPacket np, Device.SendPacketStatusCallback callback);
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,8 @@ import java.io.Reader;
|
|||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import androidx.annotation.WorkerThread;
|
||||||
|
|
||||||
public class BluetoothLink extends BaseLink {
|
public class BluetoothLink extends BaseLink {
|
||||||
private final ConnectionMultiplexer connection;
|
private final ConnectionMultiplexer connection;
|
||||||
private final InputStream input;
|
private final InputStream input;
|
||||||
@ -150,6 +152,7 @@ public class BluetoothLink extends BaseLink {
|
|||||||
Log.i("BluetoothLink", "Finished sending message");
|
Log.i("BluetoothLink", "Finished sending message");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
@Override
|
@Override
|
||||||
public boolean sendPacket(NetworkPacket np, final Device.SendPacketStatusCallback callback) {
|
public boolean sendPacket(NetworkPacket np, final Device.SendPacketStatusCallback callback) {
|
||||||
|
|
||||||
|
@ -44,6 +44,8 @@ import java.nio.channels.NotYetConnectedException;
|
|||||||
|
|
||||||
import javax.net.ssl.SSLSocket;
|
import javax.net.ssl.SSLSocket;
|
||||||
|
|
||||||
|
import androidx.annotation.WorkerThread;
|
||||||
|
|
||||||
public class LanLink extends BaseLink {
|
public class LanLink extends BaseLink {
|
||||||
|
|
||||||
public interface LinkDisconnectedCallback {
|
public interface LinkDisconnectedCallback {
|
||||||
@ -137,6 +139,7 @@ public class LanLink extends BaseLink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Blocking, do not call from main thread
|
//Blocking, do not call from main thread
|
||||||
|
@WorkerThread
|
||||||
@Override
|
@Override
|
||||||
public boolean sendPacket(NetworkPacket np, final Device.SendPacketStatusCallback callback) {
|
public boolean sendPacket(NetworkPacket np, final Device.SendPacketStatusCallback callback) {
|
||||||
if (socket == null) {
|
if (socket == null) {
|
||||||
|
@ -28,6 +28,8 @@ import org.kde.kdeconnect.Backends.BasePairingHandler;
|
|||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
import org.kde.kdeconnect.NetworkPacket;
|
import org.kde.kdeconnect.NetworkPacket;
|
||||||
|
|
||||||
|
import androidx.annotation.WorkerThread;
|
||||||
|
|
||||||
public class LoopbackLink extends BaseLink {
|
public class LoopbackLink extends BaseLink {
|
||||||
|
|
||||||
public LoopbackLink(Context context, BaseLinkProvider linkProvider) {
|
public LoopbackLink(Context context, BaseLinkProvider linkProvider) {
|
||||||
@ -44,6 +46,7 @@ public class LoopbackLink extends BaseLink {
|
|||||||
return new LoopbackPairingHandler(device, callback);
|
return new LoopbackPairingHandler(device, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
@Override
|
@Override
|
||||||
public boolean sendPacket(NetworkPacket in, Device.SendPacketStatusCallback callback) {
|
public boolean sendPacket(NetworkPacket in, Device.SendPacketStatusCallback callback) {
|
||||||
packageReceived(in);
|
packageReceived(in);
|
||||||
|
@ -57,6 +57,8 @@ import java.util.Vector;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
import androidx.annotation.AnyThread;
|
||||||
|
import androidx.annotation.WorkerThread;
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
@ -621,18 +623,22 @@ public class Device implements BaseLink.PacketReceiver {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@AnyThread
|
||||||
public void sendPacket(NetworkPacket np) {
|
public void sendPacket(NetworkPacket np) {
|
||||||
sendPacket(np, -1, defaultCallback);
|
sendPacket(np, -1, defaultCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AnyThread
|
||||||
public void sendPacket(NetworkPacket np, int replaceID) {
|
public void sendPacket(NetworkPacket np, int replaceID) {
|
||||||
sendPacket(np, replaceID, defaultCallback);
|
sendPacket(np, replaceID, defaultCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
public boolean sendPacketBlocking(NetworkPacket np) {
|
public boolean sendPacketBlocking(NetworkPacket np) {
|
||||||
return sendPacketBlocking(np, defaultCallback);
|
return sendPacketBlocking(np, defaultCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AnyThread
|
||||||
public void sendPacket(final NetworkPacket np, final SendPacketStatusCallback callback) {
|
public void sendPacket(final NetworkPacket np, final SendPacketStatusCallback callback) {
|
||||||
sendPacket(np, -1, callback);
|
sendPacket(np, -1, callback);
|
||||||
}
|
}
|
||||||
@ -643,6 +649,7 @@ public class Device implements BaseLink.PacketReceiver {
|
|||||||
* @param replaceID If positive, replaces all unsent packages with the same replaceID
|
* @param replaceID If positive, replaces all unsent packages with the same replaceID
|
||||||
* @param callback A callback for success/failure
|
* @param callback A callback for success/failure
|
||||||
*/
|
*/
|
||||||
|
@AnyThread
|
||||||
public void sendPacket(final NetworkPacket np, int replaceID, final SendPacketStatusCallback callback) {
|
public void sendPacket(final NetworkPacket np, int replaceID, final SendPacketStatusCallback callback) {
|
||||||
if (packetQueue == null) {
|
if (packetQueue == null) {
|
||||||
callback.onFailure(new Exception("Device disconnected!"));
|
callback.onFailure(new Exception("Device disconnected!"));
|
||||||
@ -665,6 +672,15 @@ public class Device implements BaseLink.PacketReceiver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send {@code np} over one of this device's connected {@link #links}.
|
||||||
|
*
|
||||||
|
* @param np the packet to send
|
||||||
|
* @param callback a callback that can receive realtime updates
|
||||||
|
* @return true if the packet was sent ok, false otherwise
|
||||||
|
* @see BaseLink#sendPacket(NetworkPacket, SendPacketStatusCallback)
|
||||||
|
*/
|
||||||
|
@WorkerThread
|
||||||
public boolean sendPacketBlocking(final NetworkPacket np, final SendPacketStatusCallback callback) {
|
public boolean sendPacketBlocking(final NetworkPacket np, final SendPacketStatusCallback callback) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -43,9 +43,27 @@ import java.io.OutputStream;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import androidx.annotation.GuardedBy;
|
||||||
import androidx.core.content.FileProvider;
|
import androidx.core.content.FileProvider;
|
||||||
import androidx.documentfile.provider.DocumentFile;
|
import androidx.documentfile.provider.DocumentFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type of {@link BackgroundJob} that reads Files from another device.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* We receive the requests as {@link NetworkPacket}s.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Each packet should have a 'filename' property and a payload. If the payload is missing,
|
||||||
|
* we'll just create an empty file. You can add new packets anytime via
|
||||||
|
* {@link #addNetworkPacket(NetworkPacket)}.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* The I/O-part of this file reading is handled by {@link #receiveFile(InputStream, OutputStream)}.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see CompositeUploadFileJob
|
||||||
|
*/
|
||||||
public class CompositeReceiveFileJob extends BackgroundJob<Device, Void> {
|
public class CompositeReceiveFileJob extends BackgroundJob<Device, Void> {
|
||||||
private final ReceiveNotification receiveNotification;
|
private final ReceiveNotification receiveNotification;
|
||||||
private NetworkPacket currentNetworkPacket;
|
private NetworkPacket currentNetworkPacket;
|
||||||
@ -56,8 +74,11 @@ public class CompositeReceiveFileJob extends BackgroundJob<Device, Void> {
|
|||||||
private long prevProgressPercentage;
|
private long prevProgressPercentage;
|
||||||
|
|
||||||
private final Object lock; //Use to protect concurrent access to the variables below
|
private final Object lock; //Use to protect concurrent access to the variables below
|
||||||
|
@GuardedBy("lock")
|
||||||
private final List<NetworkPacket> networkPacketList;
|
private final List<NetworkPacket> networkPacketList;
|
||||||
|
@GuardedBy("lock")
|
||||||
private int totalNumFiles;
|
private int totalNumFiles;
|
||||||
|
@GuardedBy("lock")
|
||||||
private long totalPayloadSize;
|
private long totalPayloadSize;
|
||||||
private boolean isRunning;
|
private boolean isRunning;
|
||||||
|
|
||||||
|
@ -31,8 +31,28 @@ import org.kde.kdeconnect_tp.R;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import androidx.annotation.GuardedBy;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type of {@link BackgroundJob} that sends Files to another device.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* We represent the individual upload requests as {@link NetworkPacket}s.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Each packet should have a 'filename' property and a payload. If the payload is
|
||||||
|
* missing, we'll just send an empty file. You can add new packets anytime via
|
||||||
|
* {@link #addNetworkPacket(NetworkPacket)}.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* The I/O-part of this file sending is handled by
|
||||||
|
* {@link Device#sendPacketBlocking(NetworkPacket, Device.SendPacketStatusCallback)}.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see CompositeReceiveFileJob
|
||||||
|
* @see SendPacketStatusCallback
|
||||||
|
*/
|
||||||
public class CompositeUploadFileJob extends BackgroundJob<Device, Void> {
|
public class CompositeUploadFileJob extends BackgroundJob<Device, Void> {
|
||||||
private boolean isRunning;
|
private boolean isRunning;
|
||||||
private Handler handler;
|
private Handler handler;
|
||||||
@ -44,10 +64,13 @@ public class CompositeUploadFileJob extends BackgroundJob<Device, Void> {
|
|||||||
private UploadNotification uploadNotification;
|
private UploadNotification uploadNotification;
|
||||||
|
|
||||||
private final Object lock; //Use to protect concurrent access to the variables below
|
private final Object lock; //Use to protect concurrent access to the variables below
|
||||||
|
@GuardedBy("lock")
|
||||||
private final List<NetworkPacket> networkPacketList;
|
private final List<NetworkPacket> networkPacketList;
|
||||||
private NetworkPacket currentNetworkPacket;
|
private NetworkPacket currentNetworkPacket;
|
||||||
private final Device.SendPacketStatusCallback sendPacketStatusCallback;
|
private final Device.SendPacketStatusCallback sendPacketStatusCallback;
|
||||||
|
@GuardedBy("lock")
|
||||||
private int totalNumFiles;
|
private int totalNumFiles;
|
||||||
|
@GuardedBy("lock")
|
||||||
private long totalPayloadSize;
|
private long totalPayloadSize;
|
||||||
|
|
||||||
CompositeUploadFileJob(@NonNull Device device, @NonNull Callback<Void> callback) {
|
CompositeUploadFileJob(@NonNull Device device, @NonNull Callback<Void> callback) {
|
||||||
@ -169,6 +192,9 @@ public class CompositeUploadFileJob extends BackgroundJob<Device, Void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this to send metadata ahead of all the other {@link #networkPacketList packets}.
|
||||||
|
*/
|
||||||
private void sendUpdatePacket() {
|
private void sendUpdatePacket() {
|
||||||
NetworkPacket np = new NetworkPacket(SharePlugin.PACKET_TYPE_SHARE_REQUEST_UPDATE);
|
NetworkPacket np = new NetworkPacket(SharePlugin.PACKET_TYPE_SHARE_REQUEST_UPDATE);
|
||||||
|
|
||||||
|
@ -49,6 +49,13 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.WorkerThread;
|
import androidx.annotation.WorkerThread;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Plugin for sharing and receiving files and uris.
|
||||||
|
* <p>
|
||||||
|
* All of the associated I/O work is scheduled on background
|
||||||
|
* threads by {@link BackgroundJobHandler}.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
@PluginFactory.LoadablePlugin
|
@PluginFactory.LoadablePlugin
|
||||||
public class SharePlugin extends Plugin {
|
public class SharePlugin extends Plugin {
|
||||||
final static String ACTION_CANCEL_SHARE = "org.kde.kdeconnect.Plugins.SharePlugin.CancelShare";
|
final static String ACTION_CANCEL_SHARE = "org.kde.kdeconnect.Plugins.SharePlugin.CancelShare";
|
||||||
|
@ -37,6 +37,13 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scheduler for {@link BackgroundJob} objects.
|
||||||
|
* <p>
|
||||||
|
* We use an internal {@link ThreadPoolExecutor} to catch Exceptions and
|
||||||
|
* pass them along to {@link #handleUncaughtException(Future, Throwable)}.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
public class BackgroundJobHandler {
|
public class BackgroundJobHandler {
|
||||||
private static final String TAG = BackgroundJobHandler.class.getSimpleName();
|
private static final String TAG = BackgroundJobHandler.class.getSimpleName();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user