Skip to content

CodePandaaAI/Sync360

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

106 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Sync360 app icon

Sync360

When the device is nearby, the path should be nearby too.

Direct text and file sharing between Android and Desktop devices on the same local network.

Kotlin Compose Multiplatform Ktor Android License

Android → Android

Sync360 Android-to-Android text and file transfer demo Nearby discovery, receiver approval, and direct Android-to-Android text/file transfer.

Desktop → Android

Sync360 Desktop-to-Android file transfer demo 1.51 GB transferred from Desktop to Android in 22.333 seconds in one manual test.

Nearby sharing should not need a cloud detour

We have all done it: send a file to ourselves, wait for it to upload, open another device, wait for it to download, and save it again—even when both devices are in the same room.

Sync360 is for that nearby moment.

open app -> find nearby device -> choose what to send -> receiver approves -> send directly

The current app discovers other Sync360 devices on the same local network and transfers content directly between them. The transfer path does not use an account, cloud storage, or a Sync360 backend. It depends on the local network and the two devices involved.

Chat apps and cloud drives are great when the other person is far away. Sync360 is being built for the simpler case: the destination is already nearby.

Current status

Sync360 has a working Android-to-Android MVP for text and multiple-file transfer. The Desktop/JVM app now uses the same shared flow, and Desktop-to-Android file transfer is working in manual testing. It is still an active rebuild, not a production-ready release.

Working now

  • Discover nearby Android devices with Android NSD/mDNS.
  • Advertise dynamic HTTP and file-transfer ports on the local network.
  • Send a text offer and let the receiver accept or decline it.
  • Transfer accepted text and copy it from the Receive screen.
  • Select images, videos, documents, and multiple files.
  • Show file metadata to the receiver before any file bytes are sent.
  • Stream file bytes directly over raw TCP without loading an entire file into memory.
  • Save received files into public Android Downloads through MediaStore, preserving the extension when duplicate names are resolved.
  • Delete the incomplete current file if its receive operation fails or is cancelled.
  • Send files sequentially with a save acknowledgement after each file.
  • Cancel a pending send or active file transfer on a best-effort basis.
  • Show batch-wide byte percentage while files are being sent and received.
  • Show clear offer, transfer, success, failure, and cancelled states on the sender, with incoming, receiving, and received states on the receiver.
  • Run the shared Send/Receive UI on Desktop, with an adaptive 50/50 two-pane layout in wider windows.
  • Discover and advertise Desktop devices through JmDNS using the same DNS-SD service as Android.
  • Select multiple Desktop files with the native file dialog and send them through the same offer and TCP protocol.
  • Save received Desktop files safely into Downloads through a temporary .part file, then move completed files into place without overwriting an existing name.
  • Copy received text and open the Downloads folder on Desktop.
  • Open connection troubleshooting from Send, Receive, or the top app bar, then manually restart local discovery and service advertising without resetting the app or removing received files.

Still needs work

  • Authentication, encryption, transfer tokens, and session validation.
  • File integrity hashes/checksums.
  • Rich receiver-side failure details and per-file results.
  • More robust discovery, server, foreground/background, and cleanup lifecycles.
  • Better IP address selection and IPv6 handling.
  • Retry, pause/resume, and interrupted-transfer recovery.
  • Automated transfer coverage and broader device/router testing.
  • Broader Desktop validation across Windows, macOS, Linux, routers, firewalls, VPNs, and machines with multiple network adapters.
  • Desktop packaging and release testing.
  • iOS discovery, transfer, and storage implementations.

The current progress UI tracks the exact bytes transferred across the accepted batch and displays the resulting percentage.

How it works

Sync360 uses two small networking paths with different jobs:

  • Ktor HTTP is the control plane. It carries text/file offers, receiver decisions, file metadata, and text payloads.
  • Raw TCP is the file data plane. It streams the actual file bytes directly between devices.
flowchart LR
    A["Sender device"] -->|"Android NSD or Desktop JmDNS"| B["Receiver device"]
    A -->|"Ktor: offer + decision + metadata"| B
    A -->|"Raw TCP: streamed file bytes"| B
    B -->|"Platform Downloads writer"| D["Downloads"]
Loading

