From 95e68cbbe748f81af1113753c5b99929e3db9ea2 Mon Sep 17 00:00:00 2001 From: Guillaume Jacquart Date: Wed, 11 Oct 2023 16:36:02 +0000 Subject: epic18: Trackers control on standalone app (without Ipscrambling). --- .../core/utils/NotificationsHelper.kt | 35 +++++ .../domain/entities/FeatureServiceState.kt | 21 +++ .../domain/entities/NotificationChannels.kt | 27 ++++ .../domain/entities/NotificationContent.kt | 27 ++++ .../permissions/APermissionsPrivacyModule.kt | 160 --------------------- .../permissions/PermissionsPrivacyModuleBase.kt | 160 +++++++++++++++++++++ 6 files changed, 270 insertions(+), 160 deletions(-) create mode 100644 core/src/main/java/foundation/e/advancedprivacy/core/utils/NotificationsHelper.kt create mode 100644 core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureServiceState.kt create mode 100644 core/src/main/java/foundation/e/advancedprivacy/domain/entities/NotificationChannels.kt create mode 100644 core/src/main/java/foundation/e/advancedprivacy/domain/entities/NotificationContent.kt delete mode 100644 core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/APermissionsPrivacyModule.kt create mode 100644 core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleBase.kt (limited to 'core') diff --git a/core/src/main/java/foundation/e/advancedprivacy/core/utils/NotificationsHelper.kt b/core/src/main/java/foundation/e/advancedprivacy/core/utils/NotificationsHelper.kt new file mode 100644 index 0000000..29721b0 --- /dev/null +++ b/core/src/main/java/foundation/e/advancedprivacy/core/utils/NotificationsHelper.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2023 MURENA SAS + * + * 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, see . + */ +package foundation.e.advancedprivacy.core.utils + +import android.content.Context +import androidx.core.app.NotificationCompat +import foundation.e.advancedprivacy.domain.entities.NotificationContent + +fun notificationBuilder( + context: Context, + content: NotificationContent +): NotificationCompat.Builder { + val builder = NotificationCompat.Builder(context, content.channelId) + .setSmallIcon(content.icon) + .setPriority(NotificationCompat.PRIORITY_LOW) + .setContentTitle(context.getString(content.title)) + .setStyle(NotificationCompat.BigTextStyle().bigText(context.getString(content.description))) + content.pendingIntent?.let { builder.setContentIntent(it) } + + return builder +} diff --git a/core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureServiceState.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureServiceState.kt new file mode 100644 index 0000000..6bfecbb --- /dev/null +++ b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureServiceState.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2023 MURENA SAS + * + * 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, see . + */ +package foundation.e.advancedprivacy.domain.entities + +enum class FeatureServiceState { + OFF, ON, STARTING, STOPPING +} diff --git a/core/src/main/java/foundation/e/advancedprivacy/domain/entities/NotificationChannels.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/NotificationChannels.kt new file mode 100644 index 0000000..4458e1d --- /dev/null +++ b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/NotificationChannels.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 MURENA SAS + * + * 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, see . + */ +package foundation.e.advancedprivacy.domain.entities + +const val CHANNEL_FIRST_BOOT = "first_boot_notification" +const val CHANNEL_FAKE_LOCATION_FLAG = "fake_location_flag" +const val CHANNEL_IPSCRAMBLING_FLAG = "ipscrambling_flag" +const val CHANNEL_TRACKER_FLAG = "tracker_flag" + +const val NOTIFICATION_FIRST_BOOT = 1000 +const val NOTIFICATION_FAKE_LOCATION_FLAG = NOTIFICATION_FIRST_BOOT + 1 +const val NOTIFICATION_IPSCRAMBLING_FLAG = NOTIFICATION_FAKE_LOCATION_FLAG + 1 +const val NOTIFICATION_TRACKER_FLAG = NOTIFICATION_IPSCRAMBLING_FLAG + 1 diff --git a/core/src/main/java/foundation/e/advancedprivacy/domain/entities/NotificationContent.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/NotificationContent.kt new file mode 100644 index 0000000..44b508d --- /dev/null +++ b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/NotificationContent.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 MURENA SAS + * + * 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, see . + */ +package foundation.e.advancedprivacy.domain.entities + +import android.app.PendingIntent + +data class NotificationContent( + val channelId: String, + val icon: Int, + val title: Int, + val description: Int, + val pendingIntent: PendingIntent? +) diff --git a/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/APermissionsPrivacyModule.kt b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/APermissionsPrivacyModule.kt deleted file mode 100644 index 78f424b..0000000 --- a/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/APermissionsPrivacyModule.kt +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2022 - 2023 MURENA SAS - * Copyright (C) 2021 E FOUNDATION - * - * 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, see . - */ - -package foundation.e.advancedprivacy.externalinterfaces.permissions - -import android.app.AppOpsManager -import android.content.Context -import android.content.pm.ApplicationInfo -import android.content.pm.PackageManager -import android.content.pm.PermissionInfo -import android.content.pm.PermissionInfo.PROTECTION_DANGEROUS -import android.graphics.drawable.Drawable -import android.os.Build -import android.util.Log -import foundation.e.advancedprivacy.domain.entities.AppOpModes -import foundation.e.advancedprivacy.domain.entities.ApplicationDescription -import foundation.e.advancedprivacy.domain.entities.PermissionDescription -import foundation.e.advancedprivacy.domain.entities.ProfileType - -/** - * Implementation of the commons functionality between privileged and standard - * versions of the module. - * @param context an Android context, to retrieve packageManager for example. - */ -abstract class APermissionsPrivacyModule(protected val context: Context) : IPermissionsPrivacyModule { - - companion object { - private const val TAG = "PermissionsModule" - } - - /** - * @see IPermissionsPrivacyModule.getInstalledApplications - */ - override fun getApplicationDescription(packageName: String, withIcon: Boolean): ApplicationDescription { - val appDesc = buildApplicationDescription(context.packageManager.getApplicationInfo(packageName, 0)) - if (withIcon) { - appDesc.icon = getApplicationIcon(appDesc.packageName) - } - return appDesc - } - - /** - * * @see IPermissionsPrivacyModule.getPermissions - */ - override fun getPermissions(packageName: String): List { - val packageInfo = context.packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS) - return packageInfo.requestedPermissions?.asList() ?: emptyList() - } - - override fun getPermissionDescription(permissionName: String): PermissionDescription { - val info = context.packageManager.getPermissionInfo(permissionName, 0) - return PermissionDescription( - name = permissionName, - isDangerous = isPermissionsDangerous(info), - group = null, - label = info.loadLabel(context.packageManager), - description = info.loadDescription(context.packageManager) - ) - } - - /** - * @see IPermissionsPrivacyModule.isDangerousPermissionGranted - */ - override fun isDangerousPermissionGranted(packageName: String, permissionName: String): Boolean { - return context.packageManager - .checkPermission(permissionName, packageName) == PackageManager.PERMISSION_GRANTED - } - - // on google version, work only for the current package. - @Suppress("DEPRECATION") - override fun getAppOpMode( - appDesc: ApplicationDescription, - appOpPermissionName: String - ): AppOpModes { - - val appOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager - - val mode = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { - appOps.checkOpNoThrow( - appOpPermissionName, - - appDesc.uid, appDesc.packageName - ) - } else { - appOps.unsafeCheckOpNoThrow( - appOpPermissionName, - appDesc.uid, appDesc.packageName - ) - } - - return AppOpModes.getByModeValue(mode) - } - - override fun isPermissionsDangerous(permissionName: String): Boolean { - try { - val permissionInfo = context.packageManager.getPermissionInfo(permissionName, 0) - return isPermissionsDangerous(permissionInfo) - } catch (e: Exception) { - Log.w(TAG, "exception in isPermissionsDangerous(String)", e) - return false - } - } - - @Suppress("DEPRECATION") - private fun isPermissionsDangerous(permissionInfo: PermissionInfo): Boolean { - try { - return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { - permissionInfo.protectionLevel and PROTECTION_DANGEROUS == 1 - } else { - permissionInfo.protection == PROTECTION_DANGEROUS - } - } catch (e: Exception) { - Log.w(TAG, "exception in isPermissionsDangerous(PermissionInfo)", e) - return false - } - } - - override fun buildApplicationDescription( - appInfo: ApplicationInfo, - profileId: Int, - profileType: ProfileType - ): - ApplicationDescription { - return ApplicationDescription( - packageName = appInfo.packageName, - uid = appInfo.uid, - label = getAppLabel(appInfo), - icon = null, - profileId = profileId, - profileType = profileType, - ) - } - - private fun getAppLabel(appInfo: ApplicationInfo): CharSequence { - return context.packageManager.getApplicationLabel(appInfo) - } - - fun getApplicationIcon(appInfo: ApplicationInfo): Drawable? { - return context.packageManager.getApplicationIcon(appInfo) - } - - override fun getApplicationIcon(packageName: String): Drawable? { - return context.packageManager.getApplicationIcon(packageName) - } -} diff --git a/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleBase.kt b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleBase.kt new file mode 100644 index 0000000..27ba17f --- /dev/null +++ b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleBase.kt @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2022 - 2023 MURENA SAS + * Copyright (C) 2021 E FOUNDATION + * + * 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, see . + */ + +package foundation.e.advancedprivacy.externalinterfaces.permissions + +import android.app.AppOpsManager +import android.content.Context +import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager +import android.content.pm.PermissionInfo +import android.content.pm.PermissionInfo.PROTECTION_DANGEROUS +import android.graphics.drawable.Drawable +import android.os.Build +import android.util.Log +import foundation.e.advancedprivacy.domain.entities.AppOpModes +import foundation.e.advancedprivacy.domain.entities.ApplicationDescription +import foundation.e.advancedprivacy.domain.entities.PermissionDescription +import foundation.e.advancedprivacy.domain.entities.ProfileType + +/** + * Implementation of the commons functionality between privileged and standard + * versions of the module. + * @param context an Android context, to retrieve packageManager for example. + */ +abstract class PermissionsPrivacyModuleBase(protected val context: Context) : IPermissionsPrivacyModule { + + companion object { + private const val TAG = "PermissionsModule" + } + + /** + * @see IPermissionsPrivacyModule.getInstalledApplications + */ + override fun getApplicationDescription(packageName: String, withIcon: Boolean): ApplicationDescription { + val appDesc = buildApplicationDescription(context.packageManager.getApplicationInfo(packageName, 0)) + if (withIcon) { + appDesc.icon = getApplicationIcon(appDesc.packageName) + } + return appDesc + } + + /** + * * @see IPermissionsPrivacyModule.getPermissions + */ + override fun getPermissions(packageName: String): List { + val packageInfo = context.packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS) + return packageInfo.requestedPermissions?.asList() ?: emptyList() + } + + override fun getPermissionDescription(permissionName: String): PermissionDescription { + val info = context.packageManager.getPermissionInfo(permissionName, 0) + return PermissionDescription( + name = permissionName, + isDangerous = isPermissionsDangerous(info), + group = null, + label = info.loadLabel(context.packageManager), + description = info.loadDescription(context.packageManager) + ) + } + + /** + * @see IPermissionsPrivacyModule.isDangerousPermissionGranted + */ + override fun isDangerousPermissionGranted(packageName: String, permissionName: String): Boolean { + return context.packageManager + .checkPermission(permissionName, packageName) == PackageManager.PERMISSION_GRANTED + } + + // on google version, work only for the current package. + @Suppress("DEPRECATION") + override fun getAppOpMode( + appDesc: ApplicationDescription, + appOpPermissionName: String + ): AppOpModes { + + val appOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager + + val mode = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + appOps.checkOpNoThrow( + appOpPermissionName, + + appDesc.uid, appDesc.packageName + ) + } else { + appOps.unsafeCheckOpNoThrow( + appOpPermissionName, + appDesc.uid, appDesc.packageName + ) + } + + return AppOpModes.getByModeValue(mode) + } + + override fun isPermissionsDangerous(permissionName: String): Boolean { + try { + val permissionInfo = context.packageManager.getPermissionInfo(permissionName, 0) + return isPermissionsDangerous(permissionInfo) + } catch (e: Exception) { + Log.w(TAG, "exception in isPermissionsDangerous(String)", e) + return false + } + } + + @Suppress("DEPRECATION") + private fun isPermissionsDangerous(permissionInfo: PermissionInfo): Boolean { + try { + return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { + permissionInfo.protectionLevel and PROTECTION_DANGEROUS == 1 + } else { + permissionInfo.protection == PROTECTION_DANGEROUS + } + } catch (e: Exception) { + Log.w(TAG, "exception in isPermissionsDangerous(PermissionInfo)", e) + return false + } + } + + override fun buildApplicationDescription( + appInfo: ApplicationInfo, + profileId: Int, + profileType: ProfileType + ): + ApplicationDescription { + return ApplicationDescription( + packageName = appInfo.packageName, + uid = appInfo.uid, + label = getAppLabel(appInfo), + icon = null, + profileId = profileId, + profileType = profileType, + ) + } + + private fun getAppLabel(appInfo: ApplicationInfo): CharSequence { + return context.packageManager.getApplicationLabel(appInfo) + } + + fun getApplicationIcon(appInfo: ApplicationInfo): Drawable? { + return context.packageManager.getApplicationIcon(appInfo) + } + + override fun getApplicationIcon(packageName: String): Drawable? { + return context.packageManager.getApplicationIcon(packageName) + } +} -- cgit v1.2.1