diff options
Diffstat (limited to 'app/src/main/java/moe/yuuta/workmode/utils/Utils.kt')
-rw-r--r-- | app/src/main/java/moe/yuuta/workmode/utils/Utils.kt | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/app/src/main/java/moe/yuuta/workmode/utils/Utils.kt b/app/src/main/java/moe/yuuta/workmode/utils/Utils.kt index 2ac68e9..75a98e9 100644 --- a/app/src/main/java/moe/yuuta/workmode/utils/Utils.kt +++ b/app/src/main/java/moe/yuuta/workmode/utils/Utils.kt @@ -1,8 +1,12 @@ package moe.yuuta.workmode.utils +import android.annotation.SystemApi import android.content.Context import android.content.Intent import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager +import android.content.pm.PackageManager.GET_DISABLED_COMPONENTS +import android.content.pm.ResolveInfo import android.os.Bundle import android.os.Process import android.view.ViewGroup @@ -10,6 +14,8 @@ import android.widget.LinearLayout import androidx.core.view.children import com.google.android.material.tabs.TabLayout import moe.yuuta.workmode.BuildConfig +import moe.yuuta.workmode.suspend.data.PersistableSuspendedApp +import moe.yuuta.workmode.suspend.data.TransferableSuspendedApp import java.util.function.Predicate import java.util.stream.Collectors @@ -90,6 +96,76 @@ object Utils { } } + fun buildGeneralSuspendedAppInfoFilter(context: Context): Predicate<TransferableSuspendedApp> { + val i = Intent(Intent.ACTION_MAIN) + i.addCategory(Intent.CATEGORY_HOME) + val launchers = context.packageManager.queryIntentActivitiesAsUser(i, 0, context.userId) + .stream() + .map { + return@map it.resolvePackageName + } + .collect(Collectors.toList()) + return object : Predicate<TransferableSuspendedApp> { + override fun test(it: TransferableSuspendedApp): Boolean { + for (pkg in WHITELIST_PKGS) + if (pkg == it.packageName) { + return true + } + for (pkg in PROTECTED_PACKAGES) + if (pkg == it.packageName) { + return false + } + for (pkg in PROTECTED_PACKAGES_WIDE_MATCH) + if (it.packageName.startsWith(pkg)) { + return false + } + val itUid = context.packageManager.getPackageUidAsUser(it.packageName, + GET_DISABLED_COMPONENTS, + it.userId) + for (uid in PROTECTED_UIDS) + if (uid == itUid) { + return false + } + if (launchers.contains(it.packageName)) { + return false + } + if (itUid < Process.FIRST_APPLICATION_UID) { + return false + } + return getLaunchIntentForPackageAsUser(it.packageName, context.packageManager, it.userId) != null + } + } + } + + fun getLaunchIntentForPackageAsUser(packageName: String, pm: PackageManager, userId: Int): Intent? { + // First see if the package has an INFO activity; the existence of + // such an activity is implied to be the desired front-door for the + // overall package (such as if it has multiple launcher entries). + val intentToResolve = Intent(Intent.ACTION_MAIN) + intentToResolve.addCategory(Intent.CATEGORY_INFO) + intentToResolve.setPackage(packageName) + var ris: List<ResolveInfo>? = pm.queryIntentActivitiesAsUser(intentToResolve, 0, userId) + + // Otherwise, try to find a main launcher activity. + if (ris == null || ris.size <= 0) { + // reuse the intent instance + intentToResolve.removeCategory(Intent.CATEGORY_INFO) + intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER) + intentToResolve.setPackage(packageName) + ris = pm.queryIntentActivitiesAsUser(intentToResolve, 0, userId) + } + if (ris == null || ris.size <= 0) { + return null + } + val intent = Intent(intentToResolve) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + intent.setClassName( + ris[0].activityInfo.packageName, + ris[0].activityInfo.name + ) + return intent + } + fun dumpExtras(bundle: Bundle?): String { val builder = StringBuilder() if (bundle != null) { @@ -124,4 +200,32 @@ object Utils { tabStrip.getChildAt(i).setOnTouchListener { v, event -> !enable } } } + + fun canSafelyLoadAppInfo(packageInfo: TransferableSuspendedApp, context: Context): Boolean { + return Utils.canSafelyLoadAppInfo(packageInfo, Process.myUserHandle().hashCode(), context) + } + + fun canSafelyLoadAppInfo(packageInfo: PersistableSuspendedApp, context: Context): Boolean { + return packageInfo.userId == Process.myUserHandle().hashCode() || + isAppInstalledInCurrentUser(packageInfo.packageName, context) + } + + fun canSafelyLoadAppInfo(packageInfo: TransferableSuspendedApp, userId: Int, context: Context): Boolean { + return packageInfo.userId == userId || + isAppInstalledInUser(packageInfo.packageName, context, userId) + } + + fun isAppInstalledInCurrentUser(packageName: String, context: Context): Boolean { + return isAppInstalledInUser(packageName, context, Process.myUserHandle().hashCode()) + } + + @SystemApi + fun isAppInstalledInUser(packageName: String, context: Context, userId: Int): Boolean { + try { + context.packageManager.getPackageInfoAsUser(packageName, PackageManager.GET_DISABLED_COMPONENTS, userId) + return true + } catch (e: PackageManager.NameNotFoundException) { + return false + } + } }
\ No newline at end of file |