From c36e60f4e7517f6bfa3678f45b52b2b1d75d4981 Mon Sep 17 00:00:00 2001 From: Irfan Latif Date: Sun, 30 Jul 2023 15:48:04 +0500 Subject: [PATCH] v1.21 --- app/build.gradle | 40 ++++++++++--------- .../backup/BackupRestore.java | 6 ++- .../parser/PackageParser.java | 18 ++++----- .../prefs/ExcFiltersData.java | 24 +++++------ .../privs/DaemonHandler.java | 4 +- .../permissionmanagerx/util/ApiUtils.java | 2 +- .../permissionmanagerx/util/AppLifecycle.java | 4 +- build.gradle | 2 +- .../metadata/android/en-US/changelogs/121.txt | 8 ++++ .../com/mirfatif/err/ContainerException.java | 31 ++++++++++++++ .../mirfatif/privtasks/iface/IPrivTasks.java | 22 +++------- 11 files changed, 98 insertions(+), 63 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/121.txt create mode 100644 priv_library/src/main/java/com/mirfatif/err/ContainerException.java diff --git a/app/build.gradle b/app/build.gradle index 5f013b98..c814955d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { defaultConfig { applicationId APP_ID - versionCode 120 - versionName 'v1.20' + versionCode 121 + versionName 'v1.21' // Flavor-independent and BuildType-independent BuildConfig.APPLICATION_ID buildConfigField 'String', 'APP_ID', '"' + APP_ID + '"' @@ -64,7 +64,7 @@ android { } } - applicationVariants.all { variant -> + applicationVariants.configureEach { variant -> def mf = variant.mergedFlavor if (variant.flavorName == 'psPro' && variant.buildType.name == 'release') { // No .ps.pro suffix for Play Store Pro release @@ -80,7 +80,7 @@ android { // println() } - sourceSets.all { sc -> + sourceSets.configureEach { sc -> // These combinations are not created by default (required for daemon dex). def dir if (sc.name.matches('(self|ps)ProDebug')) { @@ -112,7 +112,7 @@ android { } configurations { - all { + configureEach { // To avoid duplicate class version conflict. exclude group: 'androidx.lifecycle', module: 'lifecycle-viewmodel-ktx' } @@ -128,15 +128,15 @@ dependencies { implementation 'org.lsposed.hiddenapibypass:hiddenapibypass:4.3' implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'androidx.recyclerview:recyclerview:1.3.0' + implementation 'androidx.recyclerview:recyclerview:1.3.1' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01' - implementation 'androidx.preference:preference:1.2.0' + implementation 'androidx.preference:preference:1.2.1' implementation 'androidx.browser:browser:1.5.0' - implementation 'androidx.room:room-runtime:2.5.1' + implementation 'androidx.room:room-runtime:2.5.2' implementation 'androidx.security:security-crypto:1.1.0-alpha06' implementation 'androidx.webkit:webkit:1.7.0' - annotationProcessor 'androidx.room:room-compiler:2.5.1' + annotationProcessor 'androidx.room:room-compiler:2.5.2' // For SnackBar and NavigationView. Also includes CoordinatorLayout implementation 'com.google.android.material:material:1.9.0' @@ -206,7 +206,7 @@ def createTasksForDaemonBuild = () -> { File srcFile = new File(rootDir, src) File dstFile = new File(rootDir, 'app/src/' + dir + '/assets/' + daemonDex) - tasks.create('buildDaemon' + task) { + tasks.register('buildDaemon' + task) { dependsOn(':priv_daemon:' + dexTaskDep) if (foss) { @@ -222,7 +222,7 @@ def createTasksForDaemonBuild = () -> { } } -task buildNativeFoss(type: Exec) { +tasks.register('buildNativeFoss', Exec) { environment 'ANDROID_NDK', ndkDir workingDir nativeDir commandLine './build_native.sh' @@ -238,16 +238,20 @@ def setExtSrcDependencies(String type, String version) { for (boolean debug : new boolean[]{true, false}) { String build = debug ? 'Debug' : 'Release' - Task task = tasks.findByName('merge' + type + version + build + 'Assets') + TaskProvider task = tasks.named('merge' + type + version + build + 'Assets') - task.dependsOn('buildDaemon' + version + build) + task.configure { + dependsOn('buildDaemon' + version + build) + } - task = tasks.findByName('merge' + type + version + build + 'JniLibFolders') + task = tasks.named('merge' + type + version + build + 'JniLibFolders') - if (version == 'Foss') { - task.dependsOn('buildNativeFoss') - } else { - task.dependsOn('buildNative' + type + version + build) + task.configure { + if (version == 'Foss') { + dependsOn('buildNativeFoss') + } else { + dependsOn('buildNative' + type + version + build) + } } } } diff --git a/app/src/main/java/com/mirfatif/permissionmanagerx/backup/BackupRestore.java b/app/src/main/java/com/mirfatif/permissionmanagerx/backup/BackupRestore.java index ac23aef8..a430691e 100644 --- a/app/src/main/java/com/mirfatif/permissionmanagerx/backup/BackupRestore.java +++ b/app/src/main/java/com/mirfatif/permissionmanagerx/backup/BackupRestore.java @@ -276,6 +276,10 @@ public Result restore(Uri file, boolean skipUninstalledApps, SwapUserIds swapUse Result res; try (InputStream is = App.getCxt().getContentResolver().openInputStream(file)) { + if (is == null) { + MyLog.e(TAG, "restore", "Failed to get InputStream"); + return null; + } res = restore(is, skipUninstalledApps, swapUserIds); } catch (IOException | SecurityException e) { @@ -284,7 +288,7 @@ public Result restore(Uri file, boolean skipUninstalledApps, SwapUserIds swapUse } if (res != null) { - ExcFiltersData.INS.populateLists(); + ExcFiltersData.INS.populateLists(true); PermsDb.INS.buildRefs(); BackupRestoreFlavor.onRestoreDone(); } diff --git a/app/src/main/java/com/mirfatif/permissionmanagerx/parser/PackageParser.java b/app/src/main/java/com/mirfatif/permissionmanagerx/parser/PackageParser.java index bf7f7e85..5e9b23d0 100644 --- a/app/src/main/java/com/mirfatif/permissionmanagerx/parser/PackageParser.java +++ b/app/src/main/java/com/mirfatif/permissionmanagerx/parser/PackageParser.java @@ -35,12 +35,10 @@ import com.mirfatif.privtasks.bind.PermFixedFlags; import com.mirfatif.privtasks.util.MyLog; import com.mirfatif.privtasks.util.Util; -import com.mirfatif.privtasks.util.bg.BgRunner; import com.mirfatif.privtasks.util.bg.RateLimitedTaskTyped; import com.mirfatif.privtasks.util.bg.SingleParamTask; import com.mirfatif.privtasks.util.bg.SingleSchedTaskExecutor; import com.mirfatif.privtasks.util.bg.SingleTaskExecutorTyped; -import com.mirfatif.privtasks.util.bg.ThreadUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -122,6 +120,11 @@ private List updatePkgListInternal() { setProgress(i, false, false); PackageInfo pkgInfo = pkgInfoList.get(i); + if (pkgInfo == null) { + + continue; + } + Package pkg = new Package(); if (isPkgUpdated(pkgInfo, pkg, true)) { pkgList.add(pkg); @@ -193,11 +196,6 @@ private List buildPkgInfoList() { } public void clearPkgInfoList() { - if (ThreadUtils.isMainThread()) { - BgRunner.execute(this::clearPkgInfoList); - return; - } - synchronized (mPkgInfoList) { mPkgInfoList.clear(); } @@ -410,12 +408,12 @@ public int getProgMsg(int progMax) { } boolean isPkgUpdated(PackageInfo pkgInfo, Package pkg, boolean filterPerms) { - Boolean out = PkgParserFlavor.INS.isFilteredOut(pkgInfo, pkg); - if (Boolean.TRUE.equals(out)) { + Boolean filteredOut = PkgParserFlavor.INS.isFilteredOut(pkgInfo, pkg); + if (Boolean.TRUE.equals(filteredOut)) { return false; } - boolean filterPkg = out == null; + boolean filterPkg = filteredOut == null; if (filterPkg && isFilteredOutPkgName(pkgInfo.packageName)) { return false; diff --git a/app/src/main/java/com/mirfatif/permissionmanagerx/prefs/ExcFiltersData.java b/app/src/main/java/com/mirfatif/permissionmanagerx/prefs/ExcFiltersData.java index 96e19ab1..503a49c9 100644 --- a/app/src/main/java/com/mirfatif/permissionmanagerx/prefs/ExcFiltersData.java +++ b/app/src/main/java/com/mirfatif/permissionmanagerx/prefs/ExcFiltersData.java @@ -64,9 +64,9 @@ public boolean canBeExcluded(Package pkg) { private final Object EXCLUDED_APPS_LOCK = new Object(); - private void populateExcludedAppsList(boolean update, boolean loadDefaults) { + private void populateExcludedAppsList(boolean force, boolean loadDefaults) { synchronized (EXCLUDED_APPS_LOCK) { - if (!update && mExcludedAppsLabels != null) { + if (!force && mExcludedAppsLabels != null) { return; } @@ -158,9 +158,9 @@ public boolean canBeExcluded(Permission perm) { private final Object EXCLUDED_PERMS_LOCK = new Object(); - private void populateExcludedPermsList(boolean update) { + private void populateExcludedPermsList(boolean force) { synchronized (EXCLUDED_PERMS_LOCK) { - if (!update && mExcludedPerms != null) { + if (!force && mExcludedPerms != null) { return; } @@ -194,9 +194,9 @@ public boolean isExtraAppOp(String opName) { private final Object EXTRA_APP_OPS_LOCK = new Object(); - public void populateExtraAppOpsList(boolean update, boolean loadDefaults) { + public void populateExtraAppOpsList(boolean force, boolean loadDefaults) { synchronized (EXTRA_APP_OPS_LOCK) { - if (!update && mExtraAppOps != null) { + if (!force && mExtraAppOps != null) { return; } @@ -240,10 +240,10 @@ public void updateList(String key) { } } - public void populateLists() { - BgRunner.execute(() -> populateExcludedAppsList(false, false)); - BgRunner.execute(() -> populateExcludedPermsList(false)); - BgRunner.execute(() -> populateExtraAppOpsList(false, false)); + public void populateLists(boolean force) { + BgRunner.execute(() -> populateExcludedAppsList(force, false)); + BgRunner.execute(() -> populateExcludedPermsList(force)); + BgRunner.execute(() -> populateExtraAppOpsList(force, false)); } public void resetExcFilters() { @@ -274,7 +274,7 @@ public void resetExcFilters() { prefEditor.apply(); MyLog.i(TAG, "resetExcFilters", count + " preferences removed"); - BgRunner.execute(() -> populateExcludedAppsList(true, true)); - BgRunner.execute(() -> populateExtraAppOpsList(true, true)); + populateExcludedAppsList(true, true); + populateExtraAppOpsList(true, true); } } diff --git a/app/src/main/java/com/mirfatif/permissionmanagerx/privs/DaemonHandler.java b/app/src/main/java/com/mirfatif/permissionmanagerx/privs/DaemonHandler.java index e16e60e3..d7ef01bf 100644 --- a/app/src/main/java/com/mirfatif/permissionmanagerx/privs/DaemonHandler.java +++ b/app/src/main/java/com/mirfatif/permissionmanagerx/privs/DaemonHandler.java @@ -39,6 +39,7 @@ import java.net.Inet4Address; import java.net.Socket; import java.util.NoSuchElementException; +import java.util.Objects; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -382,7 +383,8 @@ public void showError(int error) { static { VM_NAME = APPLICATION_ID.replace(APP_ID, DAEMON_PACKAGE_NAME + ".pmx"); String dex = VM_NAME + ".dex"; - String sharedDir = App.getCxt().getExternalFilesDir(null).getAbsolutePath(); + String sharedDir = + Objects.requireNonNull(App.getCxt().getExternalFilesDir(null)).getAbsolutePath(); SHARED_DIR_DEX_PATH = new File(sharedDir, dex).getAbsolutePath(); TMP_DIR_DEX_PATH = new File(TMP_DIR, dex).getAbsolutePath(); } diff --git a/app/src/main/java/com/mirfatif/permissionmanagerx/util/ApiUtils.java b/app/src/main/java/com/mirfatif/permissionmanagerx/util/ApiUtils.java index c889e62f..42d9b75d 100644 --- a/app/src/main/java/com/mirfatif/permissionmanagerx/util/ApiUtils.java +++ b/app/src/main/java/com/mirfatif/permissionmanagerx/util/ApiUtils.java @@ -161,7 +161,7 @@ public static void setTargetFragment(Fragment source, Fragment target) { public static ArrayList getParcelableArrayListExtra( Intent intent, String name, Class cls) { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { try { return intent.getParcelableArrayListExtra(name, cls); } catch (NullPointerException e) { diff --git a/app/src/main/java/com/mirfatif/permissionmanagerx/util/AppLifecycle.java b/app/src/main/java/com/mirfatif/permissionmanagerx/util/AppLifecycle.java index 11256f3d..5c7fd6c6 100644 --- a/app/src/main/java/com/mirfatif/permissionmanagerx/util/AppLifecycle.java +++ b/app/src/main/java/com/mirfatif/permissionmanagerx/util/AppLifecycle.java @@ -47,13 +47,13 @@ public void onActivityResumed(Activity activity) {} public void onActivityPaused(Activity activity) {} public void onActivityStopped(Activity activity) { - mVisibleRemover.schedule(2, TimeUnit.SECONDS); + mVisibleRemover.schedule(1, TimeUnit.SECONDS); } public void onActivitySaveInstanceState(Activity activity, Bundle outState) {} public void onActivityDestroyed(Activity activity) { - mLiveRemover.schedule(2, TimeUnit.SECONDS); + mLiveRemover.schedule(1, TimeUnit.SECONDS); } } } diff --git a/build.gradle b/build.gradle index c48a6270..2a48d6b4 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ plugins { } allprojects { - tasks.withType(JavaCompile) { + tasks.withType(JavaCompile).configureEach { options.compilerArgs << '-Xlint:all,-processing' } diff --git a/fastlane/metadata/android/en-US/changelogs/121.txt b/fastlane/metadata/android/en-US/changelogs/121.txt new file mode 100644 index 00000000..2d89086e --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/121.txt @@ -0,0 +1,8 @@ +- Fix Excluded Apps and AppOps not Restored from backup +- Add 'All users' options in Main Activity menu +- Add option to notify only red states in Scheduled Checks +- Remove watcher notifications if an app is uninstalled +- Increase permission switch padding +- Fixed crashes +- Minor improvements +- Bump libraries diff --git a/priv_library/src/main/java/com/mirfatif/err/ContainerException.java b/priv_library/src/main/java/com/mirfatif/err/ContainerException.java new file mode 100644 index 00000000..e062f44c --- /dev/null +++ b/priv_library/src/main/java/com/mirfatif/err/ContainerException.java @@ -0,0 +1,31 @@ +package com.mirfatif.err; + +import android.os.RemoteException; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; + +public class ContainerException extends RemoteException { + + private final String stackTrace; + + public ContainerException(String stackTrace) { + this.stackTrace = stackTrace; + } + + public void printStackTrace(PrintStream s) { + s.println(stackTrace); + } + + public void printStackTrace(PrintWriter s) { + s.println(stackTrace); + } + + public static String toStackTrace(Throwable e) { + StringWriter sw = new StringWriter(); + try (PrintWriter pw = new PrintWriter(sw)) { + e.printStackTrace(pw); + } + return sw.toString(); + } +} diff --git a/priv_library/src/main/java/com/mirfatif/privtasks/iface/IPrivTasks.java b/priv_library/src/main/java/com/mirfatif/privtasks/iface/IPrivTasks.java index a4dca733..12c143f2 100644 --- a/priv_library/src/main/java/com/mirfatif/privtasks/iface/IPrivTasks.java +++ b/priv_library/src/main/java/com/mirfatif/privtasks/iface/IPrivTasks.java @@ -5,7 +5,7 @@ import android.os.IInterface; import android.os.Parcel; import android.os.RemoteException; -import com.mirfatif.err.HiddenAPIsException; +import com.mirfatif.err.ContainerException; import com.mirfatif.privtasks.bind.AppOpsLists; import com.mirfatif.privtasks.bind.MyPackageOps; import com.mirfatif.privtasks.bind.PermFixedFlags; @@ -668,29 +668,17 @@ private static void initReply(Parcel data, Parcel reply) { private static final int ERROR = 1; private static void writeException(Parcel reply, Throwable t) { + reply.setDataSize(0); reply.setDataPosition(0); reply.writeInt(ERROR); - reply.writeSerializable(t); + reply.writeString(ContainerException.toStackTrace(t)); } public static void readException(Parcel reply) throws RemoteException { - if (reply.readInt() != ERROR) { - return; - } - - Throwable t = (Throwable) reply.readSerializable(); - - if (t instanceof HiddenAPIsException) { - throw (HiddenAPIsException) t; - } else if (t instanceof RemoteException) { - throw (RemoteException) t; - } else { - - RemoteException re = new RemoteException(); - re.initCause(t); - throw re; + if (reply.readInt() == ERROR) { + throw new ContainerException(reply.readString()); } }