Files
plezy/android/app/src/main/AndroidManifest.xml
T
edde746 69ceea9466 fix(android): grant shelf artwork to every installed launcher
The Watch Next poster art moved to a local content:// URI in 2.10.0, gated
twice on the package returned by resolveActivity(MAIN+HOME,
MATCH_DEFAULT_ONLY): once as the grantUriPermission target, once as a
caller-identity check inside SystemShelfArtworkProvider.openFile. Any
launcher that is not the resolved default HOME activity was denied on every
image and drew its broken-image placeholder instead. Fire OS pins its own
launcher and silently reverts a third-party default, so Projectivy could
never satisfy either gate; a device with several launchers and no chosen
default resolves to the resolver activity and granted nobody at all.

Discover consumers with queryIntentActivities(MAIN+HOME, MATCH_ALL) so every
installed launcher is granted, drop the hand-rolled identity check, and make
the provider non-exported so the framework enforces the per-URI grants that
are now the only access path. Because those grants became load-bearing,
grantReadAccess reports failure per poster and the sync rolls back rather
than committing a row no launcher can open.

close #1706
2026-07-29 05:12:28 +02:00

144 lines
7.1 KiB
XML

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- Allow minSdk=25 despite libmpv-android declaring minSdk=26 -->
<uses-sdk tools:overrideLibrary="dev.jdtech.mpv" />
<!-- Internet access permissions -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<!-- PIP and media session foreground service permissions -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
<uses-permission android:name="android.permission.REORDER_TASKS"/>
<!-- Background download notifications and foreground service -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
<!-- Explicitly remove media permissions that media_kit may add -->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" tools:node="remove" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" tools:node="remove" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="remove" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove" />
<!-- Android TV support (not required, but allow detection) -->
<uses-feature android:name="android.software.leanback" android:required="false" />
<!-- Android TV Watch Next integration -->
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!-- Touchscreen not required for TV -->
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<!-- Android Automotive OS support -->
<uses-feature android:name="android.hardware.type.automotive" android:required="false" />
<application
android:label="Plezy"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:banner="@drawable/tv_banner"
android:appCategory="video"
android:largeHeap="true"
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:supportsPictureInPicture="true"
android:configChanges="orientation|keyboardHidden|keyboard|navigation|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<meta-data
android:name="flutter_deeplinking_enabled"
android:value="false" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<!-- Allow app to appear in Android TV launcher -->
<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
</intent-filter>
<!-- Deep link handler for Watch Next items -->
<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="plezy" android:host="play"/>
</intent-filter>
</activity>
<!-- FileProvider for sharing downloaded files with external players -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.edde746.plezy.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>
<!-- Launcher shelf artwork. Not exported: readers reach it only through the
per-URI read grants issued to CATEGORY_HOME packages by WatchNextProvider. -->
<provider
android:name=".watchnext.SystemShelfArtworkProvider"
android:authorities="com.edde746.plezy.systemshelf.artwork"
android:exported="false"
android:grantUriPermissions="true" />
<receiver
android:name=".watchnext.SystemShelfUpdateReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
<!-- Required for url_launcher to open HTTPS URLs -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http" />
</intent>
<!-- Required to resolve external video player apps on Android 11+ -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:mimeType="video/*" />
</intent>
<!-- Required to identify HOME launchers as shelf artwork consumers. -->
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
</intent>
</queries>
</manifest>