Android uses NsdManager; Desktop uses JmDNS. Both advertise the _sync360._tcp. DNS-SD service with a stable per-install device ID, device details, protocol version, an OS-assigned HTTP port, and a separate OS-assigned file-transfer port.

Text path

SendScreen
  -> SendScreenViewModel
  -> OutgoingRequestsController
  -> POST /sync360/text/offer
  -> receiver Accept/Decline
  -> POST /sync360/text/transfer
  -> ReceiveScreen shows the text

The sender shares a preview and character count first. The full text is posted only after the receiver accepts.

File path

Platform file picker
  -> SelectedFileReader reads name, size, MIME type, and platform location
  -> POST /sync360/file/offer sends metadata
  -> receiver Accept/Decline
  -> platform FileTransferSender opens an InputStream
  -> one raw TCP connection streams the accepted file batch
  -> platform DownloadsWriter saves each file
  -> receiver acknowledges that the file was saved

One TCP socket is opened for the complete accepted batch. Each file begins with its index and promised byte count, followed by exactly that many bytes. The receiver checks the index and size against the accepted offer before saving the file, then sends one save acknowledgement before the sender continues. The current shared payload buffer is 512 KiB; TCP correctness does not depend on sender and receiver reads using identical chunk boundaries.

Files are sent sequentially. If a later file fails, files that were already completed stay in Downloads; the incomplete current file is cleaned up. Android uses a pending MediaStore entry and resolves its MIME type from the filename extension so duplicate names remain in the form file (1).ext. Desktop writes a temporary .part file before moving a completed file into place without overwriting an existing name.

A small performance note

In one manual Android-to-Android test over 5 GHz Wi-Fi, Sync360 transferred a roughly 575 MB file in about 24–26 seconds—around 22–24 MB/s.

In one separate manual Desktop-to-Android test, Sync360 transferred a 1.51 GB file in 22.333 seconds—roughly 69–70 MB/s.

These are individual observations, not guaranteed speeds or formal benchmarks. Transfer speed depends on both devices, their storage, Wi-Fi radios, router or hotspot, signal quality, and other network traffic. Reproducible benchmarks across more hardware and networks are still future work.

Architecture and project layout

The code intentionally follows a direct path:

Compose screen -> ViewModel -> controller/service -> common contract -> platform implementation
  • androidApp/ — Android application host, manifest, launcher assets, and app entry point.
  • shared/src/commonMain/ — shared Compose UI, adaptive Navigation 3 layout, ViewModels, screen/domain state, controllers, Ktor client/server, transfer contracts, and dependency injection.
  • shared/src/androidMain/ — Android NSD, file selection metadata, clipboard, local identity, raw TCP transfer, Downloads storage, and Android DI bindings.
  • shared/src/jvmMain/ — JmDNS discovery/registration, native file selection metadata, clipboard, local identity, raw TCP transfer, Downloads storage, and Desktop DI bindings.
  • desktopApp/ — Compose Desktop entry point and DMG/MSI/DEB packaging configuration.
  • iosApp/ — iOS shell; iOS targets are currently disabled in the shared Gradle configuration.

The project remains Android-first, but the current Desktop app reuses the shared UI, ViewModels, controllers, HTTP protocol, and transfer contracts. Platform source sets implement only the parts that require Android or JVM APIs.

Tech stack

  • Kotlin 2.3.21 and Kotlin Multiplatform
  • Compose Multiplatform 1.11.1 with Material 3
  • Android min SDK 33, compile/target SDK 37
  • Ktor 3.5.1 client/server with CIO
  • Koin 4.2.2
  • Coroutines and StateFlow
  • kotlinx.serialization JSON
  • Android NSD/mDNS
  • JmDNS 3.6.3 for Desktop DNS-SD/mDNS
  • Java Socket / ServerSocket for file bytes
  • Android ContentResolver and MediaStore
  • Navigation 3 with a Material-adaptive 50/50 two-pane Scene on wider windows
  • Gradle 9.4.1 wrapper

Getting started

