summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-android/app/src/main/kotlin/org
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-15 15:09:58 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-15 15:09:58 +0200
commit39cac2878de059992cb09a1ccf09b6bcece99fae (patch)
treec4686f00fdf40e90b4b74144c1e8fd8fb8b8ed0b /packages/meshbay-android/app/src/main/kotlin/org
parent7fc2fa04d7d88a1cdf0d290ddd2de3815a7d52a5 (diff)
downloadmeshbay-39cac2878de059992cb09a1ccf09b6bcece99fae.tar.gz
feat(android): no text messages backup, and one build again
READ_SMS sits behind restricted settings outside a store and Play keeps it for the default SMS application: not worth a second build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-android/app/src/main/kotlin/org')
-rw-r--r--packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/MainActivity.kt10
-rw-r--r--packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/DocChannels.kt18
-rw-r--r--packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/DocPlan.kt6
-rw-r--r--packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/Profiles.kt2
-rw-r--r--packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/SmsXml.kt69
-rw-r--r--packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/photos/PhotoChannels.kt2
6 files changed, 8 insertions, 99 deletions
diff --git a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/MainActivity.kt b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/MainActivity.kt
index d523da7..5f225e2 100644
--- a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/MainActivity.kt
+++ b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/MainActivity.kt
@@ -42,7 +42,6 @@ import org.meshbay.client.phonesync.CalendarSource
import org.meshbay.client.phonesync.ContactSource
import org.meshbay.client.phonesync.DestinationChannels
import org.meshbay.client.phonesync.DocChannels
-import org.meshbay.client.phonesync.Flavor
import org.meshbay.client.phonesync.Profiles
import org.meshbay.client.photos.PhotoChannels
import org.meshbay.client.save.SaveSinks
@@ -128,11 +127,7 @@ class MainActivity : Activity() {
DocChannels("calendarsync", this, getSharedPreferences("calendarsync", Context.MODE_PRIVATE), destinations,
java.io.File(cacheDir, "calendarsync"), CalendarSource(this),
notifyId = 12, permissionRequest = 4211),
- ) + listOfNotNull(Flavor.messageSource(this)?.let { source ->
- DocChannels("messagesync", this, getSharedPreferences("messagesync", Context.MODE_PRIVATE), destinations,
- java.io.File(cacheDir, "messagesync"), source,
- notifyId = 11, permissionRequest = 4210)
- })
+ )
channels = Channels(hub, onHubChanged = { runOnUiThread { reloadForHub() } },
hasCatalogue = { code -> hasAsset("ui/locales/$code.js") }, keys = keys, saves = saves,
cast = cast, onPlayback = { on -> runOnUiThread { playing = on; keepAlive() } },
@@ -279,8 +274,7 @@ class MainActivity : Activity() {
val binary = WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER)
val prelude = "const HUB_BASE = ${JSONObject.quote(hub.base)};\nconst BINARY = $binary;\n" +
"const CAST = ${cast.control.available()};\n" +
- "const BACKUP = $backups;\n" +
- "const MESSAGES = ${docs.any { it.handles("messagesync:") }};\n"
+ "const BACKUP = $backups;\n"
shim = WebViewCompat.addDocumentStartJavaScript(web, "(function(){$prelude$source\n})();", setOf(UiAssets.ORIGIN))
}
diff --git a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/DocChannels.kt b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/DocChannels.kt
index f4da64f..dd74256 100644
--- a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/DocChannels.kt
+++ b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/DocChannels.kt
@@ -16,7 +16,7 @@ import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
/**
- * Contacts or messages backup (docs/MESHBAY_DESIGN.md §9.13): what the page
+ * Contacts or calendar backup (docs/MESHBAY_DESIGN.md §9.13): what the page
* needs from the phone for one kind of data, and nothing it could use to read
* anything else.
*
@@ -64,7 +64,6 @@ class DocChannels(
"sent" -> { sent(args.optString(0, ""), args.optString(1, ""), args.optString(2, "")); true }
"completed" -> { completed(); status() }
"failed" -> failed(args.optString(0, ""), args.optString(1, ""))
- "open-settings" -> { openSettings(); true }
else -> throw Refused("Refused: no such channel")
}
@@ -126,7 +125,7 @@ class DocChannels(
issued = Issued(token, export, c.ledgerKey)
return JSONObject().put("item", JSONObject()
.put("token", token).put("name", export.name)
- .put("dir", DocPlan.dirFor(c, source.suffix) + (if (export.subdir.isEmpty()) "" else "/${export.subdir}"))
+ .put("dir", DocPlan.dirFor(c, source.suffix))
.put("size", export.file.length()).put("count", export.count))
}
@@ -168,19 +167,6 @@ class DocChannels(
permission = null
}
- /**
- * The application's page in the system's settings. Android keeps some
- * permissions (text messages) behind "restricted settings" for an
- * application installed outside a store; that page is where the person
- * lifts it (⋮ > Allow restricted settings), and nowhere in here can.
- */
- private fun openSettings() {
- val intent = android.content.Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
- android.net.Uri.fromParts("package", activity.packageName, null))
- .addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK)
- activity.runOnUiThread { activity.startActivity(intent) }
- }
-
/** From Activity.onRequestPermissionsResult; true when the request was ours. */
fun deliverPermission(requestCode: Int): Boolean {
if (requestCode != permissionRequest) return false
diff --git a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/DocPlan.kt b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/DocPlan.kt
index 1a2a359..ecf643b 100644
--- a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/DocPlan.kt
+++ b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/DocPlan.kt
@@ -13,14 +13,12 @@ data class Export(
val mime: String,
/** Recorded only when the node took the file: what the next export starts from. */
val marker: String,
- /** Contacts or messages in it, for the page to say. */
+ /** Contacts or events in it, for the page to say. */
val count: Int,
- /** A folder under the kind's own, such as the year, or empty. */
- val subdir: String = "",
)
/**
- * One kind of the phone's data (the contacts, the messages) written out as
+ * One kind of the phone's data (the contacts, the calendar) written out as
* a file of what is new since `marker`, the value the last file sent left.
*/
interface DocSource {
diff --git a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/Profiles.kt b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/Profiles.kt
index 660cfaa..305e705 100644
--- a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/Profiles.kt
+++ b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/Profiles.kt
@@ -9,7 +9,7 @@ import android.os.UserManager
* of the application installed inside a work profile offers none of them.
*
* In the personal profile, every source reads that profile alone: MediaStore,
- * ContactsContract, the SMS and calendar providers answer for the profile
+ * ContactsContract and the calendar provider answer for the profile
* they are asked from, and none of the cross-profile (`ENTERPRISE_*`) URIs
* is used (`test_android_shell.py` checks for them).
*/
diff --git a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/SmsXml.kt b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/SmsXml.kt
deleted file mode 100644
index 624e1f1..0000000
--- a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/SmsXml.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.meshbay.client.phonesync
-
-import java.io.Writer
-import java.text.SimpleDateFormat
-import java.util.Date
-import java.util.Locale
-import java.util.TimeZone
-
-/** One text message, as the platform's SMS provider stores it. */
-data class Sms(
- val id: Long,
- val address: String,
- /** Milliseconds, received or sent. */
- val date: Long,
- val dateSent: Long,
- /** 1 received, 2 sent, 3 draft, 4 outbox, 5 failed, 6 queued. */
- val type: Int,
- val body: String,
- val read: Int,
- val status: Int,
- val locked: Int,
- val protocol: Int,
- val subject: String?,
- val serviceCenter: String?,
- val contactName: String?,
-)
-
-/**
- * Messages written as the `<smses>` XML that SMS backup applications read and
- * restore, so a copy on the node goes back onto a phone with tools that exist.
- * Pure, so the JVM tests hold the format and its escaping.
- */
-object SmsXml {
- fun write(messages: List<Sms>, out: Writer, zone: TimeZone) {
- val readable = SimpleDateFormat("d MMM yyyy HH:mm:ss", Locale.ROOT).apply { timeZone = zone }
- out.write("<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\n")
- out.write("<smses count=\"${messages.size}\">\n")
- for (m in messages) {
- out.write(" <sms protocol=\"${m.protocol}\" address=${q(m.address)} date=\"${m.date}\"" +
- " type=\"${m.type}\" subject=${q(m.subject ?: "null")} body=${q(m.body)}" +
- " toa=\"null\" sc_toa=\"null\" service_center=${q(m.serviceCenter ?: "null")}" +
- " read=\"${m.read}\" status=\"${m.status}\" locked=\"${m.locked}\" date_sent=\"${m.dateSent}\"" +
- " readable_date=${q(readable.format(Date(m.date)))}" +
- " contact_name=${q(m.contactName ?: "(Unknown)")} />\n")
- }
- out.write("</smses>\n")
- }
-
- /**
- * A quoted attribute value. Line breaks are kept as character references,
- * which an attribute would otherwise fold into spaces; characters XML 1.0
- * cannot carry at all, even escaped, are left out.
- */
- fun q(text: String): String {
- val b = StringBuilder(text.length + 2).append('"')
- for (c in text) when {
- c == '&' -> b.append("&amp;")
- c == '<' -> b.append("&lt;")
- c == '>' -> b.append("&gt;")
- c == '"' -> b.append("&quot;")
- c == '\n' -> b.append("&#10;")
- c == '\r' -> b.append("&#13;")
- c == '\t' -> b.append("&#9;")
- c < ' ' || c == '￾' || c == '￿' -> {}
- else -> b.append(c)
- }
- return b.append('"').toString()
- }
-}
diff --git a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/photos/PhotoChannels.kt b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/photos/PhotoChannels.kt
index c1de859..21734fb 100644
--- a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/photos/PhotoChannels.kt
+++ b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/photos/PhotoChannels.kt
@@ -348,7 +348,7 @@ class PhotoChannels(
private const val FAILURE_AT = "failure_at"
private const val NOTIFIED = "notified"
- /** Created, or renamed from "Photo backup" now that contacts and messages use it too. */
+ /** Created, or renamed from "Photo backup" now that contacts and the calendar use it too. */
fun ensureChannel(context: Context) {
context.getSystemService(NotificationManager::class.java)
.createNotificationChannel(NotificationChannel(CHANNEL, "Backup", NotificationManager.IMPORTANCE_LOW))