<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
  -->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:installLocation="internalOnly">

    <!-- normal permissions -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
    <uses-permission android:name="android.permission.READ_SYNC_STATS"/>
    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>

    <!-- other permissions -->
    <!-- android.permission-group.CONTACTS -->
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
    <!-- android.permission-group.CALENDAR -->
    <uses-permission android:name="android.permission.READ_CALENDAR"/>
    <uses-permission android:name="android.permission.WRITE_CALENDAR"/>

    <!-- android.permission-group.LOCATION -->
    <!-- getting the WiFi name (for "sync in Wifi only") requires
      - coarse location (Android 8.1)
      - fine location (Android 10) -->
    <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <!-- required since Android 10 to get the WiFi name while in background (= while syncing) -->
    <uses-permission-sdk-23 android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

    <!-- ical4android declares task access permissions -->

    <!-- Disable GPS capability requirement, which is implicitly derived from ACCESS_FINE_LOCATION
    permission and makes app unusable on some devices without GPS. We need location permissions only
    to get the current WiFi SSID, and we don't need GPS for that. -->
    <uses-feature android:name="android.hardware.location.gps" android:required="false" />

    <application
        android:name=".App"
        android:allowBackup="false"
        android:networkSecurityConfig="@xml/network_security_config"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"
        android:resizeableActivity="true"
        tools:ignore="UnusedAttribute"
        android:supportsRtl="true">

        <!-- Required for Hilt/WorkManager integration. See
        - https://developer.android.com/develop/background-work/background-tasks/persistent/configuration/custom-configuration#remove-default
        - https://developer.android.com/training/dependency-injection/hilt-jetpack#workmanager
        However, we must not disable AndroidX startup completely, as it's needed by other libraries like okhttp. -->
        <provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            android:exported="false"
            tools:node="merge">
            <meta-data
                android:name="androidx.work.WorkManagerInitializer"
                android:value="androidx.startup"
                tools:node="remove" />
        </provider>

        <!-- Remove the node added by AppAuth (remove only from net.openid.appauth library, not from our flavor manifest files) -->
        <activity android:name="net.openid.appauth.RedirectUriReceiverActivity"
            tools:node="remove" tools:selector="net.openid.appauth"/>

        <activity android:name=".ui.intro.IntroActivity" />
        <activity
            android:name=".ui.AccountsActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <activity
            android:name=".ui.AboutActivity"
            android:label="@string/navigation_drawer_about"
            android:parentActivityName=".ui.AccountsActivity"/>

        <activity
            android:name=".ui.AppSettingsActivity"
            android:label="@string/app_settings"
            android:parentActivityName=".ui.AccountsActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.APPLICATION_PREFERENCES"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".ui.DebugInfoActivity"
            android:parentActivityName=".ui.AppSettingsActivity"
            android:exported="false"
            android:label="@string/debug_info_title">
            <intent-filter>
                <action android:name="android.intent.action.BUG_REPORT"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".ui.PermissionsActivity"
            android:label="@string/app_settings_security_app_permissions"
            android:parentActivityName=".ui.AppSettingsActivity" />
        <activity
            android:name=".ui.TasksActivity"
            android:label="@string/intro_tasks_title"
            android:parentActivityName=".ui.AppSettingsActivity" />

        <activity
            android:name=".ui.setup.LoginActivity"
            android:parentActivityName=".ui.AccountsActivity"
            android:windowSoftInputMode="adjustResize"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.BROWSABLE"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:scheme="caldav"/>
                <data android:scheme="caldavs"/>
                <data android:scheme="carddav"/>
                <data android:scheme="carddavs"/>
                <data android:scheme="davx5"/>
            </intent-filter>
            <intent-filter>
                <action android:name="loginFlow" /> <!-- Ensures this filter matches, even if the sending app is not defining an action -->
                <category android:name="android.intent.category.DEFAULT" />
                <data
                    tools:ignore="AppLinkUrlError"
                    android:scheme="http" />
                <data android:scheme="https" />
            </intent-filter>
        </activity>

        <activity
            android:name=".ui.account.AccountActivity"
            android:parentActivityName=".ui.AccountsActivity"
            android:exported="true">
        </activity>
        <activity
            android:name=".ui.account.CollectionActivity"
            android:parentActivityName=".ui.account.AccountActivity" />
        <activity
            android:name=".ui.account.CreateAddressBookActivity"
            android:parentActivityName=".ui.account.AccountActivity" />
        <activity
            android:name=".ui.account.CreateCalendarActivity"
            android:parentActivityName=".ui.account.AccountActivity" />
        <activity
            android:name=".ui.account.AccountSettingsActivity"
            android:parentActivityName=".ui.account.AccountActivity" />
        <activity
            android:name=".ui.account.WifiPermissionsActivity"
            android:parentActivityName=".ui.account.AccountSettingsActivity" />

        <activity
            android:name=".ui.webdav.WebdavMountsActivity"
            android:exported="true"
            android:parentActivityName=".ui.AccountsActivity" />
        <activity
            android:name=".ui.webdav.AddWebdavMountActivity"
            android:parentActivityName=".ui.webdav.WebdavMountsActivity"
            android:windowSoftInputMode="adjustResize" />

        <!-- account type "DAVx⁵" -->
        <service
            android:name=".sync.account.AccountAuthenticatorService"
            android:exported="false">
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator"/>
            </intent-filter>
            <meta-data
                android:name="android.accounts.AccountAuthenticator"
                android:resource="@xml/account_authenticator"/>
        </service>
        <service
            android:name=".sync.adapter.CalendarsSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/sync_calendars"/>
        </service>
        <service
            android:name=".sync.adapter.JtxSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/sync_notes"/>
        </service>
        <service
            android:name=".sync.adapter.OpenTasksSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/sync_opentasks"/>
        </service>
        <service
            android:name=".sync.adapter.TasksOrgSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/sync_tasks_org"/>
        </service>
        <provider
            android:authorities="@string/webdav_authority"
            android:name=".webdav.DavDocumentsProvider"
            android:exported="true"
            android:grantUriPermissions="true"
            android:permission="android.permission.MANAGE_DOCUMENTS">
            <intent-filter>
                <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
            </intent-filter>
        </provider>

        <!-- account type "DAVx⁵ Address book" -->
        <service
            android:name=".sync.account.AddressBookAuthenticatorService"
            android:exported="true"
            tools:ignore="ExportedService">   <!-- Since Android 11, this must be true so that Google Contacts shows the address book accounts -->
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator"/>
            </intent-filter>

            <meta-data
                android:name="android.accounts.AccountAuthenticator"
                android:resource="@xml/account_authenticator_address_book"/>
        </service>
        <service
            android:name=".sync.adapter.ContactsSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>

            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/sync_contacts"/>
            <meta-data
                android:name="android.provider.CONTACTS_STRUCTURE"
                android:resource="@xml/contacts"/>
        </service>

        <!-- provider to share debug info/logs -->
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="@string/authority_debug_provider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/debug_paths" />
        </provider>

        <!-- UnifiedPush -->
        <service android:exported="false" android:name=".push.UnifiedPushService">
            <intent-filter>
                <action android:name="org.unifiedpush.android.connector.PUSH_EVENT"/>
            </intent-filter>
        </service>

        <!-- Widgets -->
        <receiver android:name=".ui.widget.LabeledSyncButtonWidgetReceiver"
            android:label="@string/widget_labeled_sync_label"
            android:exported="true">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_info_labeled_sync_button" />
        </receiver>
        <receiver android:name=".ui.widget.IconSyncButtonWidgetReceiver"
            android:label="@string/widget_icon_sync_label"
            android:exported="true">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_info_icon_sync_button" />
        </receiver>

    </application>

    <!-- package visiblity – which apps do we need to see? -->
    <queries>
        <!-- system providers (listing them is technically not required, but some apps like the
        Huawei calendar take this as indication of whether these providers are accessed) -->
        <provider android:authorities="com.android.calendar"/>
        <provider android:authorities="com.android.contacts"/>

        <!-- task providers -->
        <package android:name="at.techbee.jtx" />
        <package android:name="org.dmfs.tasks" />
        <package android:name="org.tasks" />

        <!-- ICSx5 for Webcal feeds -->
        <package android:name="at.bitfire.icsdroid"/>

        <!-- apps that interact with contact, calendar, task data (for debug info) -->
        <intent>
            <action android:name="*" />
            <data android:scheme="content" android:host="com.android.contacts" />
        </intent>
        <intent>
            <action android:name="*" />
            <data android:scheme="content" android:host="com.android.calendar" />
        </intent>

        <!-- Open URLs in a browser or other app [https://developer.android.com/training/package-visibility/use-cases#open-urls-browser-or-other-app] -->
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="https" />
        </intent>

        <!-- Custom Tabs support (e.g. Nextcloud Login Flow) -->
        <intent>
            <action android:name="android.support.customtabs.action.CustomTabsService" />
        </intent>
    </queries>

</manifest>