<?xml version="1.0" encoding="utf-8"?>
<!--
 * Copyright (C) 2010-2012 Ciaran Gultnieks
 * Copyright (C) 2013-2017 Peter Serwylo
 * Copyright (C) 2014-2015 Daniel Martí
 * Copyright (C) 2014-2018 Hans-Christoph Steiner
 * Copyright (C) 2016 Dominik Schürmann
 * Copyright (C) 2018 Torsten Grote
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          package="org.fdroid.fdroid"
          android:installLocation="auto">

    <supports-screens
            android:anyDensity="true"
            android:largeScreens="true"
            android:normalScreens="true"
            android:resizeable="true"
            android:smallScreens="true"
            android:xlargeScreens="true"
    />

    <uses-feature
            android:name="android.hardware.telephony"
            android:required="false"/>
    <uses-feature
            android:name="android.hardware.wifi"
            android:required="false"/>
    <uses-feature
            android:name="android.hardware.touchscreen"
            android:required="false"/>

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.NFC"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>

    <application
            android:name=".FDroidApp"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:description="@string/app_description"
            android:allowBackup="true"
            android:fullBackupContent="@xml/backup_rules"
            android:networkSecurityConfig="@xml/network_security_config"
            android:theme="@style/AppThemeLight"
            android:supportsRtl="true">

        <provider
                android:authorities="${applicationId}.data.AppProvider"
                android:name="org.fdroid.fdroid.data.AppProvider"
                android:exported="false"/>

        <provider
                android:authorities="${applicationId}.data.RepoProvider"
                android:name="org.fdroid.fdroid.data.RepoProvider"
                android:exported="false"/>

        <provider
                android:authorities="${applicationId}.data.ApkProvider"
                android:name="org.fdroid.fdroid.data.ApkProvider"
                android:exported="false"/>

        <provider
                android:authorities="${applicationId}.data.TempApkProvider"
                android:name="org.fdroid.fdroid.data.TempApkProvider"
                android:exported="false"/>

        <provider
                android:authorities="${applicationId}.data.TempAppProvider"
                android:name="org.fdroid.fdroid.data.TempAppProvider"
                android:exported="false"/>

        <provider
                android:authorities="${applicationId}.data.InstalledAppProvider"
                android:name="org.fdroid.fdroid.data.InstalledAppProvider"
                android:exported="false"/>

        <provider
                android:authorities="${applicationId}.data.AppPrefsProvider"
                android:name="org.fdroid.fdroid.data.AppPrefsProvider"
                android:exported="false"/>

        <provider
                android:authorities="${applicationId}.data.PackageProvider"
                android:name="org.fdroid.fdroid.data.PackageProvider"
                android:exported="false"/>

        <provider
                android:authorities="${applicationId}.data.CategoryProvider"
                android:name="org.fdroid.fdroid.data.CategoryProvider"
                android:exported="false"/>

        <provider
                android:name="org.fdroid.fdroid.installer.ApkFileProvider"
                android:authorities="${applicationId}.installer.ApkFileProvider"
                android:exported="false"
                android:grantUriPermissions="true">
            <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/apk_file_provider"/>
        </provider>
        <provider
                android:name="androidx.core.content.FileProvider"
                android:authorities="${applicationId}.installer"
                android:exported="false"
                android:grantUriPermissions="true">
            <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/installer_file_provider"/>
        </provider>

        <activity
                android:name=".privileged.views.InstallConfirmActivity"
                android:label="@string/menu_install"
                android:theme="@style/MinWithDialogBaseThemeLight"
                android:excludeFromRecents="true"
                android:parentActivityName=".views.main.MainActivity"
                android:configChanges="layoutDirection|locale">
            <meta-data
                    android:name="android.support.PARENT_ACTIVITY"
                    android:value=".views.main.MainActivity"/>
        </activity>
        <activity
                android:name=".privileged.views.UninstallDialogActivity"
                android:excludeFromRecents="true"
                android:theme="@style/AppThemeTransparent"/>
        <activity
                android:name=".views.ManageReposActivity"
                android:label="@string/menu_manage"
                android:launchMode="singleTask"
                android:parentActivityName=".views.main.MainActivity"
                android:configChanges="layoutDirection|locale">
            <meta-data
                    android:name="android.support.PARENT_ACTIVITY"
                    android:value=".views.main.MainActivity"/>
        </activity>
        <activity
                android:name=".NfcNotEnabledActivity"
                android:noHistory="true"
                android:configChanges="layoutDirection|locale"/>
        <activity
                android:name=".views.RepoDetailsActivity"
                android:label="@string/repo_details"
                android:parentActivityName=".views.ManageReposActivity"
                android:windowSoftInputMode="stateHidden"
                android:configChanges="layoutDirection|locale">
            <meta-data
                    android:name="android.support.PARENT_ACTIVITY"
                    android:value=".views.ManageReposActivity"/>
        </activity>

        <activity
                android:name=".views.AppDetailsActivity"
                android:label="@string/app_details"
                android:exported="true"
                android:parentActivityName=".views.main.MainActivity"
                android:configChanges="layoutDirection|locale">
            <meta-data
                    android:name="android.support.PARENT_ACTIVITY"
                    android:value=".views.main.MainActivity"/>
        </activity>
        <activity
                android:name=".acra.CrashReportActivity"
                android:theme="@style/AppThemeDark"
                android:process=":error_report"
                android:launchMode="singleInstance"
                android:excludeFromRecents="true"
                android:finishOnTaskLaunch="true"/>
        <activity android:name=".views.ScreenShotsActivity"/>
        <!-- Note: AppThemeTransparent, this activity shows dialogs only -->
        <activity android:name=".data.ObbUrlActivity"
                  android:theme="@android:style/Theme.NoDisplay"/>
        <!-- Note: AppThemeTransparent, this activity shows dialogs only -->
        <activity
                android:name=".installer.DefaultInstallerActivity"
                android:theme="@style/AppThemeTransparent"/>
        <!-- Note: AppThemeTransparent, this activity shows dialogs only -->
        <activity
                android:name=".installer.ErrorDialogActivity"
                android:theme="@style/AppThemeTransparent"/>

        <receiver android:name=".receiver.StartupReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>

                <category android:name="android.intent.category.HOME"/>
            </intent-filter>
        </receiver>

        <receiver android:name=".receiver.PackageManagerReceiver">
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED"/>
                <action android:name="android.intent.action.PACKAGE_CHANGED"/>
                <action android:name="android.intent.action.PACKAGE_REMOVED"/>

                <data android:scheme="package"/>
            </intent-filter>
        </receiver>

        <receiver android:name=".NotificationBroadcastReceiver" android:exported="false">
            <!-- Doesn't require an intent-filter because it is explicitly invoked via Intent.setClass() -->
        </receiver>

        <receiver android:name=".receiver.DeviceStorageReceiver">
            <intent-filter>
                <action android:name="android.intent.action.DEVICE_STORAGE_LOW"/>
            </intent-filter>
        </receiver>

        <service
                android:name=".UpdateService"
                android:permission="android.permission.BIND_JOB_SERVICE"
                android:exported="false"/>
        <service
                android:name=".UpdateJobService"
                android:exported="false"
                android:permission="android.permission.BIND_JOB_SERVICE"/>
        <service
                android:name=".net.DownloaderService"
                android:exported="false"/>
        <service
                android:name=".installer.InstallerService"
                android:permission="android.permission.BIND_JOB_SERVICE"
                android:exported="false"/>
        <service
                android:name=".CleanCacheService"
                android:permission="android.permission.BIND_JOB_SERVICE"
                android:exported="false"/>
        <service
                android:name=".CleanCacheJobService"
                android:permission="android.permission.BIND_JOB_SERVICE"
                android:exported="false"/>
        <service
                android:name=".DeleteCacheService"
                android:permission="android.permission.BIND_JOB_SERVICE"
                android:exported="false"/>
        <service
                android:name=".net.ConnectivityMonitorService"
                android:permission="android.permission.BIND_JOB_SERVICE"
                android:exported="false"/>
        <service
                android:name=".installer.InstallManagerService"
                android:exported="false"/>
        <service
                android:name=".installer.InstallHistoryService"
                android:exported="false"/>
        <service
                android:name=".data.InstalledAppProviderService"
                android:permission="android.permission.BIND_JOB_SERVICE"
                android:exported="false"/>
        <service
                android:name=".AddRepoIntentService"
                android:exported="false"/>


        <!-- Warning: Please add all new services to HidingManager -->

        <activity
                android:name=".views.main.MainActivity"
                android:launchMode="singleTop"
                android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>


            <!-- App URLs -->

            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:scheme="fdroid.app"/>
            </intent-filter>

            <intent-filter android:autoVerify="false">
                <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"/>
                <data android:host="f-droid.org"/>
                <data android:host="www.f-droid.org"/>
                <data android:host="staging.f-droid.org"/>
                <data android:pathPrefix="/app/"/>
                <data android:pathPrefix="/packages/"/>
                <data android:pathPrefix="/repository/browse"/>
                <!-- support localized URLs -->
                <data android:pathPattern="/.*/packages/.*"/>
                <data android:pathPattern="/.*/packages/.*/"/>
            </intent-filter>

            <intent-filter android:autoVerify="false">
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:scheme="http"/>
                <data android:host="f-droid.org"/>
                <data android:host="www.f-droid.org"/>
                <data android:host="staging.f-droid.org"/>
                <data android:pathPrefix="/app/"/>
                <data android:pathPrefix="/packages/"/>
                <data android:pathPrefix="/repository/browse"/>
                <!-- support localized URLs -->
                <data android:pathPattern="/.*/packages/.*"/>
                <data android:pathPattern="/.*/packages/.*/"/>
            </intent-filter>

            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:scheme="market" android:host="details"/>
            </intent-filter>

            <intent-filter android:autoVerify="false">
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:scheme="http"/>
                <data android:scheme="https"/>
                <data android:host="play.google.com"/> <!-- they don't do www. -->
                <data android:path="/store/apps/details"/>
            </intent-filter>

            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:scheme="amzn" android:host="apps" android:path="/android"/>
            </intent-filter>

            <intent-filter android:autoVerify="false">
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:scheme="http"/>
                <data android:scheme="https"/>
                <data android:host="amazon.com"/>
                <data android:host="www.amazon.com"/>
                <data android:path="/gp/mas/dl/android"/>
            </intent-filter>


            <!-- Search URLs -->

            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:scheme="fdroid.search"/>
            </intent-filter>

            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:scheme="market" android:host="search"/>
            </intent-filter>

            <intent-filter android:autoVerify="false">
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:scheme="http"/>
                <data android:scheme="https"/>
                <data android:host="play.google.com"/> <!-- they don't do www. -->
                <data android:path="/store/search"/>
            </intent-filter>

            <intent-filter>
                <action android:name="android.intent.action.SEARCH"/>
            </intent-filter>

            <meta-data
                    android:name="android.app.searchable"
                    android:resource="@xml/searchable"/>


            <!-- Repo URLs -->

            <!--
            This intent serves two purposes: Swapping apps between devices and adding a
            repo from a website (e.g. https://guardianproject.info/fdroid/repo).
            We intercept both of these situations in the FDroid activity, and then redirect
            to the appropriate handler (swap handling, manage repos respectively) from there.

            The reason for this is that the only differentiating factor is the presence
            of a "swap=1" in the query string, and intent-filter is unable to deal with
            query parameters. An alternative would be to do something like fdroidswap:// as
            a scheme, but then we need to copy/paste all of this intent-filter stuff and
            keep it up to date when it changes or a bug is found.

            This filter supports HTTP and HTTPS schemes. There is an additional filter for
            fdroidrepo:// and fdroidrepos://
            -->
            <intent-filter android:autoVerify="false">
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.BROWSABLE"/>
                <category android:name="android.intent.category.DEFAULT"/>

                <!--
                Android's scheme matcher is case-sensitive, so include
                ALL CAPS versions to support ALL CAPS URLs in QR Codes.
                QR Codes have a special ALL CAPS mode that uses a reduced
                character set, making for more compact QR Codes.
                -->
                <data android:scheme="http"/>
                <data android:scheme="HTTP" tools:ignore="AppLinkUrlError"/>
                <data android:scheme="https"/>
                <data android:scheme="HTTPS" tools:ignore="AppLinkUrlError"/>

                <data android:host="*"/>

                <!--
                The pattern matcher here is poorly implemented, in particular the * is
                non-greedy, so you have to do stupid tricks to match patterns that have
                repeat characters in them. http://stackoverflow.com/a/8599921/306864
                -->
                <data android:path="/fdroid/repo"/>
                <data android:pathPattern="/fdroid/repo/*"/>
                <data android:pathPattern="/.*/fdroid/repo"/>
                <data android:pathPattern="/.*/fdroid/repo/*"/>
                <data android:pathPattern="/.*/.*/fdroid/repo"/>
                <data android:pathPattern="/.*/.*/fdroid/repo/*"/>
                <data android:pathPattern="/.*/.*/.*/fdroid/repo"/>
                <data android:pathPattern="/.*/.*/.*/fdroid/repo/*"/>
                <data android:pathPattern="/.*/.*/.*/.*/fdroid/repo"/>
                <data android:pathPattern="/.*/.*/.*/.*/fdroid/repo/*"/>
                <data android:path="/fdroid/archive"/>
                <data android:pathPattern="/fdroid/archive/*"/>
                <data android:pathPattern="/.*/fdroid/archive"/>
                <data android:pathPattern="/.*/fdroid/archive/*"/>
                <data android:pathPattern="/.*/.*/fdroid/archive"/>
                <data android:pathPattern="/.*/.*/fdroid/archive/*"/>
                <data android:pathPattern="/.*/.*/.*/fdroid/archive"/>
                <data android:pathPattern="/.*/.*/.*/fdroid/archive/*"/>
                <data android:pathPattern="/.*/.*/.*/.*/fdroid/archive"/>
                <data android:pathPattern="/.*/.*/.*/.*/fdroid/archive/*"/>
                <!--
                Some QR Code scanners don't respect custom schemes like fdroidrepo://,
                so this is a workaround, since the local repo URL is all uppercase in
                the QR Code for sending the local repo to another device.
                -->
                <data android:path="/FDROID/REPO"/>
                <data android:pathPattern="/.*/FDROID/REPO"/>
                <data android:pathPattern="/.*/.*/FDROID/REPO"/>
                <data android:pathPattern="/.*/.*/.*/FDROID/REPO"/>
            </intent-filter>

            <!--
            Same as the intent filter listening for repositories via https://*/fdroid/repo, except this
            looks for fdroidrepos://* and doesn't care what the path is.
            -->
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.BROWSABLE"/>
                <category android:name="android.intent.category.DEFAULT"/>

                <!--
                Android's scheme matcher is case-sensitive, so include
                ALL CAPS versions to support ALL CAPS URLs in QR Codes.
                QR Codes have a special ALL CAPS mode that uses a reduced
                character set, making for more compact QR Codes.
                -->
                <data android:scheme="fdroidrepo"/>
                <data android:scheme="FDROIDREPO" tools:ignore="AppLinkUrlError"/>
                <data android:scheme="fdroidrepos"/>
                <data android:scheme="FDROIDREPOS" tools:ignore="AppLinkUrlError"/>
            </intent-filter>


            <!-- Handle NFC tags detected from outside our application -->

            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED"/>

                <category android:name="android.intent.category.DEFAULT"/>

                <!--
                URIs that come in via NFC have scheme/host normalized to all lower case
                https://developer.android.com/reference/android/nfc/NfcAdapter.html#ACTION_NDEF_DISCOVERED
                -->
                <data android:scheme="fdroidrepo"/>
                <data android:scheme="fdroidrepos"/>
            </intent-filter>

        </activity>

        <activity android:name=".views.apps.AppListActivity"/>

        <activity android:name=".views.installed.InstalledAppsActivity"
                  android:parentActivityName=".views.main.MainActivity">
            <meta-data
                    android:name="android.support.PARENT_ACTIVITY"
                    android:value=".views.main.MainActivity"/>
        </activity>
        <activity android:name=".views.InstallHistoryActivity"
                  android:parentActivityName=".views.main.MainActivity">
            <meta-data
                    android:name="android.support.PARENT_ACTIVITY"
                    android:value=".views.main.MainActivity"/>
        </activity>

        <activity android:name=".AboutActivity" android:theme="@style/Theme.AppCompat.Light.Dialog"/>
        <activity android:name=".installer.FileInstallerActivity" android:theme="@style/AppThemeTransparent"/>

    </application>

</manifest>