Requirements

  • JDK 17
  • A recent Android Studio version compatible with Android Gradle Plugin 9.2.x
  • Android SDK Platform 37
  • Two physical Android 13+ devices for Android-to-Android testing, or one Android device and one Desktop machine for cross-platform testing
  • A Wi-Fi network or hotspot that allows devices to communicate with each other

Clone and open

git clone https://github.com/CodePandaaAI/Sync360.git
cd Sync360

Open the repository root in Android Studio and let Gradle sync finish.

Build Android

Windows:

./gradlew.bat :androidApp:assembleDebug

macOS/Linux:

./gradlew :androidApp:assembleDebug

There is no stable public release yet. For now, Sync360 should be built from source and treated as development software.

Run Desktop

Windows:

./gradlew.bat :desktopApp:run

macOS/Linux:

./gradlew :desktopApp:run

Try the current flow

  1. Install/open Sync360 on two supported devices: two Android devices, or Android and Desktop.
  2. Connect both devices to the same Wi-Fi network or hotspot.
  3. Keep Sync360 open on both devices during the current foreground-only test flow.
  4. On the Send screen, wait for the other device to appear.
  5. Choose Text or Files, select the nearby device, and send an offer.
  6. Accept the offer on the receiving device.
  7. Received files will be written to the platform's Downloads folder.

Some routers enable client isolation and block local device-to-device traffic. If discovery or transfer does not work, try another trusted Wi-Fi network or a phone hotspot.

If devices still cannot discover this device or fail to connect after a network change, open Settings from the top app bar or select Troubleshoot on Send or Receive, then use Repair connection. Repair restarts local discovery and advertises Sync360 again; it does not reset the app or remove received files.

Security warning

Sync360 is not secure for untrusted networks yet.

The current Android/Desktop implementation uses cleartext local HTTP and raw TCP. It does not authenticate the sender, encrypt content, bind file sockets to an approved session token, or verify file integrity with a cryptographic hash. Receiver approval exists in the UI, but it is not a complete security boundary.

Use the current app only for development and testing on private networks you control. Please report security-sensitive findings according to SECURITY.md, not in a public issue.

Roadmap

Next: make the current MVP trustworthy and informative

  • Improve active-transfer feedback around the current byte percentage.
  • Add integrity verification.
  • Improve cancellation and failure reporting.
  • Strengthen lifecycle behavior and local-network reliability.
  • Validate Desktop discovery and transfer across more operating systems, network adapters, routers, and firewall configurations.
  • Design session validation, authentication, and encryption deliberately.

Later: bring the same simple flow to more devices

  • Desktop packaging, release workflow, and broader compatibility testing.
  • iOS investigation and implementation.
  • More actionable connection errors and broader troubleshooting guidance.
  • Retry or resume support where the added protocol complexity is justified.

Sync360 is not trying to become a chat app, cloud-sync product, or permanent device manager. The product direction stays focused:

find nearby -> approve -> send directly

Why the rebuild is intentionally small

An older AI-generated sync implementation grew faster than it could be understood and maintained, so it was removed. The current version is being rebuilt manually, one complete path at a time.

That history shapes the code today:

  • Prefer readable control flow over clever abstractions.
  • Keep platform work out of composables.
  • Keep HTTP DTOs at the network boundary.
  • Stream large files instead of buffering them whole.
  • Add architecture only when it clarifies a real responsibility.
  • Describe unfinished work honestly.

This is a learning-driven project, but the goal is serious software that its maintainer can fully explain and own.

Contributing

Focused feedback and contributions are welcome, especially around:

  • Android NSD behavior across devices and routers
  • local-network and socket reliability
  • transfer security and threat modelling
  • small UI/UX improvements
  • focused tests for pure Kotlin logic
  • clear documentation fixes

For large architecture or protocol changes, start with an issue so the user flow and tradeoffs can be discussed before implementation.

When reporting a networking bug, include the device models, Android versions, network setup, exact steps, expected result, actual result, and useful logs.

License

Sync360 is available under the Apache License 2.0.

Maintainer

Created by Romit Sharma.

If the idea clicks with you, star the repository, try the current MVP, or share what broke. Real feedback is more useful than hype.

About

Send text and files directly between nearby Android phones and computers on the same Wi-Fi. No cloud uploads, accounts, Bluetooth, or internet connection required.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

10 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors