Files
oxmc a48077078c Initial commit: PawletProfiled, Android device-owner priv-app
Android counterpart to git.oxmc.me/PawletOS/profiled's Linux daemon --
independent implementation, not a port. Same .vconfig profile format and
17 payload types, but implemented against DevicePolicyManager/VpnManager/
WifiManager/WallpaperManager/KeyChain instead of a native NDK Binder
daemon, since that's where AOSP actually exposes this functionality.

Self-provisions as device owner at first boot (DeviceOwnerProvisioner.kt)
to unlock the DevicePolicyManager-gated payload types (cert, pkcs12,
passcode, proxy, screensaver lock enforcement). 16 of 17 payload types are
real implementations; firewall is a documented platform dead end (no app
UID gets CAP_NET_ADMIN). See README's capability matrix for the full
per-payload breakdown.

Reviewed against the documented @SystemApi/hidden-API surface, not
compiled -- no AOSP toolchain available in this environment.
2026-07-25 01:35:58 -07:00

88 lines
4.1 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="os.pawlet.profiled">
<!-- Installed as a priv-app under /system/priv-app, platform-signed.
Privileged permissions below require a matching entry in
etc/privapp-permissions-os.pawlet.profiled.xml on top of this
declaration — AOSP ignores privileged perms without both. -->
<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.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
<!-- Signature-protected, auto-granted to platform-signed apps, no
privapp-permissions allowlist entry required. Lets this app
provision itself as device owner at first boot (see
DeviceOwnerProvisioner.kt) and manage other admins afterward. -->
<uses-permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS" />
<uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
<!-- Privileged (signature|privileged) — require the allowlist entry.
WRITE_SECURE_SETTINGS: private DNS, screensaver, device-provisioned
flags, NTP server.
NETWORK_SETTINGS: global HTTP proxy, privileged Wi-Fi/Ethernet
config that WifiNetworkSuggestion can't express (EAP anchor
pinning, static config without user approval UI).
INTERACT_ACROSS_USERS: apply profiles before any secondary user
exists / from the system user context during first boot. -->
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.NETWORK_SETTINGS" />
<uses-permission android:name="android.permission.NETWORK_SETUP_WIZARD" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<!-- ZTE hardware-identity collection (DeviceIdentityCollector.kt) -->
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
<application
android:name=".PawletProfileApplication"
android:label="@string/app_name"
android:persistent="true"
android:directBootAware="true"
android:allowBackup="false">
<service
android:name=".PawletProfileService"
android:exported="true"
android:directBootAware="true"
android:permission="os.pawlet.profiled.permission.BIND_SERVICE">
<intent-filter>
<action android:name="os.pawlet.profiled.action.BIND" />
</intent-filter>
</service>
<receiver
android:name=".PawletDeviceAdminReceiver"
android:permission="android.permission.BIND_DEVICE_ADMIN"
android:exported="true">
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/device_admin_receiver" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<receiver
android:name=".BootCompletedReceiver"
android:exported="true"
android:directBootAware="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
<permission
android:name="os.pawlet.profiled.permission.BIND_SERVICE"
android:protectionLevel="signature" />
</manifest>