├── .gitignore ├── .gitmodules ├── FUNDING.yml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── foss │ ├── java │ │ └── com │ │ │ └── mirfatif │ │ │ └── permissionmanagerx │ │ │ ├── app │ │ │ └── AppFlavor.java │ │ │ ├── main │ │ │ └── MainActivityFlavor.java │ │ │ ├── parser │ │ │ ├── PkgParserFlavor.java │ │ │ └── permsdb │ │ │ │ └── PermsDbFlavor.java │ │ │ ├── pkg │ │ │ └── PkgActivityFlavor.java │ │ │ ├── prefs │ │ │ ├── BackupRestoreFlavor.java │ │ │ ├── MySettingsFlavor.java │ │ │ └── settings │ │ │ │ ├── AdvSettingsFlavor.java │ │ │ │ ├── FilterSettingsFragFlavor.java │ │ │ │ ├── SearchSettingsFragFlavor.java │ │ │ │ ├── SettingsActivityFlavor.java │ │ │ │ ├── SettingsFragFlavor.java │ │ │ │ └── SettingsFragGeneralFlavor.java │ │ │ ├── privs │ │ │ ├── DaemonIfaceFlavor.java │ │ │ └── NativeDaemonFlavor.java │ │ │ ├── profile │ │ │ └── PermProfileBackupRestore.java │ │ │ └── util │ │ │ └── UiUtilsFlavor.java │ └── res │ │ ├── values-ar │ │ └── strings_foss.xml │ │ ├── values-el │ │ └── strings_foss.xml │ │ ├── values-es │ │ └── strings_foss.xml │ │ ├── values-ru │ │ └── strings_foss.xml │ │ ├── values-tr │ │ └── strings_foss.xml │ │ ├── values-zh-rCN │ │ └── strings_foss.xml │ │ ├── values │ │ ├── strings_foss.xml │ │ └── theme.xml │ │ └── xml │ │ └── settings_prefs.xml │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── mirfatif │ │ │ ├── err │ │ │ └── AdbException.java │ │ │ └── permissionmanagerx │ │ │ ├── about │ │ │ ├── AboutActivity.java │ │ │ ├── CrashReportActivity.java │ │ │ ├── PrivilegesAdapter.java │ │ │ ├── PrivilegesDialog.java │ │ │ └── TransCreditsDialogFrag.java │ │ │ ├── annot │ │ │ ├── NoRecordConversion.java │ │ │ └── ToDo.java │ │ │ ├── app │ │ │ └── App.java │ │ │ ├── backup │ │ │ ├── BackupFileSelector.java │ │ │ └── BackupRestore.java │ │ │ ├── base │ │ │ ├── AlertDialogFragment.java │ │ │ ├── BaseActivity.java │ │ │ ├── BottomSheetDialogFrag.java │ │ │ ├── DialogBg.java │ │ │ └── MyListAdapter.java │ │ │ ├── fwk │ │ │ ├── AboutActivityM.java │ │ │ ├── AdbConnectSvcM.java │ │ │ ├── AdvSettingsActivityM.java │ │ │ ├── AppM.java │ │ │ ├── CrashReportActivityM.java │ │ │ ├── CustomButton.java │ │ │ ├── DaemonRcvSvcM.java │ │ │ ├── DialogHelpIcon.java │ │ │ ├── FilterSettingsActivityM.java │ │ │ ├── HelpActivityM.java │ │ │ ├── LifecycleWatcher.java │ │ │ ├── LogcatSvcM.java │ │ │ ├── MainActivityM.java │ │ │ ├── MoveUpBehavior.java │ │ │ ├── MyCoordinatorLayout.java │ │ │ ├── MyDrawerLayout.java │ │ │ ├── MyLinearLayout.java │ │ │ ├── MyNavigationView.java │ │ │ ├── MySearchView.java │ │ │ ├── MyWebView.java │ │ │ ├── NumPickerPref.java │ │ │ ├── PackageActivityM.java │ │ │ ├── ProgressLinearLayout.java │ │ │ └── SettingsActivityM.java │ │ │ ├── help │ │ │ ├── HelpActivity.java │ │ │ └── HelpJsInterface.java │ │ │ ├── main │ │ │ ├── AdbConnectDialog.java │ │ │ ├── BackupRestoreDialog.java │ │ │ ├── DaemonStartProg.java │ │ │ ├── Feedback.java │ │ │ ├── FeedbackDialogFrag.java │ │ │ ├── MainActivity.java │ │ │ ├── PackageAdapter.java │ │ │ ├── PkgLongPressDialogFrag.java │ │ │ └── PrivsCheckBoxFocus.java │ │ │ ├── parser │ │ │ ├── AppOpsParser.java │ │ │ ├── Package.java │ │ │ ├── PackageParser.java │ │ │ ├── PermGroupsMapping.java │ │ │ ├── Permission.java │ │ │ ├── SearchConstants.java │ │ │ └── permsdb │ │ │ │ ├── PermissionDao.java │ │ │ │ ├── PermissionDatabase.java │ │ │ │ ├── PermissionEntity.java │ │ │ │ └── PermsDb.java │ │ │ ├── pkg │ │ │ ├── PackageActivity.java │ │ │ ├── PermDetailDialog.java │ │ │ ├── PermLongPressDialogFrag.java │ │ │ └── PermissionAdapter.java │ │ │ ├── prefs │ │ │ ├── AppUpdate.java │ │ │ ├── ExcFiltersData.java │ │ │ ├── MySettings.java │ │ │ ├── fwk │ │ │ │ ├── CustomPrefDialogFrag.java │ │ │ │ ├── EditTextPrefDialogFrag.java │ │ │ │ ├── ListPrefDialogFrag.java │ │ │ │ └── MultiSelectListPrefDialogFrag.java │ │ │ └── settings │ │ │ │ ├── AdvSettingsActivity.java │ │ │ │ ├── AdvSettingsFrag.java │ │ │ │ ├── FilterSettingsActivity.java │ │ │ │ ├── FilterSettingsFragment.java │ │ │ │ ├── SearchSettingsFrag.java │ │ │ │ ├── SettingsActivity.java │ │ │ │ ├── SettingsFragGeneral.java │ │ │ │ └── SettingsFragTheme.java │ │ │ ├── privs │ │ │ ├── AdbConnManager.java │ │ │ ├── DaemonHandler.java │ │ │ ├── DaemonIface.java │ │ │ ├── DaemonStarter.java │ │ │ └── NativeDaemon.java │ │ │ ├── svc │ │ │ ├── AdbConnectSvc.java │ │ │ ├── DaemonRcvSvc.java │ │ │ └── LogcatSvc.java │ │ │ └── util │ │ │ ├── ApiUtils.java │ │ │ ├── AppLifecycle.java │ │ │ ├── LocaleUtils.java │ │ │ ├── LogUtils.java │ │ │ ├── NotifUtils.java │ │ │ ├── SizeColorStyleSpan.java │ │ │ ├── SmallDimMarginSpan.java │ │ │ ├── StdErrLogServer.java │ │ │ ├── StringUtils.java │ │ │ ├── UiUtils.java │ │ │ ├── UserUtils.java │ │ │ ├── Utils.java │ │ │ └── bg │ │ │ ├── LiveBgTask.java │ │ │ ├── LiveEvent.java │ │ │ ├── LiveMinDelayParamTask.java │ │ │ ├── LiveSchedParamTask.java │ │ │ ├── LiveSchedTask.java │ │ │ ├── LiveSingleParamTask.java │ │ │ ├── LiveTasksQueue.java │ │ │ ├── LiveTasksQueueTyped.java │ │ │ ├── LiveUiParamTask.java │ │ │ ├── LiveUiTask.java │ │ │ ├── LiveUiWaitTask.java │ │ │ └── UiRunner.java │ └── res │ │ ├── anim │ │ └── shake.xml │ │ ├── color │ │ ├── active_disabled.xml │ │ └── slim_switch.xml │ │ ├── drawable │ │ ├── accessibility.xml │ │ ├── advanced_settings.xml │ │ ├── arrow_right.xml │ │ ├── backup_restore.xml │ │ ├── check_circle.xml │ │ ├── circle_progress_bar.xml │ │ ├── color.xml │ │ ├── crash_report_text_bg.xml │ │ ├── cross_red.xml │ │ ├── danger.xml │ │ ├── dark_mode.xml │ │ ├── database.xml │ │ ├── donate.xml │ │ ├── email.xml │ │ ├── exit.xml │ │ ├── filter.xml │ │ ├── folder.xml │ │ ├── g_accounts.xml │ │ ├── g_audio.xml │ │ ├── g_background.xml │ │ ├── g_biometrics.xml │ │ ├── g_bluetooth.xml │ │ ├── g_calendar.xml │ │ ├── g_calllog.xml │ │ ├── g_camera.xml │ │ ├── g_clipboard.xml │ │ ├── g_contacts.xml │ │ ├── g_data.xml │ │ ├── g_display.xml │ │ ├── g_hardware.xml │ │ ├── g_home.xml │ │ ├── g_location.xml │ │ ├── g_log.xml │ │ ├── g_mic.xml │ │ ├── g_network.xml │ │ ├── g_notif.xml │ │ ├── g_others.xml │ │ ├── g_package.xml │ │ ├── g_phone.xml │ │ ├── g_power.xml │ │ ├── g_sensors.xml │ │ ├── g_settings.xml │ │ ├── g_sms.xml │ │ ├── g_storage.xml │ │ ├── g_vibration.xml │ │ ├── g_wifi.xml │ │ ├── github_mark.xml │ │ ├── help.xml │ │ ├── hinge.xml │ │ ├── icon.webp │ │ ├── info.xml │ │ ├── issues.xml │ │ ├── key.xml │ │ ├── label.xml │ │ ├── link.xml │ │ ├── locale.xml │ │ ├── log.xml │ │ ├── main_act_big_prog_bg.xml │ │ ├── notification_icon.xml │ │ ├── paid.xml │ │ ├── perm_watcher.xml │ │ ├── permission.xml │ │ ├── privacy_policy.xml │ │ ├── report.xml │ │ ├── root.xml │ │ ├── schedule.xml │ │ ├── search_settings.xml │ │ ├── search_settings_bg.xml │ │ ├── settings.xml │ │ ├── share.xml │ │ ├── shell.xml │ │ ├── slim_switch_thumb.xml │ │ ├── slim_switch_track.xml │ │ ├── star.xml │ │ ├── telegram.xml │ │ ├── theme.xml │ │ ├── tick.xml │ │ ├── triangle.xml │ │ ├── update.xml │ │ ├── zoom_in.xml │ │ └── zoom_out.xml │ │ ├── layout │ │ ├── about_privileges_dialog.xml │ │ ├── about_privileges_item.xml │ │ ├── activity_about.xml │ │ ├── activity_crash_report.xml │ │ ├── activity_fragment_container.xml │ │ ├── activity_help.xml │ │ ├── activity_main.xml │ │ ├── activity_main_moving_container.xml │ │ ├── activity_package.xml │ │ ├── adb_connect_dialog.xml │ │ ├── backup_restore_dialog.xml │ │ ├── dilog_title_with_help.xml │ │ ├── feedback_dialog.xml │ │ ├── perm_details_dialog.xml │ │ ├── perm_long_press_dialog.xml │ │ ├── pkg_long_press_dialog.xml │ │ ├── progress_dialog.xml │ │ ├── rate_donate_dialog.xml │ │ ├── rv_item_perm.xml │ │ ├── rv_item_pkg.xml │ │ ├── trans_credits_row.xml │ │ └── translation_dialog.xml │ │ ├── menu │ │ ├── about_menu.xml │ │ ├── filter_settings.xml │ │ ├── help_menu.xml │ │ ├── main_drawer.xml │ │ ├── main_search.xml │ │ └── package_menu.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.png │ │ ├── values-ar │ │ ├── pref_keys.xml │ │ ├── search_strings.xml │ │ └── strings.xml │ │ ├── values-el │ │ ├── pref_keys.xml │ │ ├── search_strings.xml │ │ └── strings.xml │ │ ├── values-es │ │ ├── pref_keys.xml │ │ ├── search_strings.xml │ │ └── strings.xml │ │ ├── values-night │ │ └── colors.xml │ │ ├── values-ru │ │ ├── pref_keys.xml │ │ ├── search_strings.xml │ │ └── strings.xml │ │ ├── values-tr │ │ ├── pref_keys.xml │ │ ├── search_strings.xml │ │ └── strings.xml │ │ ├── values-v29 │ │ └── styles.xml │ │ ├── values-zh-rCN │ │ ├── pref_keys.xml │ │ ├── search_strings.xml │ │ └── strings.xml │ │ ├── values │ │ ├── arrays.xml │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── pref_keys.xml │ │ ├── search_strings.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── adv_settings_prefs.xml │ │ ├── file_paths.xml │ │ ├── filter_settings_preferences.xml │ │ ├── settings_prefs_general.xml │ │ ├── settings_prefs_search.xml │ │ └── settings_prefs_theming.xml │ └── release │ └── AndroidManifest.xml ├── build.gradle.kts ├── buildSrc ├── .gitignore ├── build.gradle.kts ├── settings.gradle.kts └── src │ └── main │ └── kotlin │ ├── android-base-conventions.gradle.kts │ ├── android-lib-conventions.gradle.kts │ ├── apk-conventions.gradle.kts │ ├── java-android-lib-conventions.gradle.kts │ ├── java-base-conventions.gradle.kts │ ├── java-kotlin-conventions.gradle.kts │ ├── java-lib-conventions.gradle.kts │ └── spotless-conventions.gradle.kts ├── configs └── foss-pro-flavors.gradle ├── fastlane └── metadata │ └── android │ ├── ar │ ├── short_description.txt │ └── title.txt │ ├── de │ └── short_description.txt │ ├── el │ └── title.txt │ ├── en-US │ ├── changelogs │ │ ├── 101.txt │ │ ├── 103.txt │ │ ├── 104.txt │ │ ├── 105.txt │ │ ├── 106.txt │ │ ├── 107.txt │ │ ├── 108.txt │ │ ├── 109.txt │ │ ├── 110.txt │ │ ├── 111.txt │ │ ├── 112.txt │ │ ├── 113.txt │ │ ├── 114.txt │ │ ├── 116.txt │ │ ├── 117.txt │ │ ├── 118.txt │ │ ├── 119.txt │ │ ├── 120.txt │ │ ├── 121.txt │ │ ├── 122.txt │ │ ├── 123.txt │ │ ├── 124.txt │ │ ├── 125.txt │ │ ├── 126.txt │ │ └── 127.txt │ ├── full_description.txt │ ├── images │ │ ├── featureGraphic.png │ │ ├── icon.png │ │ └── phoneScreenshots │ │ │ ├── 1.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ └── 6.jpg │ ├── short_description.txt │ └── title.txt │ ├── es │ ├── short_description.txt │ └── title.txt │ ├── ru │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── tr │ └── title.txt │ ├── ur │ └── title.txt │ └── zh │ ├── short_description.txt │ └── title.txt ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── help ├── cn │ ├── img │ │ ├── perm.webp │ │ └── search.webp │ └── index.html ├── en │ ├── img │ │ ├── adb_in_dev_options_1.webp │ │ ├── adb_in_dev_options_11_1.webp │ │ ├── adb_in_dev_options_11_2.webp │ │ ├── adb_in_dev_options_11_3.webp │ │ ├── adb_in_dev_options_2.webp │ │ ├── adb_in_dev_options_3.webp │ │ ├── adb_pairing.mp4 │ │ ├── allow_network_access.webp │ │ ├── banner.webp │ │ ├── fg_and_one_time_perm_modes.webp │ │ ├── hide_app_from_list.webp │ │ ├── hide_perm_from_list.webp │ │ ├── icon.webp │ │ ├── multi_users.webp │ │ ├── perm.webp │ │ ├── perm2.webp │ │ ├── perm_profiles.webp │ │ ├── perm_view.webp │ │ ├── perm_view2.webp │ │ ├── perm_watcher.gif │ │ ├── pkg.webp │ │ ├── privs.webp │ │ ├── remove_unused_perms.webp │ │ ├── search.webp │ │ ├── set_refs.webp │ │ ├── unsupported_android_version_warning.webp │ │ ├── watcher_settings.webp │ │ ├── wrun_integration1.jpg │ │ └── wrun_integration2.webp │ └── index.html ├── favicon.ico ├── help.html ├── index.html ├── main.css ├── main.js └── ru │ ├── img │ ├── perm.webp │ └── search.webp │ └── index.html ├── hidden_apis ├── .gitignore ├── build.gradle.kts └── src │ └── foss │ └── java │ ├── android │ ├── app │ │ ├── ActivityManagerNative.java │ │ ├── AppOpsManager.java │ │ └── IActivityManager.java │ ├── content │ │ ├── Context.java │ │ └── pm │ │ │ ├── IPackageManager.java │ │ │ └── ParceledListSlice.java │ ├── os │ │ ├── IDeviceIdleController.java │ │ ├── Process.java │ │ └── ServiceManager.java │ └── permission │ │ └── IPermissionManager.java │ └── com │ └── android │ └── internal │ └── app │ └── IAppOpsService.java ├── native ├── build_native.sh ├── pmxd.c └── pmxe.c ├── priv_daemon ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro └── src │ ├── foss │ └── java │ │ └── com │ │ └── mirfatif │ │ └── privdaemon │ │ └── IPrivTasksFlavorImpl.java │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── mirfatif │ └── privdaemon │ ├── Callbacks.java │ ├── DaemonLog.java │ ├── IPrivTasksImpl.java │ ├── Jni.java │ ├── Main.java │ ├── PrivDaemon.java │ ├── PrivsStatusReader.java │ └── Server.java ├── priv_library ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro └── src │ └── main │ ├── aidl │ └── com │ │ └── mirfatif │ │ └── privtasks │ │ └── bind │ │ ├── ILogCallback.aidl │ │ └── IPrivTasksCallback.aidl │ └── java │ └── com │ └── mirfatif │ ├── err │ ├── ContainerException.java │ └── HiddenAPIsException.java │ └── privtasks │ ├── AppPrivTasks.java │ ├── Constants.java │ ├── HiddenSdkIntConstants.java │ ├── HiddenSdkStringConstants.java │ ├── PrivTasksError.java │ ├── bind │ ├── AppOpsLists.java │ ├── DaemonState.java │ ├── MyPackageInfo.java │ ├── MyPackageOps.java │ ├── PermFixedFlags.java │ ├── PrivsStatus.java │ └── StrIntMap.java │ ├── hiddenapis │ ├── HiddenAPIs.java │ ├── MidReleaseBrokenAPIsDelegate.kt │ └── SysSvcFactory.java │ ├── iface │ └── IPrivTasks.java │ └── util │ ├── CloseableReadWriteLock.java │ ├── LogUtil.java │ ├── MyLog.java │ ├── NonBlockingReader.java │ ├── Util.java │ └── bg │ ├── BgRunner.java │ ├── MinDelayTaskExecutor.java │ ├── NotifyWaiter.java │ ├── RateLimitedTask.java │ ├── RateLimitedTaskTyped.java │ ├── RateLimiter.java │ ├── RunnableWithParam.java │ ├── RunnableWithResult.java │ ├── SingleParamTask.java │ ├── SingleSchedTaskExecutor.java │ ├── SingleTaskExecutor.java │ ├── SingleTaskExecutorAbstract.java │ ├── SingleTaskExecutorTyped.java │ └── ThreadUtils.java ├── privacy_policy.html └── settings.gradle.kts /.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle/ 2 | /.idea/ 3 | 4 | /build/ 5 | 6 | /local.properties 7 | 8 | /out/ 9 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "native/libcap"] 2 | path = native/libcap 3 | url = https://android.googlesource.com/platform/external/libcap 4 | -------------------------------------------------------------------------------- /FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ['https://www.buymeacoffee.com/mirfatif'] 2 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /src/*/assets/*.dx 3 | /src/*/jniLibs/ 4 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Preserve the line number information for debugging stack traces. 2 | -keepattributes SourceFile,LineNumberTable 3 | 4 | # Keep the line number information but hide the original source file name. 5 | -renamesourcefileattribute SourceFile 6 | 7 | # Move all obfuscated classes into the root package. 8 | -repackageclasses 9 | -allowaccessmodification 10 | 11 | # Preference keys are accesses through reflection to reset filters and for backup / restore. 12 | -keepclassmembers class com.mirfatif.permissionmanagerx.R$string { 13 | int pref_*_key; 14 | } 15 | 16 | # Throwable names must not be obfuscated to correctly print e.toString() 17 | -keepnames class com.mirfatif.err.* 18 | 19 | -dontwarn io.github.muntashirakon.adb.AdbProtocol$AuthType 20 | -dontwarn jakarta.annotation.Nullable 21 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/app/AppFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.app; 2 | 3 | public class AppFlavor { 4 | 5 | void onCreated() {} 6 | } 7 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/parser/permsdb/PermsDbFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.parser.permsdb; 2 | 3 | public class PermsDbFlavor { 4 | 5 | public static int getUserIdForPermRefs(int uid) { 6 | return 0; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/pkg/PkgActivityFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.pkg; 2 | 3 | import android.view.Menu; 4 | import android.view.MenuItem; 5 | import com.mirfatif.permissionmanagerx.parser.Package; 6 | import com.mirfatif.permissionmanagerx.parser.Permission; 7 | import java.util.Comparator; 8 | import java.util.List; 9 | 10 | public class PkgActivityFlavor { 11 | 12 | public void sortPermsList(List permissionsList) { 13 | permissionsList.sort(Comparator.comparingInt(Permission::getGroupId)); 14 | } 15 | 16 | public PkgActivityFlavor(PackageActivity activity) {} 17 | 18 | public void onCreateOptionsMenu(Menu menu) {} 19 | 20 | public void onPrepareOptionsMenu(Menu menu, boolean havePerms) {} 21 | 22 | public boolean onOptionsItemSelected(MenuItem item) { 23 | return false; 24 | } 25 | 26 | public Boolean beforePermChange(Package mPackage, Permission permission) { 27 | return true; 28 | } 29 | 30 | public void afterPermChange(Package mPackage, Permission permission, boolean isSystemFixed) {} 31 | 32 | void beforeAppOpChange(Package pkg, Permission appOp, int mode) {} 33 | 34 | public boolean onPermClick(Permission perm) { 35 | return true; 36 | } 37 | 38 | public void onStart() {} 39 | 40 | public void onStop() {} 41 | 42 | public void pkgRefChanged(Package mPackage) {} 43 | } 44 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/prefs/BackupRestoreFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.prefs; 2 | 3 | import com.mirfatif.permissionmanagerx.parser.PackageParser; 4 | 5 | public class BackupRestoreFlavor { 6 | 7 | private BackupRestoreFlavor() {} 8 | 9 | public static void onRestoreDone() { 10 | PackageParser.INS.updatePkgList(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/prefs/MySettingsFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.prefs; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import com.mirfatif.permissionmanagerx.app.App; 6 | import com.mirfatif.permissionmanagerx.parser.Package; 7 | import com.mirfatif.permissionmanagerx.parser.Permission; 8 | 9 | public enum MySettingsFlavor { 10 | INS; 11 | 12 | public Boolean isPkgInstallDate() { 13 | return null; 14 | } 15 | 16 | public boolean allowCriticalChanges() { 17 | return false; 18 | } 19 | 20 | public Boolean handleSearchQuery(String queryText, Package pkg, Permission permission) { 21 | return null; 22 | } 23 | 24 | public SharedPreferences getNoBackupPrefs() { 25 | return App.getCxt() 26 | .getSharedPreferences( 27 | App.getCxt().getPackageName() + "_no_backup_prefs", Context.MODE_PRIVATE); 28 | } 29 | 30 | public boolean showFrameworkPermNames() { 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/prefs/settings/AdvSettingsFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.prefs.settings; 2 | 3 | import androidx.fragment.app.FragmentActivity; 4 | import androidx.preference.PreferenceFragmentCompat; 5 | 6 | public class AdvSettingsFlavor { 7 | 8 | void onCreatePrefs(FragmentActivity activity, PreferenceFragmentCompat frag) {} 9 | 10 | public void onPrefChanged(String key) {} 11 | } 12 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/prefs/settings/FilterSettingsFragFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.prefs.settings; 2 | 3 | public class FilterSettingsFragFlavor { 4 | 5 | public static void onCreatePrefs(FilterSettingsFragment frag) {} 6 | } 7 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/prefs/settings/SearchSettingsFragFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.prefs.settings; 2 | 3 | import static com.mirfatif.permissionmanagerx.util.ApiUtils.getString; 4 | 5 | import androidx.preference.Preference; 6 | import com.mirfatif.permissionmanagerx.R; 7 | import com.mirfatif.permissionmanagerx.fwk.MainActivityM; 8 | import java.util.Objects; 9 | 10 | public class SearchSettingsFragFlavor { 11 | 12 | private final SearchSettingsFrag mPrefFrag; 13 | 14 | SearchSettingsFragFlavor(SearchSettingsFrag prefFrag) { 15 | mPrefFrag = prefFrag; 16 | } 17 | 18 | void onCreatePreferences(MainActivityM activity) { 19 | Preference pref = 20 | mPrefFrag.findPreference(getString(R.string.pref_settings_search_suggestions_count_key)); 21 | Objects.requireNonNull(pref) 22 | .setTitle(getString(R.string.pref_settings_search_suggestions_count_title2, 0)); 23 | } 24 | 25 | public boolean onDisplayPreferenceDialog(Preference preference) { 26 | return false; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/prefs/settings/SettingsActivityFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.prefs.settings; 2 | 3 | import android.content.Intent; 4 | 5 | public class SettingsActivityFlavor { 6 | 7 | public SettingsActivityFlavor(SettingsActivity activity) {} 8 | 9 | public void onCreate() {} 10 | 11 | static boolean shouldCloseOnBackPressed(Intent intent) { 12 | return false; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/prefs/settings/SettingsFragFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.prefs.settings; 2 | 3 | import android.os.Bundle; 4 | import androidx.preference.Preference; 5 | import androidx.preference.PreferenceFragmentCompat; 6 | import com.mirfatif.permissionmanagerx.R; 7 | import com.mirfatif.permissionmanagerx.fwk.SettingsActivityM; 8 | 9 | public class SettingsFragFlavor extends PreferenceFragmentCompat { 10 | 11 | private SettingsActivityM mA; 12 | 13 | public void onStart() { 14 | super.onStart(); 15 | mA = (SettingsActivityM) getActivity(); 16 | } 17 | 18 | public void onResume() { 19 | super.onResume(); 20 | mA.mA.setActionBarTitle(getString(R.string.settings_menu_item)); 21 | } 22 | 23 | private T findPref(int key) { 24 | return findPreference(getString(key)); 25 | } 26 | 27 | public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 28 | setPreferencesFromResource(R.xml.settings_prefs, rootKey); 29 | 30 | findPref(R.string.pref_settings_general_cat_key) 31 | .setFragment(SettingsFragGeneral.class.getName()); 32 | findPref(R.string.pref_settings_theming_cat_key).setFragment(SettingsFragTheme.class.getName()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/prefs/settings/SettingsFragGeneralFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.prefs.settings; 2 | 3 | public class SettingsFragGeneralFlavor { 4 | 5 | private SettingsFragGeneralFlavor() {} 6 | 7 | static void onCreatePreferences(SettingsFragGeneral general) {} 8 | 9 | public static void onSharedPreferenceChanged(String key) {} 10 | } 11 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/privs/DaemonIfaceFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.privs; 2 | 3 | import android.os.IBinder; 4 | 5 | public enum DaemonIfaceFlavor { 6 | INS; 7 | 8 | public void onDaemonStarted(IBinder privTasksFlavor) {} 9 | 10 | public void onDaemonStopped() {} 11 | } 12 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/privs/NativeDaemonFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.privs; 2 | 3 | import static com.mirfatif.permissionmanagerx.BuildConfig.DAEMON_DEX; 4 | 5 | import com.mirfatif.permissionmanagerx.app.App; 6 | import com.mirfatif.permissionmanagerx.util.Utils; 7 | import com.mirfatif.privtasks.util.MyLog; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.io.OutputStream; 11 | 12 | public class NativeDaemonFlavor { 13 | 14 | private NativeDaemonFlavor() {} 15 | 16 | private static final String TAG = "NativeDaemonFlavor"; 17 | 18 | private static final String CMD_SAVE_FILE = "save_file "; 19 | 20 | public static boolean extractDex(String path, NativeDaemon daemon, OutputStream os) { 21 | try (InputStream inStream1 = App.getCxt().getAssets().open(DAEMON_DEX); 22 | InputStream inStream2 = App.getCxt().getAssets().open(DAEMON_DEX)) { 23 | int size = 0; 24 | while (inStream1.read() != -1) { 25 | size++; 26 | } 27 | 28 | daemon.sendCmd(CMD_SAVE_FILE + size + " " + path, null); 29 | 30 | if (!Utils.copyStream(TAG, inStream2, os)) { 31 | MyLog.e(TAG, "extractDex", "Extracting " + DAEMON_DEX + " failed"); 32 | return false; 33 | } 34 | os.flush(); 35 | } catch (IOException e) { 36 | MyLog.e(TAG, "extractDex", e); 37 | return false; 38 | } 39 | 40 | return true; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/profile/PermProfileBackupRestore.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.profile; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import org.xmlpull.v1.XmlSerializer; 6 | 7 | public class PermProfileBackupRestore { 8 | 9 | public static int backup(XmlSerializer ignored) throws IOException { 10 | return -1; 11 | } 12 | 13 | public static int restore(InputStream ignored) { 14 | return -1; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/foss/java/com/mirfatif/permissionmanagerx/util/UiUtilsFlavor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.permissionmanagerx.util; 2 | 3 | import android.app.Activity; 4 | import com.mirfatif.permissionmanagerx.R; 5 | import com.mirfatif.permissionmanagerx.app.App; 6 | 7 | public class UiUtilsFlavor { 8 | 9 | private UiUtilsFlavor() {} 10 | 11 | public static void onCreateStart(Activity activity) {} 12 | 13 | public static int getAccentColor() { 14 | return App.getCxt().getColor(R.color.green); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/foss/res/values-ar/strings_foss.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | مدير الصلاحيّات X 4 | 5 | -------------------------------------------------------------------------------- /app/src/foss/res/values-el/strings_foss.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Διαχειριστής Δικαιωμάτων X 4 | 5 | -------------------------------------------------------------------------------- /app/src/foss/res/values-es/strings_foss.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Permission Manager X 4 | 5 | -------------------------------------------------------------------------------- /app/src/foss/res/values-ru/strings_foss.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Permission Manager X 4 | 5 | -------------------------------------------------------------------------------- /app/src/foss/res/values-tr/strings_foss.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | İzinler Yöneticisi X 4 | 5 | -------------------------------------------------------------------------------- /app/src/foss/res/values-zh-rCN/strings_foss.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 权限管理 X 4 | 5 | -------------------------------------------------------------------------------- /app/src/foss/res/values/strings_foss.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Permission Manager X 4 | 5 | -------------------------------------------------------------------------------- /app/src/foss/res/values/theme.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values-zh-rCN/search_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 核心 4 | 框架 5 | 系统 6 | 用户 7 | 已冻结 8 | 未知 9 | 普通 10 | 危险 11 | 签名 12 | 内置 13 | AppOps 14 | 开发 15 | 特权 16 | 修复 17 | UID 18 | 时间 19 | 额外 20 | 红色 21 | 橙色 22 | 绿色 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #007F7F 4 | #0D007F7F 5 | #1A007F7F 6 | #33007F7F 7 | #80007F7F 8 | #BF007F7F 9 | 10 | @android:color/black 11 | 12 | #FFFFC107 13 | 14 | #80000000 15 | 16 | 17 | #919191 18 | 19 | #80919191 20 | 21 | 22 | #D2D2D2 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/values/search_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Critical 4 | Framework 5 | System 6 | User 7 | Disabled 8 | 9 | Unknown 10 | Normal 11 | Dangerous 12 | Signature 13 | Internal 14 | AppOps 15 | Development 16 | Privileged 17 | Fixed 18 | UID 19 | TIME 20 | EXTRA 21 | RED 22 | ORANGE 23 | GREEN 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/xml/settings_prefs_theming.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/release/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 10 | 11 | 15 | 16 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.diffplug.gradle.spotless.SpotlessExtensionPredeclare 2 | import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask 3 | import java.io.FileInputStream 4 | import java.util.Properties 5 | 6 | plugins { 7 | id("spotless-conventions") 8 | alias(libs.plugins.task.tree) 9 | alias(libs.plugins.gradle.versions) 10 | alias(libs.plugins.gradle.dependency.analysis) 11 | } 12 | 13 | val localProps = Properties() 14 | 15 | localProps.load(FileInputStream(File(rootDir, "local.properties"))) 16 | 17 | val ndkDir: String = 18 | File(localProps["sdk.dir"].toString(), "ndk/" + libs.versions.sdk.ndk.get()).absolutePath 19 | 20 | allprojects { 21 | project.extra.set("ndkDir", ndkDir) 22 | project.extra.set("nativeDir", rootDir.absolutePath + "/native") 23 | project.extra.set("daemonDex", "daemon.dx") 24 | project.extra.set("noPro", !File(rootDir, "configs/pro-app.gradle").isFile) 25 | } 26 | 27 | // https://github.com/diffplug/spotless/issues/1380#issuecomment-1405392506 28 | spotless { predeclareDeps() } 29 | 30 | configure { 31 | java { googleJavaFormat() } 32 | kotlin { ktfmt() } 33 | } 34 | 35 | fun isStableVersion(version: String): Boolean { 36 | return ".*-(rc|beta|alpha)(|-)[0-9]*$".toRegex().matches(version.lowercase()).not() 37 | } 38 | 39 | tasks.register("buildSrcDependencyUpdates") { 40 | dir = File(rootDir, "buildSrc") 41 | tasks = mutableListOf("dependencyUpdates") 42 | buildName = "buildSource" 43 | } 44 | 45 | tasks.withType { 46 | dependsOn("buildSrcDependencyUpdates") 47 | rejectVersionIf { !isStableVersion(candidate.version) && isStableVersion(currentVersion) } 48 | } 49 | -------------------------------------------------------------------------------- /buildSrc/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /.gradle 3 | -------------------------------------------------------------------------------- /buildSrc/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask 2 | 3 | plugins { 4 | `kotlin-dsl` 5 | id("com.diffplug.spotless").version("6.25.0").apply(true) 6 | id("com.github.ben-manes.versions").version("0.51.0").apply(true) 7 | } 8 | 9 | // This is a replacement of plugins {} block in root build.gradle.kts 10 | dependencies { 11 | implementation(libs.plugin.android.application) 12 | implementation(libs.plugin.android.library) 13 | implementation(libs.plugin.jetbrains.kotlin.android) 14 | 15 | implementation(libs.plugin.spotless) 16 | implementation(libs.plugin.lsparanoid) 17 | 18 | // Make version catalogs available to convention plugins 19 | // https://github.com/gradle/gradle/issues/15383 20 | implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) 21 | } 22 | 23 | spotless { 24 | java { 25 | target("src/**/*.java") 26 | googleJavaFormat() 27 | } 28 | 29 | kotlin { 30 | target("src/**/*.kt", "src/**/*.kts", "*.kts") 31 | ktfmt() 32 | } 33 | } 34 | 35 | tasks.named("jar").get().dependsOn("spotlessApply") 36 | 37 | fun isStableVersion(version: String): Boolean { 38 | return ".*-(rc|beta|alpha)(|-)[0-9]*$".toRegex().matches(version.lowercase()).not() 39 | } 40 | 41 | tasks.withType { 42 | rejectVersionIf { !isStableVersion(candidate.version) && isStableVersion(currentVersion) } 43 | } 44 | -------------------------------------------------------------------------------- /buildSrc/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("UnstableApiUsage") 2 | dependencyResolutionManagement { 3 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 4 | 5 | repositories { 6 | mavenLocal() 7 | mavenCentral() 8 | google() 9 | gradlePluginPortal() 10 | } 11 | 12 | versionCatalogs { create("libs") { from(files("../gradle/libs.versions.toml")) } } 13 | } 14 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/android-base-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("org.jetbrains.kotlin.android") 3 | id("java-kotlin-conventions") 4 | } 5 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/android-lib-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.gradle.accessors.dm.LibrariesForLibs 2 | 3 | plugins { 4 | id("com.android.library") 5 | id("android-base-conventions") 6 | } 7 | 8 | val libs = the() 9 | 10 | android { 11 | compileSdk = libs.versions.sdk.compile.get().toInt() 12 | buildToolsVersion = libs.versions.sdk.tools.build.get() 13 | 14 | defaultConfig { minSdk = libs.versions.sdk.min.get().toInt() } 15 | 16 | compileOptions { 17 | sourceCompatibility = JavaVersion.VERSION_17 18 | targetCompatibility = JavaVersion.VERSION_17 19 | } 20 | 21 | kotlinOptions { jvmTarget = "17" } 22 | 23 | buildFeatures { buildConfig = false } 24 | } 25 | 26 | dependencies { 27 | implementation(libs.androidx.annotation) 28 | compileOnly(libs.lsparanoid.core) 29 | } 30 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/apk-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.gradle.accessors.dm.LibrariesForLibs 2 | 3 | plugins { 4 | id("com.android.application") 5 | id("org.lsposed.lsparanoid") 6 | id("android-base-conventions") 7 | } 8 | 9 | val libs = the() 10 | 11 | android { 12 | compileSdk = libs.versions.sdk.compile.get().toInt() 13 | buildToolsVersion = libs.versions.sdk.tools.build.get() 14 | 15 | defaultConfig { 16 | minSdk = libs.versions.sdk.min.get().toInt() 17 | targetSdk = libs.versions.sdk.target.get().toInt() 18 | 19 | multiDexEnabled = true // Required for desugaring 20 | } 21 | 22 | compileOptions { 23 | sourceCompatibility = JavaVersion.VERSION_17 24 | targetCompatibility = JavaVersion.VERSION_17 25 | 26 | isCoreLibraryDesugaringEnabled = true 27 | } 28 | 29 | kotlinOptions { jvmTarget = "17" } 30 | 31 | buildTypes { 32 | release { 33 | isMinifyEnabled = true 34 | isShrinkResources = true 35 | 36 | proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") 37 | } 38 | } 39 | 40 | dependenciesInfo { includeInApk = false } 41 | 42 | buildFeatures { 43 | viewBinding = true 44 | dataBinding = true 45 | buildConfig = true 46 | compose = true 47 | } 48 | 49 | composeOptions { 50 | kotlinCompilerExtensionVersion = libs.versions.compose.kotlin.compiler.ext.get() 51 | } 52 | } 53 | 54 | lsparanoid { 55 | includeDependencies = true 56 | classFilter = { it.startsWith("com.mirfatif.") } 57 | } 58 | 59 | dependencies { 60 | implementation(libs.androidx.annotation) 61 | coreLibraryDesugaring(libs.desugar.jdk) 62 | } 63 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/java-android-lib-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.gradle.accessors.dm.LibrariesForLibs 2 | 3 | plugins { 4 | id("java-library") 5 | id("java-lib-conventions") 6 | } 7 | 8 | val libs = the() 9 | 10 | dependencies { compileOnly(libs.lsparanoid.core) } 11 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/java-base-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.gradle.accessors.dm.LibrariesForLibs 2 | import org.gradle.kotlin.dsl.the 3 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget 4 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 5 | 6 | plugins { 7 | id("org.jetbrains.kotlin.jvm") 8 | id("java-kotlin-conventions") 9 | } 10 | 11 | java { 12 | sourceCompatibility = JavaVersion.VERSION_17 13 | targetCompatibility = JavaVersion.VERSION_17 14 | } 15 | 16 | tasks.withType { 17 | kotlinOptions.jvmTarget = "17" 18 | compilerOptions.jvmTarget.set(JvmTarget.JVM_17) 19 | } 20 | 21 | val libs = the() 22 | 23 | dependencies { compileOnly(libs.jetbrains.annotations) } 24 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/java-kotlin-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { id("spotless-conventions") } 4 | 5 | // https://docs.oracle.com/en/java/javase/17/docs/specs/man/javac.html#examples-of-using--xlint-keys 6 | tasks.withType { 7 | options.compilerArgs.addAll( 8 | arrayOf("-Xlint:all,-processing,-try,-serial", "-XDstring-concat=inline")) 9 | } 10 | 11 | tasks.withType { 12 | kotlinOptions.freeCompilerArgs += 13 | "-Xjavac-arguments=['-Xlint:all,-processing,-try,-serial', '-XDstring-concat=inline']" 14 | kotlinOptions.freeCompilerArgs += "-Xstring-concat=inline" 15 | } 16 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/java-lib-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("java-library") 3 | id("java-base-conventions") 4 | } 5 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/spotless-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { id("com.diffplug.spotless") } 4 | 5 | spotless { 6 | java { 7 | target("src/**/*.java") 8 | googleJavaFormat() 9 | } 10 | 11 | kotlin { 12 | target("src/**/*.kt", "src/**/*.kts", "*.kts") 13 | ktfmt() 14 | } 15 | } 16 | 17 | tasks.withType { dependsOn("spotlessCheck") } 18 | 19 | tasks.withType { dependsOn("spotlessCheck") } 20 | 21 | afterEvaluate { tasks.findByName("preBuild")?.dependsOn("spotlessCheck") } 22 | -------------------------------------------------------------------------------- /configs/foss-pro-flavors.gradle: -------------------------------------------------------------------------------- 1 | // Arbitrary objects configuration is not possible in .gradle.kts 2 | // So the script cannot be shared with app and libraries. 3 | // https://docs.gradle.org/current/userguide/writing_build_scripts.html#sec:configuring_arbitrary_objects_using_an_external_script 4 | 5 | android { 6 | flavorDimensions 'version' 7 | productFlavors { 8 | foss { 9 | dimension 'version' 10 | } 11 | pro { 12 | dimension 'version' 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /fastlane/metadata/android/ar/short_description.txt: -------------------------------------------------------------------------------- 1 | مدير أذونات eXtended - تطبيق صغير لإدارة الأذونات والتطبيقات 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/ar/title.txt: -------------------------------------------------------------------------------- 1 | مدير الصلاحيّات X 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/de/short_description.txt: -------------------------------------------------------------------------------- 1 | eXtended Permission Manager - eine App zum Verwalten von Berechtigungen u.v.m 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/el/title.txt: -------------------------------------------------------------------------------- 1 | Διαχειριστής Δικαιωμάτων X 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/101.txt: -------------------------------------------------------------------------------- 1 | Initial release. Enjoy it. It's gonna taste a bit unique :) 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/103.txt: -------------------------------------------------------------------------------- 1 | Fixed AppOps mode spinner click area 2 | Disabled Foreground AppOp mode for RUN_IN_BACKGROUND 3 | Added option to skip uninstalled apps in backup/restore 4 | Fixed Exclusin Filter Settings Fragment crash on orientation changes 5 | Improved Help section 6 | Added | and & to search queries 7 | Added Telegram support group link and paid features to About section 8 | Added "Ask for redeem code" option to Donate dialog 9 | Ask to send app and daemon's crash log files, delete files older than a month 10 | Fixed permissions Activity crash on launch due to null ActionBar 11 | Fixed OutOfMemory crash by releasing Icon Bitmaps on low memory conditions 12 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/104.txt: -------------------------------------------------------------------------------- 1 | Added Android 11 support 2 | Improved crash reporting 3 | Added SELinux context, ADB port and Switch to ADB in Advanced Settings 4 | Improved performance and app size 5 | Added app update check 6 | Reduced dialog interventions 7 | Improved Snackbar and ProgressBar theming 8 | Made Help more friendly and accessible 9 | Fixed AppOp's getLastAccessTime() crash on Pie 10 | Fixed memory leaks 11 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/105.txt: -------------------------------------------------------------------------------- 1 | Fixed crash due to space in some permissions name 2 | Temp fix for bug in androidx.security: https://github.com/google/tink/issues/413 3 | Added option to run daemon from /data/local/tmp or external storage 4 | Run logcat collection as a foreground service with notification 5 | Build hidden APIs with official SDK without requiring any modifications 6 | Improved log tags 7 | Fixed ArrayAdapter memory leak 8 | Added quick scan option for speed lovers 9 | Make deep search faster 10 | Added NOT operator in search queries 11 | Added preference for special search characters: AND, OR and NOT 12 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/106.txt: -------------------------------------------------------------------------------- 1 | Added receive back commands from daemon through Intents 2 | Improved About section, warnings and Advanced Settings 3 | Fixed crashes due to OEM's bad implementations 4 | Bumped library and NDK versions 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/107.txt: -------------------------------------------------------------------------------- 1 | Added Russian translation 2 | Major changes for locale awareness 3 | Fix for modified AppOp modes in LineageOS 4 | Numerous fixes and improvements 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/108.txt: -------------------------------------------------------------------------------- 1 | Updated libcap 2 | Changes for new features in Play Store version 3 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/109.txt: -------------------------------------------------------------------------------- 1 | Fixed crash due to theme not set in Activity 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/110.txt: -------------------------------------------------------------------------------- 1 | Improved help and Exclusion Filters 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/111.txt: -------------------------------------------------------------------------------- 1 | Added daemon privileges and AppOps bugs menu item in About 2 | Made search in permissions case sensitive 3 | Improved long press dialog Exclude button logic 4 | Added exclusion filters master switch 5 | Improved R8 rules to reduce app size and better optimization 6 | Improved touch ripples 7 | Updated README, help and fastlane descriptions 8 | Do reset() on OOS to avoid OOM 9 | Improved dialog handling after orientation change 10 | Replaced singletons with enums, removed ViewModel 11 | Made on-UI calls from background Lifecycle aware 12 | Fixed crash and improved WebView 13 | Added Spanish translation and updated translations 14 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/112.txt: -------------------------------------------------------------------------------- 1 | - Added Android 12 support 2 | - Improved preferences 3 | - Moved search settings with SearchBar, added search keyword list 4 | - Fixes for RTL layout 5 | - Added Arabic translation 6 | - Updated translations and help 7 | - Replaced some Alert Dialogs with Bottom Dialogs 8 | - Integration with WhatsRunning 9 | - Added Dialog background and animations to Github/F-Droid version 10 | - Changes for Play Store independent Pro version 11 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/113.txt: -------------------------------------------------------------------------------- 1 | - Chinese and Greek translations 2 | - Target Android 13 3 | - Binder IPC for app <--> daemon 4 | - Improved ADB pairing and connection 5 | - Show a corner tag with manifest permissions in permission list 6 | - "Follow System" option for dark theme 7 | - Menu item to temporarily show all permissions of an app 8 | - Replace AppOp states drop-down menu with toggle switch 9 | - Option to reset / cleanup permission references database 10 | - Option to send crash log to server 11 | - Fixed crashes, code cleanup, minor improvements 12 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/114.txt: -------------------------------------------------------------------------------- 1 | - Bug fixes -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/116.txt: -------------------------------------------------------------------------------- 1 | - Added Permission View (Pro) 2 | - Added permission names (Pro) 3 | - Increased tap area of permission switch 4 | - Updated permission names, descriptions, groups, icons 5 | - Updated translations 6 | - Fixed crash due to feedback views called on worker thread 7 | - Fixed crash due to get users from daemon called on main thread 8 | - Fixed crash due to INTERACT_ACROSS_USERS injected in getPackagesForUid in S+ 9 | - Minor fixes and improvements 10 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/117.txt: -------------------------------------------------------------------------------- 1 | - Process package filters on worker thread 2 | - Update translations 3 | - Improve privileges dialog message and help link 4 | - Fix Scheduled Checker not working due to app always in FG 5 | - Fix extra AppOps not selected with pretty permission names 6 | - Bump libraries 7 | - Fix issues due to background service restrictions 8 | - Fix rare NPE crashes 9 | - Fix crash due to App context null 10 | - Fix ANR due to lock contention 11 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/118.txt: -------------------------------------------------------------------------------- 1 | - Fixed crashes 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/119.txt: -------------------------------------------------------------------------------- 1 | - Fixed crashes 2 | - Bumped libraries and build plugins 3 | - Minor improvements 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/120.txt: -------------------------------------------------------------------------------- 1 | - Fixed crashes 2 | - Minor improvements 3 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/121.txt: -------------------------------------------------------------------------------- 1 | - Fix Excluded Apps and AppOps not Restored from backup 2 | - Add 'All users' options in Main Activity menu 3 | - Add option to notify only red states in Scheduled Checks 4 | - Remove watcher notifications if an app is uninstalled 5 | - Increase permission switch padding 6 | - Fixed crashes 7 | - Minor improvements 8 | - Bump libraries 9 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/122.txt: -------------------------------------------------------------------------------- 1 | - Added 'Batch Operations' / 'Permission Profiles' 2 | - Updates translations 3 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/123.txt: -------------------------------------------------------------------------------- 1 | - Added 'Clone' button to profile permission long press menu (pro) 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/124.txt: -------------------------------------------------------------------------------- 1 | - Added new permission names / descriptions for Android 14 2 | - Updated translations 3 | - Fixed crashes, random improvements 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/125.txt: -------------------------------------------------------------------------------- 1 | - Target Android 14 2 | - Make Perm Watcher more aggressive 3 | - Add Turkish translation 4 | - Bug fixes and improvements 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/126.txt: -------------------------------------------------------------------------------- 1 | - Minor fixes and improvements 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/127.txt: -------------------------------------------------------------------------------- 1 | - Fixed a crash due to internal API changes in Android 14 2 | - Updated translations 3 | - Minor fixes and improvements 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/featureGraphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/fastlane/metadata/android/en-US/images/featureGraphic.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/fastlane/metadata/android/en-US/images/phoneScreenshots/1.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/fastlane/metadata/android/en-US/images/phoneScreenshots/2.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/fastlane/metadata/android/en-US/images/phoneScreenshots/3.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/fastlane/metadata/android/en-US/images/phoneScreenshots/4.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/fastlane/metadata/android/en-US/images/phoneScreenshots/5.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/fastlane/metadata/android/en-US/images/phoneScreenshots/6.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | eXtended Permission Manager - a small app to manage permissions and AppOps 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/title.txt: -------------------------------------------------------------------------------- 1 | Permission Manager X 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/es/short_description.txt: -------------------------------------------------------------------------------- 1 | eXtended Permission Manager - una pequeña app para administrar permisos y AppOps 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/es/title.txt: -------------------------------------------------------------------------------- 1 | Permission Manager X 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/ru/short_description.txt: -------------------------------------------------------------------------------- 1 | eXtended Permission Manager - приложение для управления разрешениями и AppOps 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/ru/title.txt: -------------------------------------------------------------------------------- 1 | Permission Manager X 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/tr/title.txt: -------------------------------------------------------------------------------- 1 | İzinler Yöneticisi X 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/ur/title.txt: -------------------------------------------------------------------------------- 1 | پرمیشن مینیجر ایکس 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/zh/short_description.txt: -------------------------------------------------------------------------------- 1 | 增强型权限管理器 - 一个管理权限和 AppOps 的应用 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/zh/title.txt: -------------------------------------------------------------------------------- 1 | 权限管理 X 2 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | 8 | # Specifies the JVM arguments used for the daemon process. 9 | # The setting is particularly useful for tweaking memory settings. 10 | org.gradle.jvmargs=-Xmx2048m 11 | 12 | # When configured, Gradle will run in incubating parallel mode. 13 | # This option should only be used with decoupled projects. More details, visit 14 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 15 | # org.gradle.parallel=true 16 | 17 | # AndroidX package structure to make it clearer which packages are bundled with the 18 | # Android operating system, and which are packaged with your app"s APK 19 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 20 | android.useAndroidX=true 21 | 22 | # Automatically convert third-party libraries to use AndroidX 23 | #android.enableJetifier=true 24 | 25 | # Improve Compose preview rendering performance. 26 | #org.gradle.configuration-cache=true 27 | 28 | # Show deprecated Gradle features and obsolete APIs 29 | org.gradle.warning.mode=all 30 | android.debug.obsoleteApi=true 31 | 32 | #android.enableR8.fullMode=true 33 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip 6 | -------------------------------------------------------------------------------- /help/cn/img/perm.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/cn/img/perm.webp -------------------------------------------------------------------------------- /help/cn/img/search.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/cn/img/search.webp -------------------------------------------------------------------------------- /help/en/img/adb_in_dev_options_1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/adb_in_dev_options_1.webp -------------------------------------------------------------------------------- /help/en/img/adb_in_dev_options_11_1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/adb_in_dev_options_11_1.webp -------------------------------------------------------------------------------- /help/en/img/adb_in_dev_options_11_2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/adb_in_dev_options_11_2.webp -------------------------------------------------------------------------------- /help/en/img/adb_in_dev_options_11_3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/adb_in_dev_options_11_3.webp -------------------------------------------------------------------------------- /help/en/img/adb_in_dev_options_2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/adb_in_dev_options_2.webp -------------------------------------------------------------------------------- /help/en/img/adb_in_dev_options_3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/adb_in_dev_options_3.webp -------------------------------------------------------------------------------- /help/en/img/adb_pairing.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/adb_pairing.mp4 -------------------------------------------------------------------------------- /help/en/img/allow_network_access.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/allow_network_access.webp -------------------------------------------------------------------------------- /help/en/img/banner.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/banner.webp -------------------------------------------------------------------------------- /help/en/img/fg_and_one_time_perm_modes.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/fg_and_one_time_perm_modes.webp -------------------------------------------------------------------------------- /help/en/img/hide_app_from_list.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/hide_app_from_list.webp -------------------------------------------------------------------------------- /help/en/img/hide_perm_from_list.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/hide_perm_from_list.webp -------------------------------------------------------------------------------- /help/en/img/icon.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/icon.webp -------------------------------------------------------------------------------- /help/en/img/multi_users.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/multi_users.webp -------------------------------------------------------------------------------- /help/en/img/perm.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/perm.webp -------------------------------------------------------------------------------- /help/en/img/perm2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/perm2.webp -------------------------------------------------------------------------------- /help/en/img/perm_profiles.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/perm_profiles.webp -------------------------------------------------------------------------------- /help/en/img/perm_view.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/perm_view.webp -------------------------------------------------------------------------------- /help/en/img/perm_view2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/perm_view2.webp -------------------------------------------------------------------------------- /help/en/img/perm_watcher.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/perm_watcher.gif -------------------------------------------------------------------------------- /help/en/img/pkg.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/pkg.webp -------------------------------------------------------------------------------- /help/en/img/privs.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/privs.webp -------------------------------------------------------------------------------- /help/en/img/remove_unused_perms.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/remove_unused_perms.webp -------------------------------------------------------------------------------- /help/en/img/search.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/search.webp -------------------------------------------------------------------------------- /help/en/img/set_refs.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/set_refs.webp -------------------------------------------------------------------------------- /help/en/img/unsupported_android_version_warning.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/unsupported_android_version_warning.webp -------------------------------------------------------------------------------- /help/en/img/watcher_settings.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/watcher_settings.webp -------------------------------------------------------------------------------- /help/en/img/wrun_integration1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/wrun_integration1.jpg -------------------------------------------------------------------------------- /help/en/img/wrun_integration2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/en/img/wrun_integration2.webp -------------------------------------------------------------------------------- /help/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/favicon.ico -------------------------------------------------------------------------------- /help/help.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | PMX - Manage app permissions gracefully 11 | 12 | 13 | 14 | 15 | 16 |

