vojo/android/app/src/main/AndroidManifest.xml

145 lines
6.8 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- allowBackup=false: CallDeclineReceiver reads the Matrix access_token
from shared_prefs/CapacitorStorage.xml (written by sessionBridge).
With allowBackup=true a rooted device or adb-backup-enabled user
could exfiltrate the cleartext token. Session data is cheap to
recreate via re-login, so excluding ourselves from Auto Backup
is the simpler control vs. fine-grained backup_rules.xml exclusions. -->
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode|navigation|density"
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBarLaunch"
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- App Links for https://vojo.chat/u/<user>. autoVerify=true lets
Chrome/Gmail/SMS hand the tap straight to this activity; the
server must publish a matching /.well-known/assetlinks.json
over HTTPS with the installed APK's signing SHA-256. Telegram
and other in-app browsers ignore verification and load the
URL in their own webview — the intent-URL redirect injected
in index.html covers that case. -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="vojo.chat"
android:pathPrefix="/u/" />
</intent-filter>
<!-- System share-sheet target. Three filters because Android's
sheet UI dedupes by activity but resolves by MIME match:
text/* gets its own filter so the Vojo icon shows up
alongside WhatsApp/Telegram for «share link/selection»; */*
covers single-file (image/video/audio/pdf/…) and
SEND_MULTIPLE picks up gallery multi-select.
Payload extraction lives in ShareTargetPlugin — MainActivity
only routes the Intent to the plugin via onNewIntent. -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"></meta-data>
</provider>
<!-- Replace Capacitor's default FCM service. VojoFirebaseMessagingService
extends MessagingService so super.onMessageReceived() still forwards
to the JS bridge; we add cold-start notification display on top. -->
<service
android:name="com.capacitorjs.plugins.pushnotifications.MessagingService"
tools:node="remove" />
<service
android:name=".VojoFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service
android:name=".CallForegroundService"
android:exported="false"
android:foregroundServiceType="microphone" />
<receiver
android:name=".CallCancelReceiver"
android:exported="false" />
<receiver
android:name=".CallDeclineReceiver"
android:exported="false" />
<receiver
android:name=".MarkAsReadReceiver"
android:exported="false" />
<receiver
android:name=".NotificationDismissReceiver"
android:exported="false" />
<receiver
android:name=".ReplyReceiver"
android:exported="false" />
</application>
<!-- Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- DM voice calls: mic + audio routing. Capacitor auto-requests at getUserMedia time. -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!-- Required to unblock NotificationCompat.CallStyle on API 31+: NMS's
checkDisqualifyingFeatures rejects CallStyle notifications without
FSI/FGS/UIJ, throwing IllegalArgumentException on its own handler
thread (silent to the app). Declaring the permission flips
FLAG_FSI_REQUESTED_BUT_DENIED so the gate passes, even though we
never call setFullScreenIntent(). See ADR 2.5-heads-up. -->
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<!-- DM call lock-screen retention: CallForegroundService keeps the call
process foregrounded under lock so AppOps doesn't revoke RECORD_AUDIO
and netd doesn't block background network. -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
</manifest>