diff options
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.kt | 12 | ||||
| -rw-r--r-- | packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/Profiles.kt | 24 |
2 files changed, 33 insertions, 3 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 0545ead..09cef0e 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 @@ -40,6 +40,7 @@ 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 import org.meshbay.client.shell.Pickers @@ -64,6 +65,8 @@ class MainActivity : Activity() { private lateinit var channels: Channels private lateinit var photos: PhotoChannels private var docs: List<DocChannels> = emptyList() + /** Backups exist in the personal profile only (Profiles.kt). */ + private var backups = false private var network: android.net.ConnectivityManager.NetworkCallback? = null private val pickers = Pickers(this) private val text = NativeText { code -> @@ -101,11 +104,12 @@ class MainActivity : Activity() { Thread { saves.cleanUpAfterAKilledProcess() }.start() cast = CastChannels(this, onCasting = { on -> runOnUiThread { casting = on; keepAlive() } }, tell = { m -> runOnUiThread { android.widget.Toast.makeText(this, m, android.widget.Toast.LENGTH_LONG).show() } }) + backups = Profiles.isPersonal(this) val destinations = DestinationChannels(getSharedPreferences(DestinationChannels.PREFS, Context.MODE_PRIVATE)) photos = PhotoChannels(this, getSharedPreferences(PhotoChannels.PREFS, Context.MODE_PRIVATE), destinations, java.io.File(filesDir, "photosync"), onKeepAlive = { on, line -> runOnUiThread { backup(on, line) } }) - docs = listOf( + docs = if (!backups) emptyList() else listOf( DocChannels("contactsync", this, getSharedPreferences("contactsync", Context.MODE_PRIVATE), destinations, java.io.File(cacheDir, "contactsync"), ContactSource(this), notifyId = 10, permissionRequest = 4209), @@ -121,7 +125,8 @@ class MainActivity : Activity() { channelNames = { mapOf( Notifier.CHANNEL_CHAT to text.get("push.channel_chat", channels.locale), Notifier.CHANNEL_OTHER to text.get("push.channel_other", channels.locale)) }), - photos = photos, destinations = destinations, docs = docs) + photos = photos.takeIf { backups }, destinations = destinations.takeIf { backups }, + docs = docs) WebViewCompat.addWebMessageListener(web, Bridge.PORT, setOf(UiAssets.ORIGIN), Bridge(channels)) cast.control.warmUp() installShim() @@ -167,7 +172,7 @@ class MainActivity : Activity() { override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? { val url = request.url if (url.host == UiAssets.HOST && url.path?.startsWith(PhotoChannels.PATH) == true) { - return photos.serve(url.path ?: "") ?: refused() + return photos.takeIf { backups }?.serve(url.path ?: "") ?: refused() } if (url.host == UiAssets.HOST && url.path?.startsWith(DocChannels.PATH) == true) { val path = url.path ?: "" @@ -253,6 +258,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" 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/Profiles.kt b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/Profiles.kt new file mode 100644 index 0000000..660cfaa --- /dev/null +++ b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/phonesync/Profiles.kt @@ -0,0 +1,24 @@ +package org.meshbay.client.phonesync + +import android.content.Context +import android.os.Build +import android.os.UserManager + +/** + * Backups are of the personal profile only, never of a work profile: a copy + * 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 + * they are asked from, and none of the cross-profile (`ENTERPRISE_*`) URIs + * is used (`test_android_shell.py` checks for them). + */ +object Profiles { + fun isPersonal(context: Context): Boolean { + val users = context.getSystemService(UserManager::class.java) + // Before Android 11 an application cannot ask whether its own profile + // is managed; a work profile is never the system user, so that is + // the test there (a secondary user on a shared tablet loses backups). + return if (Build.VERSION.SDK_INT >= 30) !users.isManagedProfile else users.isSystemUser + } +} |