aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java/moe/yuuta/workmode/utils/Utils.kt
diff options
context:
space:
mode:
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.kt104
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