summaryrefslogtreecommitdiff
path: root/permissionse/src/main/java/foundation/e/privacymodules
diff options
context:
space:
mode:
Diffstat (limited to 'permissionse/src/main/java/foundation/e/privacymodules')
-rw-r--r--permissionse/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt139
1 files changed, 139 insertions, 0 deletions
diff --git a/permissionse/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt b/permissionse/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt
new file mode 100644
index 0000000..fe5b7ac
--- /dev/null
+++ b/permissionse/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt
@@ -0,0 +1,139 @@
+package foundation.e.privacymodules.permissions
+
+import android.annotation.TargetApi
+import android.app.AppOpsManager
+import android.app.AppOpsManager.OP_NONE
+import android.app.AppOpsManager.strOpToOp
+import android.content.Context
+import android.net.IConnectivityManager
+import android.net.VpnManager
+import android.net.VpnManager.TYPE_VPN_SERVICE
+import android.os.Build
+import android.os.ServiceManager
+import android.os.UserHandle
+import android.util.Log
+import foundation.e.privacymodules.permissions.data.AppOpModes
+import foundation.e.privacymodules.permissions.data.ApplicationDescription
+
+/**
+ * Implements [IPermissionsPrivacyModule] with all privileges of a system app.
+ */
+class PermissionsPrivacyModule(context: Context): APermissionsPrivacyModule(context) {
+
+ private val appOpsManager: AppOpsManager get()
+ = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
+
+ /**
+ * @see IPermissionsPrivacyModule.toggleDangerousPermission
+ * Always return true, permission is set using privileged capacities.
+ */
+ override fun toggleDangerousPermission(
+ appDesc: ApplicationDescription,
+ permissionName: String,
+ grant: Boolean
+ ): Boolean {
+ try {
+ if (grant) {
+ context.packageManager.grantRuntimePermission(
+ appDesc.packageName,
+ permissionName,
+ android.os.Process.myUserHandle()
+ )
+ } else {
+ context.packageManager.revokeRuntimePermission(
+ appDesc.packageName,
+ permissionName,
+ android.os.Process.myUserHandle()
+ )
+ }
+ } catch (e: Exception) {
+ Log.e("Permissions-e", "Exception while setting permission", e)
+ return false
+ }
+
+ return true
+ }
+
+ override fun setAppOpMode(
+ appDesc: ApplicationDescription,
+ appOpPermissionName: String,
+ status: AppOpModes
+ ): Boolean {
+ val op = strOpToOp(appOpPermissionName)
+ if (op != OP_NONE) {
+ appOpsManager.setMode(op, appDesc.uid, appDesc.packageName, status.modeValue)
+ }
+ return true
+ }
+
+ override fun setVpnPackageAuthorization(packageName: String): Boolean {
+ return when(Build.VERSION.SDK_INT) {
+ 29 -> setVpnPackageAuthorizationSDK29(packageName)
+ 30 -> setVpnPackageAuthorizationSDK30(packageName)
+ 31, 32 -> setVpnPackageAuthorizationSDK32(packageName)
+ else -> {
+ Log.e("Permissions-e", "Bad android sdk version")
+ false
+ }
+ }
+ }
+
+ @TargetApi(29)
+ private fun setVpnPackageAuthorizationSDK29(packageName: String): Boolean {
+ val service: IConnectivityManager = IConnectivityManager.Stub.asInterface(
+ ServiceManager.getService(Context.CONNECTIVITY_SERVICE))
+
+ try {
+ if (service.prepareVpn(null, packageName, UserHandle.myUserId())) {
+ // Authorize this app to initiate VPN connections in the future without user
+ // intervention.
+ service.setVpnPackageAuthorization(packageName, UserHandle.myUserId(), true)
+ return true
+ }
+ } catch (e: java.lang.Exception) {
+ Log.e("Permissions-e", "Exception while setting VpnPackageAuthorization", e)
+ } catch (e: NoSuchMethodError) {
+ Log.e("Permissions-e", "Bad android sdk version", e)
+ }
+ return false
+ }
+
+ @TargetApi(30)
+ private fun setVpnPackageAuthorizationSDK30(packageName: String): Boolean {
+ val service: IConnectivityManager = IConnectivityManager.Stub.asInterface(
+ ServiceManager.getService(Context.CONNECTIVITY_SERVICE))
+
+ try {
+ if (service.prepareVpn(null, packageName, UserHandle.myUserId())) {
+ // Authorize this app to initiate VPN connections in the future without user
+ // intervention.
+ service.setVpnPackageAuthorization(packageName, UserHandle.myUserId(), TYPE_VPN_SERVICE)
+ return true
+ }
+ } catch (e: java.lang.Exception) {
+ Log.e("Permissions-e", "Exception while setting VpnPackageAuthorization", e)
+ } catch (e: NoSuchMethodError) {
+ Log.e("Permissions-e", "Bad android sdk version", e)
+ }
+ return false
+ }
+
+ @TargetApi(31)
+ private fun setVpnPackageAuthorizationSDK32(packageName: String): Boolean {
+ val vpnManager = context.getSystemService(Context.VPN_MANAGEMENT_SERVICE) as VpnManager
+
+ try {
+ if (vpnManager.prepareVpn(null, packageName, UserHandle.myUserId())) {
+ // Authorize this app to initiate VPN connections in the future without user
+ // intervention.
+ vpnManager.setVpnPackageAuthorization(packageName, UserHandle.myUserId(), TYPE_VPN_SERVICE)
+ return true
+ }
+ } catch (e: java.lang.Exception) {
+ Log.e("Permissions-e", "Exception while setting VpnPackageAuthorization", e)
+ } catch (e: NoSuchMethodError) {
+ Log.e("Permissions-e", "Bad android sdk version", e)
+ }
+ return false
+ }
+}