Redirecting to en/

17 | 18 | 19 | -------------------------------------------------------------------------------- /help/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | PMX - Manage app permissions gracefully 11 | 12 | 13 | 14 | 15 | 16 |

Redirecting to en/

17 | 18 | 19 | -------------------------------------------------------------------------------- /help/ru/img/perm.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/ru/img/perm.webp -------------------------------------------------------------------------------- /help/ru/img/search.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirfatif/PermissionManagerX/05e72a79d1cbde3cc4ee505caa5c818ec00af353/help/ru/img/search.webp -------------------------------------------------------------------------------- /hidden_apis/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | -------------------------------------------------------------------------------- /hidden_apis/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { id("android-lib-conventions") } 2 | 3 | apply(from = "$rootDir/configs/foss-pro-flavors.gradle") 4 | 5 | android { namespace = "com.mirfatif.hiddenapis" } 6 | -------------------------------------------------------------------------------- /hidden_apis/src/foss/java/android/app/ActivityManagerNative.java: -------------------------------------------------------------------------------- 1 | package android.app; 2 | 3 | public abstract class ActivityManagerNative { 4 | 5 | public static IActivityManager getDefault() { 6 | return null; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /hidden_apis/src/foss/java/android/app/AppOpsManager.java: -------------------------------------------------------------------------------- 1 | package android.app; 2 | 3 | import java.util.List; 4 | 5 | public class AppOpsManager { 6 | 7 | public abstract static class PackageOps { 8 | 9 | public abstract List getOps(); 10 | 11 | public abstract String getPackageName(); 12 | } 13 | 14 | public abstract static class OpEntry { 15 | 16 | public abstract int getOp(); 17 | 18 | public abstract int getMode(); 19 | 20 | public abstract long getLastAccessTime(int i); 21 | 22 | public abstract long getTime(); 23 | } 24 | 25 | public static final String[] MODE_NAMES = null; 26 | 27 | public static final int MODE_ALLOWED = 0; 28 | 29 | public static final int MODE_IGNORED = 1; 30 | 31 | public static final int MODE_ERRORED = 2; 32 | 33 | public static final int MODE_DEFAULT = 3; 34 | 35 | public static final int MODE_FOREGROUND = 4; 36 | 37 | public static int getNumOps() { 38 | return 0; 39 | } 40 | 41 | public static int opToDefaultMode(int i) { 42 | return 0; 43 | } 44 | 45 | public static int opToDefaultMode(int i, boolean b) { 46 | return 0; 47 | } 48 | 49 | public static int opToSwitch(int i) { 50 | return 0; 51 | } 52 | 53 | public static String opToName(int i) { 54 | return null; 55 | } 56 | 57 | public static String modeToName(int i) { 58 | return null; 59 | } 60 | 61 | public static int permissionToOpCode(String s) { 62 | return 0; 63 | } 64 | 65 | public static int strDebugOpToOp(String s) { 66 | return 0; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /hidden_apis/src/foss/java/android/app/IActivityManager.java: -------------------------------------------------------------------------------- 1 | package android.app; 2 | 3 | import android.content.ComponentName; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.os.IBinder; 7 | 8 | public interface IActivityManager { 9 | 10 | int startActivityAsUser( 11 | IApplicationThread o1, 12 | String o2, 13 | Intent o3, 14 | String o4, 15 | IBinder o5, 16 | String o6, 17 | int i1, 18 | int i2, 19 | ProfilerInfo o7, 20 | Bundle o8, 21 | int i3); 22 | 23 | ComponentName startService( 24 | IApplicationThread o1, Intent o2, String o3, boolean b, String o4, String o5, int i); 25 | 26 | ComponentName startService( 27 | IApplicationThread o1, Intent o2, String o3, boolean b, String o4, int i); 28 | 29 | ComponentName startService(IApplicationThread o1, Intent o2, String o3, String o4, int i); 30 | 31 | int checkPermission(String s, int i1, int i2); 32 | 33 | abstract class Stub { 34 | 35 | public static IActivityManager asInterface(IBinder o) { 36 | return null; 37 | } 38 | } 39 | } 40 | 41 | class IApplicationThread {} 42 | 43 | class ProfilerInfo {} 44 | -------------------------------------------------------------------------------- /hidden_apis/src/foss/java/android/content/Context.java: -------------------------------------------------------------------------------- 1 | package android.content; 2 | 3 | public class Context { 4 | 5 | public static final String DEVICE_IDLE_CONTROLLER = null; 6 | 7 | public static final String ACTIVITY_SERVICE = "activity"; 8 | 9 | public static final String APP_OPS_SERVICE = "appops"; 10 | 11 | public static final int DEVICE_ID_DEFAULT = 0; 12 | } 13 | -------------------------------------------------------------------------------- /hidden_apis/src/foss/java/android/content/pm/IPackageManager.java: -------------------------------------------------------------------------------- 1 | package android.content.pm; 2 | 3 | import android.os.IBinder; 4 | 5 | public interface IPackageManager { 6 | 7 | ParceledListSlice getAllPermissionGroups(int i); 8 | 9 | ParceledListSlice queryPermissionsByGroup(String s, int i); 10 | 11 | int getPermissionFlags(String s1, String s2, int i); 12 | 13 | void grantRuntimePermission(String s1, String s2, int i); 14 | 15 | void revokeRuntimePermission(String s1, String s2, int i); 16 | 17 | void setApplicationEnabledSetting(String s1, int i1, int i2, int i3, String s2); 18 | 19 | String[] getPackagesForUid(int i); 20 | 21 | abstract class Stub { 22 | 23 | public static IPackageManager asInterface(IBinder o) { 24 | return null; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /hidden_apis/src/foss/java/android/content/pm/ParceledListSlice.java: -------------------------------------------------------------------------------- 1 | package android.content.pm; 2 | 3 | import java.util.List; 4 | 5 | public abstract class ParceledListSlice { 6 | 7 | public abstract List getList(); 8 | } 9 | -------------------------------------------------------------------------------- /hidden_apis/src/foss/java/android/os/IDeviceIdleController.java: -------------------------------------------------------------------------------- 1 | package android.os; 2 | 3 | public interface IDeviceIdleController { 4 | 5 | void addPowerSaveWhitelistApp(String s); 6 | 7 | abstract class Stub { 8 | 9 | public static IDeviceIdleController asInterface(IBinder o) { 10 | return null; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /hidden_apis/src/foss/java/android/os/Process.java: -------------------------------------------------------------------------------- 1 | package android.os; 2 | 3 | public class Process { 4 | 5 | public static int[] getPidsForCommands(String[] o) { 6 | return null; 7 | } 8 | 9 | public static int myPid() { 10 | return 0; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /hidden_apis/src/foss/java/android/os/ServiceManager.java: -------------------------------------------------------------------------------- 1 | package android.os; 2 | 3 | public class ServiceManager { 4 | 5 | public static IBinder getService(String s) { 6 | return null; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /hidden_apis/src/foss/java/android/permission/IPermissionManager.java: -------------------------------------------------------------------------------- 1 | package android.permission; 2 | 3 | import android.content.pm.ParceledListSlice; 4 | import android.os.IBinder; 5 | 6 | public interface IPermissionManager { 7 | 8 | ParceledListSlice getAllPermissionGroups(int i); 9 | 10 | ParceledListSlice queryPermissionsByGroup(String s, int i); 11 | 12 | int getPermissionFlags(String s1, String s2, int i); 13 | 14 | int getPermissionFlags(String s1, String s2, int i1, int i2); 15 | 16 | int getPermissionFlags(String s1, String s2, String s3, int i2); 17 | 18 | void grantRuntimePermission(String s1, String s2, int i); 19 | 20 | void grantRuntimePermission(String s1, String s2, int i1, int i2); 21 | 22 | void grantRuntimePermission(String s1, String s2, String s3, int i2); 23 | 24 | void revokeRuntimePermission(String s1, String s2, int i, String s3); 25 | 26 | void revokeRuntimePermission(String s1, String s2, int i1, int i2, String s3); 27 | 28 | void revokeRuntimePermission(String s1, String s2, String s3, int i2, String s4); 29 | 30 | abstract class Stub { 31 | 32 | public static IPermissionManager asInterface(IBinder o) { 33 | return null; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /hidden_apis/src/foss/java/com/android/internal/app/IAppOpsService.java: -------------------------------------------------------------------------------- 1 | package com.android.internal.app; 2 | 3 | import android.app.AppOpsManager.PackageOps; 4 | import android.os.IBinder; 5 | import java.util.List; 6 | 7 | public interface IAppOpsService { 8 | 9 | void setMode(int i1, int i2, String s, int i3); 10 | 11 | void setUidMode(int i1, int i2, int i3); 12 | 13 | void resetAllModes(int i, String s); 14 | 15 | List getUidOps(int i, int[] o); 16 | 17 | List getOpsForPackage(int i, String s, int[] o); 18 | 19 | abstract class Stub { 20 | 21 | public static IAppOpsService asInterface(IBinder o) { 22 | return null; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /priv_daemon/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | -------------------------------------------------------------------------------- /priv_daemon/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { id("apk-conventions") } 2 | 3 | apply(from = "$rootDir/configs/foss-pro-flavors.gradle") 4 | 5 | android { 6 | namespace = "com.mirfatif.privdaemon" 7 | 8 | defaultConfig { applicationId = namespace } 9 | 10 | buildFeatures { 11 | resValues = false 12 | 13 | viewBinding = false 14 | dataBinding = false 15 | buildConfig = false 16 | compose = false 17 | } 18 | } 19 | 20 | dependencies { implementation(project(path = ":priv_library")) } 21 | 22 | lsparanoid { variantFilter = { !it.name.startsWith("foss") && it.buildType != "debug" } } 23 | -------------------------------------------------------------------------------- /priv_daemon/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Preserve the line number information for debugging stack traces. 2 | -keepattributes SourceFile,LineNumberTable 3 | 4 | # Keep the line number information but hide the original source file name. 5 | -renamesourcefileattribute SourceFile 6 | 7 | # Move all obfuscated classes into the root package. 8 | -repackageclasses 9 | -allowaccessmodification 10 | 11 | # VM entry point must be kept. 12 | -keep class com.mirfatif.privdaemon.Main { 13 | public static void main(java.lang.String[]); 14 | } 15 | 16 | # Throwable names must not be obfuscated to correctly print e.toString() 17 | -keepnames class com.mirfatif.err.* 18 | -------------------------------------------------------------------------------- /priv_daemon/src/foss/java/com/mirfatif/privdaemon/IPrivTasksFlavorImpl.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privdaemon; 2 | 3 | import android.os.IBinder; 4 | import com.mirfatif.privtasks.AppPrivTasks; 5 | 6 | public class IPrivTasksFlavorImpl { 7 | 8 | public IPrivTasksFlavorImpl(AppPrivTasks.AppPrivTasksCallback obj) {} 9 | 10 | public void onDaemonStopped() {} 11 | 12 | public IBinder asBinder() { 13 | return null; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /priv_daemon/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /priv_daemon/src/main/java/com/mirfatif/privdaemon/DaemonLog.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privdaemon; 2 | 3 | import com.mirfatif.privtasks.util.MyLog; 4 | 5 | public class DaemonLog { 6 | 7 | private DaemonLog() {} 8 | 9 | private static String makeTag(String tag) { 10 | return PrivDaemon.TAG + (tag == null ? "" : ": " + tag); 11 | } 12 | 13 | public static void e(String tag, String method, Throwable e) { 14 | MyLog.e(makeTag(tag), method, e); 15 | } 16 | 17 | public static void e(String tag, String method, String err) { 18 | MyLog.e(makeTag(tag), method, err); 19 | } 20 | 21 | public static void w(String tag, String method, String msg) { 22 | MyLog.w(makeTag(tag), method, msg); 23 | } 24 | 25 | public static void i(String tag, String method, String msg) { 26 | MyLog.i(makeTag(tag), method, msg); 27 | } 28 | 29 | public static void d(String tag, String method, String msg) { 30 | if (Callbacks.INS.isDebug()) { 31 | MyLog.d(makeTag(tag), method, msg); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /priv_daemon/src/main/java/com/mirfatif/privdaemon/Jni.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privdaemon; 2 | 3 | import com.mirfatif.err.HiddenAPIsException; 4 | 5 | public enum Jni { 6 | INS; 7 | 8 | private boolean mLoaded = false; 9 | 10 | public void loadLib(String libPath) throws HiddenAPIsException { 11 | if (!mLoaded) { 12 | try { 13 | System.load(libPath); 14 | mLoaded = true; 15 | } catch (SecurityException | UnsatisfiedLinkError e) { 16 | throw new HiddenAPIsException(e); 17 | } 18 | } 19 | } 20 | 21 | public native boolean sendStdErr(int errPort); 22 | 23 | public native void closeStdErr(); 24 | 25 | public native boolean matches(String string, String regex, String logTag); 26 | } 27 | -------------------------------------------------------------------------------- /priv_daemon/src/main/java/com/mirfatif/privdaemon/Main.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privdaemon; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | new PrivDaemon().start(args); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /priv_library/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | -------------------------------------------------------------------------------- /priv_library/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { id("android-lib-conventions") } 2 | 3 | apply(from = "$rootDir/configs/foss-pro-flavors.gradle") 4 | 5 | android { 6 | namespace = "com.mirfatif.privtasks" 7 | buildTypes { release { consumerProguardFiles("proguard-rules.pro", "proguard-rules-pro.pro") } } 8 | 9 | buildFeatures { aidl = true } 10 | } 11 | 12 | dependencies { 13 | // Just to resolve APIs in editor 14 | compileOnly(project(path = ":hidden_apis")) 15 | } 16 | 17 | fun createTasksForHiddenAPIs() { 18 | val dir = File(rootDir, "hidden_apis/build/intermediates/aar_main_jar/") 19 | 20 | for (foss in booleanArrayOf(true, false)) { 21 | for (debug in booleanArrayOf(true, false)) { 22 | val variant = (if (foss) "Foss" else "Pro") + (if (debug) "Debug" else "Release") 23 | 24 | val task = tasks.named("compile" + variant + "JavaWithJavac").get() 25 | task.dependsOn(":hidden_apis:sync" + variant + "LibJars") 26 | 27 | var hiddenAPIsJarFile = variant.replaceFirstChar { it.lowercaseChar() } 28 | hiddenAPIsJarFile += "/sync" + variant + "LibJars" + "/classes.jar" 29 | 30 | task.doFirst { 31 | this as JavaCompile 32 | // dependencies.compileOnly() appends the jar but we need to the 33 | // hidden APIs jar so that to override the Android SDK classes. 34 | val cp = project.objects.fileCollection() 35 | cp.from(File(dir, hiddenAPIsJarFile)) 36 | cp.from(classpath) 37 | classpath = cp 38 | } 39 | } 40 | } 41 | } 42 | 43 | afterEvaluate { createTasksForHiddenAPIs() } 44 | -------------------------------------------------------------------------------- /priv_library/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Required for de-Serialization, must not be obfuscated. 2 | -keepclassmembers class com.mirfatif.err.HiddenAPIsException { 3 | static final long serialVersionUID; 4 | } 5 | 6 | -dontwarn android.app.ActivityManagerNative 7 | -dontwarn android.app.AppOpsManager$OpEntry 8 | -dontwarn android.app.AppOpsManager$PackageOps 9 | -dontwarn android.app.IActivityManager 10 | -dontwarn android.app.IActivityManager$Stub 11 | -dontwarn android.app.IApplicationThread 12 | -dontwarn android.app.ProfilerInfo 13 | -dontwarn android.content.pm.IPackageManager 14 | -dontwarn android.content.pm.IPackageManager$Stub 15 | -dontwarn android.content.pm.ParceledListSlice 16 | -dontwarn android.os.IDeviceIdleController 17 | -dontwarn android.os.IDeviceIdleController$Stub 18 | -dontwarn android.os.ServiceManager 19 | -dontwarn android.permission.IPermissionManager 20 | -dontwarn android.permission.IPermissionManager$Stub 21 | -dontwarn com.android.internal.app.IAppOpsService 22 | -dontwarn com.android.internal.app.IAppOpsService$Stub 23 | -------------------------------------------------------------------------------- /priv_library/src/main/aidl/com/mirfatif/privtasks/bind/ILogCallback.aidl: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.bind; 2 | 3 | interface ILogCallback { 4 | 5 | boolean writeToLogFile(String line); 6 | } 7 | -------------------------------------------------------------------------------- /priv_library/src/main/aidl/com/mirfatif/privtasks/bind/IPrivTasksCallback.aidl: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.bind; 2 | 3 | import com.mirfatif.privtasks.bind.DaemonState; 4 | 5 | parcelable DaemonState; 6 | 7 | interface IPrivTasksCallback { 8 | 9 | void hello(in DaemonState daemonState); 10 | 11 | void showError(int privTasksError); 12 | 13 | void saveLog(String stackTrace); 14 | } 15 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/err/ContainerException.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.err; 2 | 3 | import android.os.RemoteException; 4 | import java.io.PrintStream; 5 | import java.io.PrintWriter; 6 | import java.io.StringWriter; 7 | 8 | public class ContainerException extends RemoteException { 9 | 10 | private final String stackTrace; 11 | 12 | public ContainerException(String stackTrace) { 13 | this.stackTrace = stackTrace; 14 | } 15 | 16 | public void printStackTrace(PrintStream s) { 17 | s.println(stackTrace); 18 | } 19 | 20 | public void printStackTrace(PrintWriter s) { 21 | s.println(stackTrace); 22 | } 23 | 24 | public static String toStackTrace(Throwable e) { 25 | StringWriter sw = new StringWriter(); 26 | try (PrintWriter pw = new PrintWriter(sw)) { 27 | e.printStackTrace(pw); 28 | } 29 | return sw.toString(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/err/HiddenAPIsException.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.err; 2 | 3 | import android.os.RemoteException; 4 | 5 | public class HiddenAPIsException extends RemoteException { 6 | 7 | private static final long serialVersionUID = 1234567890L; 8 | 9 | public HiddenAPIsException(Throwable cause) { 10 | this(cause.getMessage()); 11 | initCause(cause); 12 | } 13 | 14 | public HiddenAPIsException(String message) { 15 | super(message); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/Constants.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks; 2 | 3 | public class Constants { 4 | 5 | private Constants() {} 6 | 7 | public static final String EXTRA_CODE_WORD = "com.mirfatif.privlib.extra.A"; 8 | public static final String EXTRA_BINDER = "com.mirfatif.privlib.extra.B"; 9 | public static final String CMD_CODE_WORD = "com.mirfatif.privlib.cmd.B"; 10 | 11 | public static final String UNKNOWN_OP = "UNKNOWN"; 12 | 13 | public static final String PERM_GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS"; 14 | 15 | public static final String APP_OP_MODE_ALLOW = "Allow"; 16 | public static final String APP_OP_MODE_IGNORE = "Ignore"; 17 | public static final String APP_OP_MODE_DENY = "Deny"; 18 | public static final String APP_OP_MODE_DEFAULT = "Default"; 19 | public static final String APP_OP_MODE_FG = "Foreground"; 20 | } 21 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/HiddenSdkStringConstants.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks; 2 | 3 | import android.companion.virtual.VirtualDeviceManager; 4 | import com.mirfatif.err.HiddenAPIsException; 5 | 6 | public enum HiddenSdkStringConstants { 7 | PERSISTENT_DEVICE_ID_DEFAULT; 8 | 9 | private String value; 10 | 11 | public String get() throws HiddenAPIsException { 12 | return get(false); 13 | } 14 | 15 | public String get(boolean wrapHiddenSdkErrors) throws HiddenAPIsException { 16 | if (value != null) { 17 | return value; 18 | } 19 | 20 | try { 21 | if (this == HiddenSdkStringConstants.PERSISTENT_DEVICE_ID_DEFAULT) { 22 | value = getStaticStringField("PERSISTENT_DEVICE_ID_DEFAULT", VirtualDeviceManager.class); 23 | } 24 | } catch (NoSuchFieldError | NoSuchMethodError e) { 25 | if (wrapHiddenSdkErrors) { 26 | throw new HiddenAPIsException(e); 27 | } else { 28 | throw e; 29 | } 30 | } 31 | 32 | if (value == null) { 33 | throw new HiddenAPIsException("Bad get call"); 34 | } 35 | 36 | return value; 37 | } 38 | 39 | private static String getStaticStringField(String name, Class cls) throws HiddenAPIsException { 40 | try { 41 | return (String) cls.getDeclaredField(name).get(null); 42 | } catch (IllegalAccessException | NoSuchFieldException e) { 43 | throw new HiddenAPIsException(e); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/PrivTasksError.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.SOURCE) 7 | public @interface PrivTasksError { 8 | 9 | int OP_NUM_INCONSISTENCY = 0; 10 | 11 | int OP_MODE_INCONSISTENCY = 1; 12 | 13 | int APP_OPS_IMPL = 2; 14 | } 15 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/bind/MyPackageInfo.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.bind; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | public class MyPackageInfo implements Parcelable { 7 | 8 | public final String packageName; 9 | 10 | public final int[] requestedPermissionsFlags; 11 | 12 | public final int uid; 13 | 14 | public final boolean enabled; 15 | 16 | public MyPackageInfo(String pkgName, int[] reqPermsFlags, int uid, boolean enabled) { 17 | packageName = pkgName; 18 | requestedPermissionsFlags = reqPermsFlags; 19 | this.uid = uid; 20 | this.enabled = enabled; 21 | } 22 | 23 | protected MyPackageInfo(Parcel in) { 24 | packageName = in.readString(); 25 | requestedPermissionsFlags = in.createIntArray(); 26 | uid = in.readInt(); 27 | enabled = in.readByte() != 0; 28 | } 29 | 30 | public static final Creator CREATOR = 31 | new Creator<>() { 32 | public MyPackageInfo createFromParcel(Parcel in) { 33 | return new MyPackageInfo(in); 34 | } 35 | 36 | public MyPackageInfo[] newArray(int size) { 37 | return new MyPackageInfo[size]; 38 | } 39 | }; 40 | 41 | public int describeContents() { 42 | return 0; 43 | } 44 | 45 | public void writeToParcel(Parcel dest, int flags) { 46 | dest.writeString(packageName); 47 | dest.writeIntArray(requestedPermissionsFlags); 48 | dest.writeInt(uid); 49 | dest.writeByte((byte) (enabled ? 1 : 0)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/bind/PermFixedFlags.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.bind; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | public class PermFixedFlags implements Parcelable { 7 | 8 | public final int systemFixed; 9 | 10 | public final int policyFixed; 11 | 12 | public PermFixedFlags(int systemFixed, int policyFixed) { 13 | this.systemFixed = systemFixed; 14 | this.policyFixed = policyFixed; 15 | } 16 | 17 | protected PermFixedFlags(Parcel in) { 18 | systemFixed = in.readInt(); 19 | policyFixed = in.readInt(); 20 | } 21 | 22 | public static final Creator CREATOR = 23 | new Creator<>() { 24 | public PermFixedFlags createFromParcel(Parcel in) { 25 | return new PermFixedFlags(in); 26 | } 27 | 28 | public PermFixedFlags[] newArray(int size) { 29 | return new PermFixedFlags[size]; 30 | } 31 | }; 32 | 33 | public int describeContents() { 34 | return 0; 35 | } 36 | 37 | public void writeToParcel(Parcel dest, int flags) { 38 | dest.writeInt(systemFixed); 39 | dest.writeInt(policyFixed); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/bind/StrIntMap.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.bind; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | import android.util.ArrayMap; 6 | 7 | public class StrIntMap implements Parcelable { 8 | 9 | public final ArrayMap map = new ArrayMap<>(); 10 | 11 | public StrIntMap() {} 12 | 13 | protected StrIntMap(Parcel in) { 14 | int size = in.readInt(); 15 | for (int i = 0; i < size; i++) { 16 | map.put(in.readString(), in.readInt()); 17 | } 18 | } 19 | 20 | public void writeToParcel(Parcel dest, int flags) { 21 | int size = map.size(); 22 | dest.writeInt(size); 23 | for (int i = 0; i < size; i++) { 24 | dest.writeString(map.keyAt(i)); 25 | dest.writeInt(map.valueAt(i)); 26 | } 27 | } 28 | 29 | public int describeContents() { 30 | return 0; 31 | } 32 | 33 | public static final Creator CREATOR = 34 | new Creator<>() { 35 | public StrIntMap createFromParcel(Parcel in) { 36 | return new StrIntMap(in); 37 | } 38 | 39 | public StrIntMap[] newArray(int size) { 40 | return new StrIntMap[size]; 41 | } 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/CloseableReadWriteLock.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util; 2 | 3 | import com.mirfatif.privtasks.util.bg.RunnableWithResult; 4 | import java.util.concurrent.locks.ReentrantReadWriteLock; 5 | 6 | public class CloseableReadWriteLock extends ReentrantReadWriteLock { 7 | 8 | public void withReadLock(Runnable task) { 9 | super.readLock().lock(); 10 | try { 11 | task.run(); 12 | } finally { 13 | super.readLock().unlock(); 14 | } 15 | } 16 | 17 | public void withWriteLock(Runnable task) { 18 | super.writeLock().lock(); 19 | try { 20 | task.run(); 21 | } finally { 22 | super.writeLock().unlock(); 23 | } 24 | } 25 | 26 | public T withReadLock(RunnableWithResult task) { 27 | super.readLock().lock(); 28 | try { 29 | return task.run(); 30 | } finally { 31 | super.readLock().unlock(); 32 | } 33 | } 34 | 35 | public T withWriteLock(RunnableWithResult task) { 36 | super.writeLock().lock(); 37 | try { 38 | return task.run(); 39 | } finally { 40 | super.writeLock().unlock(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/MyLog.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util; 2 | 3 | import android.util.Log; 4 | 5 | public class MyLog { 6 | 7 | private MyLog() {} 8 | 9 | private static String makeMsg(String method, String msg) { 10 | return (method == null ? "" : method + "(): ") + msg; 11 | } 12 | 13 | public static void e(String tag, String method, Throwable e) { 14 | e(tag, method, e.toString(), e); 15 | } 16 | 17 | public static void e(String tag, String method, String msg, Throwable e) { 18 | Log.e(tag, makeMsg(method, msg), e); 19 | e.printStackTrace(System.err); 20 | } 21 | 22 | public static void e(String tag, String method, String err) { 23 | err = makeMsg(method, err); 24 | Log.e(tag, err); 25 | System.err.println(tag + ": " + err); 26 | } 27 | 28 | public static void w(String tag, String method, String msg) { 29 | Log.w(tag, makeMsg(method, msg)); 30 | } 31 | 32 | public static void i(String tag, String method, String msg) { 33 | Log.i(tag, makeMsg(method, msg)); 34 | } 35 | 36 | public static void d(String tag, String method, String msg) { 37 | Log.d(tag, makeMsg(method, msg)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/bg/BgRunner.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util.bg; 2 | 3 | import java.util.concurrent.Callable; 4 | import java.util.concurrent.ExecutorService; 5 | import java.util.concurrent.Executors; 6 | import java.util.concurrent.Future; 7 | 8 | public class BgRunner { 9 | 10 | private static final ExecutorService BG_EXECUTOR = 11 | Executors.newCachedThreadPool(ThreadUtils::createDaemonThread); 12 | 13 | public static void execute(Runnable task) { 14 | BG_EXECUTOR.execute(task); 15 | } 16 | 17 | public static Future submit(Callable task) { 18 | return BG_EXECUTOR.submit(task); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/bg/MinDelayTaskExecutor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util.bg; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public class MinDelayTaskExecutor { 6 | 7 | private final RateLimiter mRateLimiter; 8 | private final SingleSchedTaskExecutor mE; 9 | 10 | public MinDelayTaskExecutor(Runnable task, long delay, TimeUnit unit, String threadName) { 11 | mRateLimiter = new RateLimiter(delay, unit); 12 | mE = new SingleSchedTaskExecutor(() -> run(task), threadName); 13 | } 14 | 15 | public void runOrSchedule() { 16 | runOrSchedule(false); 17 | } 18 | 19 | public void runOrSchedule(boolean cancel) { 20 | synchronized (this) { 21 | if (!mE.isAlive() || (!cancel && mE.hasRunningOrPendingTasks())) { 22 | return; 23 | } 24 | 25 | if (cancel) { 26 | mE.cancel(true); 27 | } 28 | 29 | runNow(mRateLimiter.getRemainingMillis()); 30 | } 31 | } 32 | 33 | public void cancelAndRunNow() { 34 | synchronized (this) { 35 | if (mE.isAlive()) { 36 | mE.cancel(true); 37 | runNow(0); 38 | } 39 | } 40 | } 41 | 42 | private void runNow(long delay) { 43 | mE.scheduleIfIdle(delay > 0 ? delay : 0, TimeUnit.MILLISECONDS); 44 | } 45 | 46 | public void shutdownNow() { 47 | mE.shutdownNow(); 48 | } 49 | 50 | public boolean isAlive() { 51 | return mE.isAlive(); 52 | } 53 | 54 | private void run(Runnable task) { 55 | task.run(); 56 | mRateLimiter.setTs(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/bg/RateLimitedTask.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util.bg; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public class RateLimitedTask { 6 | 7 | private final RateLimiter mRateLimiter; 8 | private final Runnable mTask; 9 | 10 | public RateLimitedTask(long minDelay, TimeUnit unit, Runnable task) { 11 | mRateLimiter = new RateLimiter(minDelay, unit); 12 | mTask = () -> RateLimitedTask.this.run(task); 13 | } 14 | 15 | public void run() { 16 | run(false); 17 | } 18 | 19 | public void run(boolean force) { 20 | run(force, false); 21 | } 22 | 23 | private boolean mRunning = false; 24 | 25 | public synchronized void run(boolean force, boolean inBg) { 26 | if (force || mRateLimiter.can() && !mRunning) { 27 | mRunning = true; 28 | 29 | if (inBg) { 30 | BgRunner.execute(mTask); 31 | } else { 32 | mTask.run(); 33 | } 34 | } 35 | } 36 | 37 | private void run(Runnable task) { 38 | task.run(); 39 | mRateLimiter.setTs(); 40 | mRunning = false; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/bg/RateLimitedTaskTyped.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util.bg; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public class RateLimitedTaskTyped { 6 | 7 | private final RateLimiter mRateLimiter; 8 | private final RunnableWithParam mTask; 9 | 10 | public RateLimitedTaskTyped(long minDelay, TimeUnit unit, RunnableWithParam task) { 11 | mRateLimiter = new RateLimiter(minDelay, unit); 12 | mTask = task; 13 | } 14 | 15 | public void run(T param) { 16 | run(param, false); 17 | } 18 | 19 | public synchronized void run(T param, boolean force) { 20 | if (force || mRateLimiter.can()) { 21 | mTask.run(param); 22 | mRateLimiter.setTs(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/bg/RateLimiter.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util.bg; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public class RateLimiter { 6 | 7 | private final long mMinDelay; 8 | private long mTs; 9 | 10 | public RateLimiter(long minDelay, TimeUnit unit) { 11 | mMinDelay = unit.toMillis(minDelay); 12 | } 13 | 14 | public long getRemainingMillis() { 15 | return mTs + mMinDelay - System.currentTimeMillis(); 16 | } 17 | 18 | public boolean can() { 19 | return can(false); 20 | } 21 | 22 | public boolean can(boolean setTs) { 23 | if (getRemainingMillis() <= 0) { 24 | if (setTs) { 25 | setTs(); 26 | } 27 | return true; 28 | } 29 | return false; 30 | } 31 | 32 | public void setTs() { 33 | mTs = System.currentTimeMillis(); 34 | } 35 | 36 | public void waitUntilCanNoThrow(boolean setTs) { 37 | try { 38 | waitUntilCan(setTs); 39 | } catch (InterruptedException ignored) { 40 | } 41 | } 42 | 43 | public void waitUntilCan() throws InterruptedException { 44 | waitUntilCan(false); 45 | } 46 | 47 | public void waitUntilCan(boolean setTs) throws InterruptedException { 48 | long sleep = getRemainingMillis(); 49 | if (sleep > 0) { 50 | Thread.sleep(sleep); 51 | } 52 | if (setTs) { 53 | setTs(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/bg/RunnableWithParam.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util.bg; 2 | 3 | public interface RunnableWithParam { 4 | 5 | void run(T param); 6 | } 7 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/bg/RunnableWithResult.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util.bg; 2 | 3 | public interface RunnableWithResult { 4 | 5 | T run(); 6 | } 7 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/bg/SingleParamTask.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util.bg; 2 | 3 | import java.util.concurrent.ConcurrentLinkedQueue; 4 | 5 | public class SingleParamTask { 6 | 7 | private final ConcurrentLinkedQueue mParam = new ConcurrentLinkedQueue<>(); 8 | private final RunnableWithParam mTask; 9 | private final SingleTaskExecutor mE; 10 | 11 | public SingleParamTask(RunnableWithParam task, String threadName) { 12 | mTask = task; 13 | mE = new SingleTaskExecutor(this::runPendingParams, threadName); 14 | } 15 | 16 | private void runPendingParams() { 17 | T param; 18 | while ((param = mParam.poll()) != null) { 19 | mTask.run(param); 20 | } 21 | } 22 | 23 | private void enqueueParam(T param) { 24 | mParam.add(param); 25 | if (!hasRunningOrPendingTasks()) { 26 | mE.submit(); 27 | } 28 | } 29 | 30 | public synchronized void submit(T param) { 31 | if (mE.isAlive()) { 32 | enqueueParam(param); 33 | } 34 | } 35 | 36 | public synchronized void submitIfIdle(T param) { 37 | if (mE.isAlive() && !hasRunningOrPendingTasks() && mParam.isEmpty()) { 38 | enqueueParam(param); 39 | } 40 | } 41 | 42 | public synchronized void cancelAndSubmit(T param, boolean interrupt) { 43 | if (mE.isAlive()) { 44 | cancel(interrupt); 45 | enqueueParam(param); 46 | } 47 | } 48 | 49 | public void cancel(boolean interrupt) { 50 | mParam.clear(); 51 | mE.cancel(interrupt); 52 | } 53 | 54 | public synchronized void shutdownNow() { 55 | mE.shutdownNow(); 56 | } 57 | 58 | public boolean hasRunningOrPendingTasks() { 59 | return mE.hasRunningOrPendingTasks(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/bg/SingleTaskExecutor.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util.bg; 2 | 3 | import java.util.Queue; 4 | import java.util.concurrent.ConcurrentLinkedQueue; 5 | 6 | public class SingleTaskExecutor extends SingleTaskExecutorAbstract { 7 | 8 | protected final ConcurrentLinkedQueue mQ = new ConcurrentLinkedQueue<>(); 9 | 10 | private final Runnable mTask; 11 | 12 | public SingleTaskExecutor(Runnable task, String threadName) { 13 | this(task, threadName, -1); 14 | } 15 | 16 | public SingleTaskExecutor(Runnable task, String threadName, int threadPriority) { 17 | super(threadName, threadPriority); 18 | mTask = task; 19 | start(); 20 | } 21 | 22 | protected Runnable poll() { 23 | return mQ.poll(); 24 | } 25 | 26 | protected long getTimeoutMillis() { 27 | return 0; 28 | } 29 | 30 | protected Queue getQueue() { 31 | return mQ; 32 | } 33 | 34 | public void submit() { 35 | synchronized (mAlive) { 36 | if (mAlive.get()) { 37 | addTask(mTask, mQ); 38 | } 39 | } 40 | } 41 | 42 | public void submitIfNotPending() { 43 | synchronized (mAlive) { 44 | if (mAlive.get() && !hasPendingTasks()) { 45 | addTask(mTask, mQ); 46 | } 47 | } 48 | } 49 | 50 | public void cancelAndSubmit(boolean interrupt) { 51 | synchronized (mAlive) { 52 | if (mAlive.get()) { 53 | cancelAndAddTask(interrupt, mTask, mQ); 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/bg/SingleTaskExecutorTyped.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util.bg; 2 | 3 | public class SingleTaskExecutorTyped extends SingleTaskExecutor { 4 | 5 | private final RunnableWithResult mTask; 6 | private final Runnable mTaskWrapper; 7 | private final T mDefValue; 8 | 9 | public SingleTaskExecutorTyped( 10 | RunnableWithResult typedTask, T def, String threadName, int threadPriority) { 11 | super(typedTask::run, threadName, threadPriority); 12 | mTask = typedTask; 13 | mTaskWrapper = SingleTaskExecutorTyped.this::runTask; 14 | mDefValue = def; 15 | } 16 | 17 | public T cancelSubmitGet(boolean interrupt) { 18 | synchronized (mAlive) { 19 | if (mAlive.get()) { 20 | cancelAndAddTask(interrupt, mTaskWrapper, mQ); 21 | } else { 22 | return mDefValue; 23 | } 24 | 25 | return getResult(); 26 | } 27 | } 28 | 29 | private final NotifyWaiter mDone = new NotifyWaiter(); 30 | private volatile T mResult; 31 | 32 | private void runTask() { 33 | T res = mDefValue; 34 | try { 35 | res = mTask.run(); 36 | } finally { 37 | mResult = res; 38 | mDone.notify(false); 39 | } 40 | } 41 | 42 | private T getResult() { 43 | try { 44 | mDone.waitForNotify(); 45 | return mResult; 46 | } catch (InterruptedException e) { 47 | return mDefValue; 48 | } finally { 49 | mResult = null; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /priv_library/src/main/java/com/mirfatif/privtasks/util/bg/ThreadUtils.java: -------------------------------------------------------------------------------- 1 | package com.mirfatif.privtasks.util.bg; 2 | 3 | import android.os.Looper; 4 | import java.util.concurrent.Executors; 5 | 6 | public class ThreadUtils { 7 | 8 | private ThreadUtils() {} 9 | 10 | public static boolean isMainThread() { 11 | Looper looper = Looper.getMainLooper(); 12 | if (looper == null) { 13 | return false; 14 | } 15 | return Thread.currentThread() == looper.getThread(); 16 | } 17 | 18 | public static void assertNotMainThread() { 19 | if (isMainThread()) { 20 | throw new RuntimeException("Must not be called on main thread"); 21 | } 22 | } 23 | 24 | public static Thread createDaemonThread(Runnable r) { 25 | Thread thread = Executors.defaultThreadFactory().newThread(r); 26 | thread.setDaemon(true); 27 | return thread; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("UnstableApiUsage") 2 | dependencyResolutionManagement { 3 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 4 | 5 | repositories { 6 | mavenLocal() 7 | mavenCentral() 8 | google() 9 | gradlePluginPortal() 10 | maven { url = uri("https://jitpack.io") } // For libadb-android 11 | } 12 | } 13 | 14 | if (File(rootDir, "configs/settings-pro.gradle.kts").isFile) { 15 | apply(from = "configs/settings-pro.gradle.kts") 16 | } 17 | 18 | include(":hidden_apis") 19 | 20 | include(":priv_library") 21 | 22 | include(":priv_daemon") 23 | 24 | include(":app") 25 | --------------------------------------------------------------------------------