mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-30 13:47:41 +00:00
Clipboard sync on new connections
Summary: Timestamp on changes to clipboards so that when a new device connects it can sync both clipboards to the most recent updated clipboard. Reviewers: #kde_connect, albertvaka Reviewed By: #kde_connect, albertvaka Subscribers: albertvaka, sredman, kdeconnect Tags: #kde_connect Differential Revision: https://phabricator.kde.org/D22585
This commit is contained in:
parent
4be5800b8b
commit
5dc65ee909
@ -41,6 +41,7 @@ public class ClipboardListener {
|
|||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private String currentContent;
|
private String currentContent;
|
||||||
|
private long updateTimestamp;
|
||||||
|
|
||||||
private ClipboardManager cm = null;
|
private ClipboardManager cm = null;
|
||||||
private ClipboardManager.OnPrimaryClipChangedListener listener;
|
private ClipboardManager.OnPrimaryClipChangedListener listener;
|
||||||
@ -76,7 +77,7 @@ public class ClipboardListener {
|
|||||||
if (content.equals(currentContent)) {
|
if (content.equals(currentContent)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
updateTimestamp = System.currentTimeMillis();
|
||||||
currentContent = content;
|
currentContent = content;
|
||||||
|
|
||||||
for (ClipboardObserver observer : observers) {
|
for (ClipboardObserver observer : observers) {
|
||||||
@ -91,8 +92,17 @@ public class ClipboardListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCurrentContent() {
|
||||||
|
return currentContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getUpdateTimestamp() {
|
||||||
|
return updateTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public void setText(String text) {
|
public void setText(String text) {
|
||||||
|
updateTimestamp = System.currentTimeMillis();
|
||||||
currentContent = text;
|
currentContent = text;
|
||||||
cm.setText(text);
|
cm.setText(text);
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,31 @@ import org.kde.kdeconnect_tp.R;
|
|||||||
@PluginFactory.LoadablePlugin
|
@PluginFactory.LoadablePlugin
|
||||||
public class ClipboardPlugin extends Plugin {
|
public class ClipboardPlugin extends Plugin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet containing just clipboard contents, sent when a device updates its clipboard.
|
||||||
|
* <p>
|
||||||
|
* The body should look like so:
|
||||||
|
* {
|
||||||
|
* "content": "password"
|
||||||
|
* }
|
||||||
|
*/
|
||||||
private final static String PACKET_TYPE_CLIPBOARD = "kdeconnect.clipboard";
|
private final static String PACKET_TYPE_CLIPBOARD = "kdeconnect.clipboard";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet containing clipboard contents and a timestamp that the contents were last updated, sent
|
||||||
|
* on first connection
|
||||||
|
* <p>
|
||||||
|
* The timestamp is milliseconds since epoch. It can be 0, which indicates that the clipboard
|
||||||
|
* update time is currently unknown.
|
||||||
|
* <p>
|
||||||
|
* The body should look like so:
|
||||||
|
* {
|
||||||
|
* "timestamp": 542904563213,
|
||||||
|
* "content": "password"
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
private final static String PACKET_TYPE_CLIPBOARD_CONNECT = "kdeconnect.clipboard.connect";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return context.getResources().getString(R.string.pref_plugin_clipboard);
|
return context.getResources().getString(R.string.pref_plugin_clipboard);
|
||||||
@ -43,19 +66,44 @@ public class ClipboardPlugin extends Plugin {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onPacketReceived(NetworkPacket np) {
|
public boolean onPacketReceived(NetworkPacket np) {
|
||||||
String content = np.getString("content");
|
String content = np.getString("content");
|
||||||
ClipboardListener.instance(context).setText(content);
|
switch (np.getType()) {
|
||||||
return true;
|
case (PACKET_TYPE_CLIPBOARD):
|
||||||
|
ClipboardListener.instance(context).setText(content);
|
||||||
|
return true;
|
||||||
|
case(PACKET_TYPE_CLIPBOARD_CONNECT):
|
||||||
|
long packetTime = np.getLong("timestamp");
|
||||||
|
// If the packetTime is 0, it means the timestamp is unknown (so do nothing).
|
||||||
|
if (packetTime == 0 || packetTime < ClipboardListener.instance(context).getUpdateTimestamp()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClipboardListener.instance(context).setText(content);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
throw new UnsupportedOperationException("Unknown packet type: " + np.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ClipboardListener.ClipboardObserver observer = content -> {
|
private final ClipboardListener.ClipboardObserver observer = this::propagateClipboard;
|
||||||
|
|
||||||
|
private void propagateClipboard(String content) {
|
||||||
NetworkPacket np = new NetworkPacket(ClipboardPlugin.PACKET_TYPE_CLIPBOARD);
|
NetworkPacket np = new NetworkPacket(ClipboardPlugin.PACKET_TYPE_CLIPBOARD);
|
||||||
np.set("content", content);
|
np.set("content", content);
|
||||||
device.sendPacket(np);
|
device.sendPacket(np);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
private void sendConnectPacket() {
|
||||||
|
String content = ClipboardListener.instance(context).getCurrentContent();
|
||||||
|
NetworkPacket np = new NetworkPacket(ClipboardPlugin.PACKET_TYPE_CLIPBOARD_CONNECT);
|
||||||
|
long timestamp = ClipboardListener.instance(context).getUpdateTimestamp();
|
||||||
|
np.set("timestamp", timestamp);
|
||||||
|
np.set("content", content);
|
||||||
|
device.sendPacket(np);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreate() {
|
public boolean onCreate() {
|
||||||
ClipboardListener.instance(context).registerObserver(observer);
|
ClipboardListener.instance(context).registerObserver(observer);
|
||||||
|
sendConnectPacket();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,12 +114,12 @@ public class ClipboardPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getSupportedPacketTypes() {
|
public String[] getSupportedPacketTypes() {
|
||||||
return new String[]{PACKET_TYPE_CLIPBOARD};
|
return new String[]{PACKET_TYPE_CLIPBOARD, PACKET_TYPE_CLIPBOARD_CONNECT};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getOutgoingPacketTypes() {
|
public String[] getOutgoingPacketTypes() {
|
||||||
return new String[]{PACKET_TYPE_CLIPBOARD};
|
return new String[]{PACKET_TYPE_CLIPBOARD, PACKET_TYPE_CLIPBOARD_CONNECT};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user