From e9389ed9c1bb7c887798ffc6479955782dded288 Mon Sep 17 00:00:00 2001 From: awoisoak Date: Fri, 4 Jun 2021 10:27:43 +0900 Subject: [PATCH 1/7] Several Improvements It checks the existence of the activities before attempting to open them. Now if the activity can really not be opened, getAutoStartPermission will return false. Related issues: https://github.com/judemanutd/AutoStarter/issues/29 https://github.com/judemanutd/AutoStarter/issues/30 isAutoStartPermissionAvailable is checking the existence of the activity in order to avoid 'false positives' when the library is not able to open a specific settings screen. Inverted the Huawei intents to process the newer ones first (I didn't invert the rest of the manufacturers as I can't test all of them). This fix known issue with Huawei P 10 Lite https://github.com/judemanutd/AutoStarter/issues/38 (tested) Use Build.BRAND.toLowerCase(Locale.ROOT) to avoid issues with certain languages as Turkish as mentioned here: https://github.com/judemanutd/AutoStarter/issues/66 (tested) Includes FLAG_ACTIVITY_NEW_TASK so that it can be called outside an Activity. Fixed this: https://github.com/judemanutd/AutoStarter/pull/62 Add a new activity to be opened in Samsung devices as: This one open the exact Sleeping Apps setting com.samsung.android.lool/com.samsung.android.sm.battery.ui.usage.CheckableAppListActivity While this one opens the main battery settings com.samsung.android.lool/com.samsung.android.sm.battery.ui.BatteryActivity That should fixes theses (Tested with Note 8, Note 9 & Note 20): https://github.com/judemanutd/AutoStarter/issues/37 https://github.com/judemanutd/AutoStarter/issues/33 --- .../autostarter/AutoStartPermissionHelper.kt | 420 ++++++++++-------- 1 file changed, 223 insertions(+), 197 deletions(-) diff --git a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt index 0c778bd..10dede3 100644 --- a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt +++ b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt @@ -1,10 +1,10 @@ package com.judemanutd.autostarter -import android.content.ActivityNotFoundException import android.content.ComponentName import android.content.Context import android.content.Intent import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager import android.net.Uri import android.os.Build import android.provider.Settings @@ -48,8 +48,8 @@ class AutoStartPermissionHelper private constructor() { */ private val BRAND_HUAWEI = "huawei" private val PACKAGE_HUAWEI_MAIN = "com.huawei.systemmanager" - private val PACKAGE_HUAWEI_COMPONENT = "com.huawei.systemmanager.optimize.process.ProtectActivity" - private val PACKAGE_HUAWEI_COMPONENT_FALLBACK = "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity" + private val PACKAGE_HUAWEI_COMPONENT = "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity" + private val PACKAGE_HUAWEI_COMPONENT_FALLBACK = "com.huawei.systemmanager.optimize.process.ProtectActivity" /** * Oppo @@ -86,7 +86,8 @@ class AutoStartPermissionHelper private constructor() { private val BRAND_SAMSUNG = "samsung" private val PACKAGE_SAMSUNG_MAIN = "com.samsung.android.lool" private val PACKAGE_SAMSUNG_COMPONENT = "com.samsung.android.sm.ui.battery.BatteryActivity" - private val PACKAGE_SAMSUNG_COMPONENT_2 = "com.samsung.android.sm.battery.ui.BatteryActivity" + private val PACKAGE_SAMSUNG_COMPONENT_2 = "com.samsung.android.sm.battery.ui.usage.CheckableAppListActivity" + private val PACKAGE_SAMSUNG_COMPONENT_3 = "com.samsung.android.sm.battery.ui.usage.CheckableAppListActivity" /*** * One plus @@ -95,258 +96,207 @@ class AutoStartPermissionHelper private constructor() { private val PACKAGE_ONE_PLUS_MAIN = "com.oneplus.security" private val PACKAGE_ONE_PLUS_COMPONENT = "com.oneplus.security.chainlaunch.view.ChainLaunchAppListActivity" - private val PACKAGES_TO_CHECK_FOR_PERMISSION = listOf(PACKAGE_ASUS_MAIN, PACKAGE_XIAOMI_MAIN, PACKAGE_LETV_MAIN, PACKAGE_HONOR_MAIN, PACKAGE_OPPO_MAIN, - PACKAGE_OPPO_FALLBACK, PACKAGE_VIVO_MAIN, PACKAGE_VIVO_FALLBACK, PACKAGE_NOKIA_MAIN, PACKAGE_HUAWEI_MAIN, PACKAGE_SAMSUNG_MAIN, PACKAGE_ONE_PLUS_MAIN) + private val PACKAGES_TO_CHECK_FOR_PERMISSION = listOf( + PACKAGE_ASUS_MAIN, + PACKAGE_XIAOMI_MAIN, + PACKAGE_LETV_MAIN, + PACKAGE_HONOR_MAIN, + PACKAGE_OPPO_MAIN, + PACKAGE_OPPO_FALLBACK, + PACKAGE_VIVO_MAIN, + PACKAGE_VIVO_FALLBACK, + PACKAGE_NOKIA_MAIN, + PACKAGE_HUAWEI_MAIN, + PACKAGE_SAMSUNG_MAIN, + PACKAGE_ONE_PLUS_MAIN + ) - fun getAutoStartPermission(context: Context): Boolean { + /** + * It will attempt to open the specific manufacturer settings screen with the autostart permission + * If [open] is changed to false it will just check the screen existence + * + * @param context + * @param open, if true it will attempt to open the activity, otherwise it will just check its existence + * @return true if the activity was opened or is confirmed that it exists (depending on [open]]), false otherwise + */ + fun getAutoStartPermission(context: Context, open: Boolean = true): Boolean { - when (Build.BRAND.toLowerCase(Locale.getDefault())) { + when (Build.BRAND.toLowerCase(Locale.ROOT)) { - BRAND_ASUS -> return autoStartAsus(context) + BRAND_ASUS -> return autoStartAsus(context, open) - BRAND_XIAOMI, BRAND_XIAOMI_POCO, BRAND_XIAOMI_REDMI -> return autoStartXiaomi(context) + BRAND_XIAOMI, BRAND_XIAOMI_POCO, BRAND_XIAOMI_REDMI -> return autoStartXiaomi(context, open) - BRAND_LETV -> return autoStartLetv(context) + BRAND_LETV -> return autoStartLetv(context, open) - BRAND_HONOR -> return autoStartHonor(context) + BRAND_HONOR -> return autoStartHonor(context, open) - BRAND_HUAWEI -> return autoStartHuawei(context) + BRAND_HUAWEI -> return autoStartHuawei(context, open) - BRAND_OPPO -> return autoStartOppo(context) + BRAND_OPPO -> return autoStartOppo(context, open) - BRAND_VIVO -> return autoStartVivo(context) + BRAND_VIVO -> return autoStartVivo(context, open) - BRAND_NOKIA -> return autoStartNokia(context) + BRAND_NOKIA -> return autoStartNokia(context, open) - BRAND_SAMSUNG -> return autoStartSamsung(context) + BRAND_SAMSUNG -> return autoStartSamsung(context, open) - BRAND_ONE_PLUS -> return autoStartOnePlus(context) + BRAND_ONE_PLUS -> return autoStartOnePlus(context, open) else -> { return false } } - } + /** + * Checks whether the autostart permission is present in the manufacturer and supported by the library + * + * @param context + * @return true if autostart permission is present in the manufacturer and supported by the library, false otherwise + */ fun isAutoStartPermissionAvailable(context: Context): Boolean { - val packages: List val pm = context.packageManager packages = pm.getInstalledApplications(0) for (packageInfo in packages) { - if (PACKAGES_TO_CHECK_FOR_PERMISSION.contains(packageInfo.packageName)) { - return true - } + if (PACKAGES_TO_CHECK_FOR_PERMISSION.contains(packageInfo.packageName) + && getAutoStartPermission(context, false) + ) return true } return false } - private fun autoStartXiaomi(context: Context): Boolean { - if (isPackageExists(context, PACKAGE_XIAOMI_MAIN)) { - try { - startIntent(context, PACKAGE_XIAOMI_MAIN, PACKAGE_XIAOMI_COMPONENT) - } catch (e: Exception) { - e.printStackTrace() - return false - } - } else { - return false - } - - return true + private fun autoStartXiaomi(context: Context, open: Boolean): Boolean { + return autoStart( + context, + listOf(PACKAGE_XIAOMI_MAIN), + listOf(getIntent(PACKAGE_XIAOMI_MAIN, PACKAGE_XIAOMI_COMPONENT)), + open + ) } - private fun autoStartAsus(context: Context): Boolean { - if (isPackageExists(context, PACKAGE_ASUS_MAIN)) { - try { - startIntent(context, PACKAGE_ASUS_MAIN, PACKAGE_ASUS_COMPONENT) - } catch (e: Exception) { - e.printStackTrace() - try { - startIntent(context, PACKAGE_ASUS_MAIN, PACKAGE_ASUS_COMPONENT_FALLBACK) - } catch (ex: Exception) { - ex.printStackTrace() - return false - } - } - } else { - return false - } - - return true + private fun autoStartAsus(context: Context, open: Boolean): Boolean { + return autoStart( + context, + listOf(PACKAGE_ASUS_MAIN), + listOf( + getIntent(PACKAGE_ASUS_MAIN, PACKAGE_ASUS_COMPONENT), + getIntent(PACKAGE_ASUS_MAIN, PACKAGE_ASUS_COMPONENT_FALLBACK) + ), + open + ) } - private fun autoStartLetv(context: Context): Boolean { - if (isPackageExists(context, PACKAGE_LETV_MAIN)) { - try { - startIntent(context, PACKAGE_LETV_MAIN, PACKAGE_LETV_COMPONENT) - } catch (e: Exception) { - e.printStackTrace() - return false - } - } else { - return false - } - - return true + private fun autoStartLetv(context: Context, open: Boolean): Boolean { + return autoStart( + context, + listOf(PACKAGE_LETV_MAIN), + listOf(getIntent(PACKAGE_LETV_MAIN, PACKAGE_LETV_COMPONENT)), + open + ) } - private fun autoStartHonor(context: Context): Boolean { - if (isPackageExists(context, PACKAGE_HONOR_MAIN)) { - try { - startIntent(context, PACKAGE_HONOR_MAIN, PACKAGE_HONOR_COMPONENT) - } catch (e: Exception) { - e.printStackTrace() - return false - } - } else { - return false - } - - return true + private fun autoStartHonor(context: Context, open: Boolean): Boolean { + return autoStart( + context, + listOf(PACKAGE_HONOR_MAIN), + listOf(getIntent(PACKAGE_HONOR_MAIN, PACKAGE_HONOR_COMPONENT)), + open + ) } - private fun autoStartHuawei(context: Context): Boolean { - if (isPackageExists(context, PACKAGE_HUAWEI_MAIN)) { - try { - startIntent(context, PACKAGE_HUAWEI_MAIN, PACKAGE_HUAWEI_COMPONENT) - } catch (e: Exception) { - e.printStackTrace() - try { - startIntent(context, PACKAGE_HUAWEI_MAIN, PACKAGE_HUAWEI_COMPONENT_FALLBACK) - } catch (ex: Exception) { - ex.printStackTrace() - return false - } - } - } else { - return false - } - - return true + private fun autoStartHuawei(context: Context, open: Boolean): Boolean { + return autoStart( + context, + listOf(PACKAGE_HUAWEI_MAIN), + listOf( + getIntent(PACKAGE_HUAWEI_MAIN, PACKAGE_HUAWEI_COMPONENT), + getIntent(PACKAGE_HUAWEI_MAIN, PACKAGE_HUAWEI_COMPONENT_FALLBACK) + ), + open + ) } - private fun autoStartOppo(context: Context): Boolean { - if (isPackageExists(context, PACKAGE_OPPO_MAIN) || isPackageExists(context, PACKAGE_OPPO_FALLBACK)) { - try { - startIntent(context, PACKAGE_OPPO_MAIN, PACKAGE_OPPO_COMPONENT) - } catch (e: Exception) { - e.printStackTrace() - try { - startIntent(context, PACKAGE_OPPO_FALLBACK, PACKAGE_OPPO_COMPONENT_FALLBACK) - } catch (ex: Exception) { - ex.printStackTrace() - try { - startIntent(context, PACKAGE_OPPO_MAIN, PACKAGE_OPPO_COMPONENT_FALLBACK_A) - } catch (exx: Exception) { - exx.printStackTrace() - return launchOppoAppInfo(context) - } - } - } - } else { - return launchOppoAppInfo(context) - } - return true + private fun autoStartOppo(context: Context, open: Boolean): Boolean { + return if (autoStart( + context, + listOf(PACKAGE_OPPO_MAIN, PACKAGE_OPPO_FALLBACK), + listOf( + getIntent(PACKAGE_OPPO_MAIN, PACKAGE_OPPO_COMPONENT), + getIntent(PACKAGE_OPPO_FALLBACK, PACKAGE_OPPO_COMPONENT_FALLBACK), + getIntent(PACKAGE_OPPO_MAIN, PACKAGE_OPPO_COMPONENT_FALLBACK_A) + ), + open + ) + ) true + else launchOppoAppInfo(context, open) } - private fun launchOppoAppInfo(context: Context): Boolean { + private fun launchOppoAppInfo(context: Context, open: Boolean): Boolean { return try { val i = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) i.addCategory(Intent.CATEGORY_DEFAULT) i.data = Uri.parse("package:${context.packageName}") - context.startActivity(i) - true + if (open) { + context.startActivity(i) + true + } else { + isActivityFound(context, i) + } } catch (exx: Exception) { exx.printStackTrace() false } } - private fun autoStartVivo(context: Context): Boolean { - if (isPackageExists(context, PACKAGE_VIVO_MAIN) || isPackageExists(context, PACKAGE_VIVO_FALLBACK)) { - try { - startIntent(context, PACKAGE_VIVO_MAIN, PACKAGE_VIVO_COMPONENT) - } catch (e: Exception) { - e.printStackTrace() - try { - startIntent(context, PACKAGE_VIVO_FALLBACK, PACKAGE_VIVO_COMPONENT_FALLBACK) - } catch (ex: Exception) { - ex.printStackTrace() - try { - startIntent(context, PACKAGE_VIVO_MAIN, PACKAGE_VIVO_COMPONENT_FALLBACK_A) - } catch (exx: Exception) { - exx.printStackTrace() - return false - } - } - } - } else { - return false - } - - return true + private fun autoStartVivo(context: Context, open: Boolean): Boolean { + return autoStart( + context, + listOf(PACKAGE_VIVO_MAIN, PACKAGE_VIVO_FALLBACK), + listOf( + getIntent(PACKAGE_VIVO_MAIN, PACKAGE_VIVO_COMPONENT), + getIntent(PACKAGE_VIVO_FALLBACK, PACKAGE_VIVO_COMPONENT_FALLBACK), + getIntent(PACKAGE_VIVO_MAIN, PACKAGE_VIVO_COMPONENT_FALLBACK_A) + ), + open + ) } - private fun autoStartNokia(context: Context): Boolean { - if (isPackageExists(context, PACKAGE_NOKIA_MAIN)) { - try { - startIntent(context, PACKAGE_NOKIA_MAIN, PACKAGE_NOKIA_COMPONENT) - } catch (e: Exception) { - e.printStackTrace() - return false - } - } else { - return false - } - - return true + private fun autoStartNokia(context: Context, open: Boolean): Boolean { + return autoStart( + context, + listOf(PACKAGE_NOKIA_MAIN), + listOf(getIntent(PACKAGE_NOKIA_MAIN, PACKAGE_NOKIA_COMPONENT)), + open + ) } - private fun autoStartSamsung(context: Context): Boolean { - if (isPackageExists(context, PACKAGE_SAMSUNG_MAIN)) { - try { - startIntent(context, PACKAGE_SAMSUNG_MAIN, PACKAGE_SAMSUNG_COMPONENT) - } catch (a: ActivityNotFoundException) { - // Try with the another package component - try { - startIntent(context, PACKAGE_SAMSUNG_MAIN, PACKAGE_SAMSUNG_COMPONENT_2) - } catch (e: Exception) { - e.printStackTrace() - return false - } - } catch (e: Exception) { - e.printStackTrace() - return false - } - } else { - return false - } - - return true + private fun autoStartSamsung(context: Context, open: Boolean): Boolean { + return autoStart( + context, + listOf(PACKAGE_SAMSUNG_MAIN), + listOf( + getIntent(PACKAGE_SAMSUNG_MAIN, PACKAGE_SAMSUNG_COMPONENT), + getIntent(PACKAGE_SAMSUNG_MAIN, PACKAGE_SAMSUNG_COMPONENT_2), + getIntent(PACKAGE_SAMSUNG_MAIN, PACKAGE_SAMSUNG_COMPONENT_3) + ), + open + ) } - private fun autoStartOnePlus(context: Context): Boolean { - if (isPackageExists(context, PACKAGE_ONE_PLUS_MAIN)) { - try { - startIntent(context, PACKAGE_ONE_PLUS_MAIN, PACKAGE_ONE_PLUS_COMPONENT) - } catch (e: Exception) { - e.printStackTrace() - return false - } - } else { - return false - } - - return true + private fun autoStartOnePlus(context: Context, open: Boolean): Boolean { + return autoStart( + context, + listOf(PACKAGE_ONE_PLUS_MAIN), + listOf(getIntent(PACKAGE_ONE_PLUS_MAIN, PACKAGE_ONE_PLUS_COMPONENT)), + open + ) } @Throws(Exception::class) - private fun startIntent(context: Context, packageName: String, componentName: String) { + private fun startIntent(context: Context, intent: Intent) { try { - val intent = Intent() - intent.component = ComponentName(packageName, componentName) context.startActivity(intent) } catch (exception: Exception) { exception.printStackTrace() @@ -367,10 +317,86 @@ class AutoStartPermissionHelper private constructor() { } companion object { + @JvmStatic fun getInstance(): AutoStartPermissionHelper { return AutoStartPermissionHelper() } + } + + /** + * Generates an intent with the passed package and component name + * @param packageName + * @param componentName + * + * @return the intent generated + */ + private fun getIntent(packageName: String, componentName: String): Intent { + return Intent().apply { + component = ComponentName(packageName, componentName) + flags = Intent.FLAG_ACTIVITY_NEW_TASK + } + } + + /** + * Will query the passed intent to check whether the Activity really exists + * + * @param context + * @param intent, intent to open an activity + * + * @return true if activity is found, false otherwise + */ + private fun isActivityFound(context: Context, intent: Intent): Boolean { + return context.packageManager.queryIntentActivities( + intent, PackageManager.MATCH_DEFAULT_ONLY + ).isNotEmpty() + } + + /** + * Will query the passed list of intents to check whether any of the activities exist + * + * @param context + * @param intents, list of intents to open an activity + * + * @return true if activity is found, false otherwise + */ + private fun areActivitiesFound(context: Context, intents: List): Boolean { + return intents.any { isActivityFound(context, it) } + } + + /** + * Will attempt to open the AutoStart settings activity from the passed list of intents in order. + * The first activity found will be opened. + * + * @param context + * @param intents list of intents + * + * @return true if an activity was opened, false otherwise + */ + private fun openAutoStartScreen(context: Context, intents: List): Boolean { + intents.forEach { + if (isActivityFound(context, it)) { + startIntent(context, it) + return@openAutoStartScreen true + } + } + return false + } + /** + * Will trigger the common autostart permission logic. If [open] is true it will attempt to open the specific + * manufacturer setting screen, otherwise it will just check for its existence + * + * @param context + * @param packages, list of known packages of the corresponding manufacturer + * @param intents, list of known intents that open the corresponding manufacturer settings screens + * @param open, if true it will attempt to open the settings screen, otherwise it just check its existence + * @return true if the screen was opened or exists, false if it doesn't exist or could not be opened + */ + private fun autoStart(context: Context, packages: List, intents: List, open: Boolean): Boolean { + return if (packages.any { isPackageExists(context, it) }) { + if (open) openAutoStartScreen(context, intents) + else areActivitiesFound(context, intents) + } else false } -} +} \ No newline at end of file From e7ccfb97e3902233c963b77f99938bf32c6a9d51 Mon Sep 17 00:00:00 2001 From: awoisoak Date: Fri, 4 Jun 2021 10:49:46 +0900 Subject: [PATCH 2/7] Make new task flag optional Set to false by default for backward compatibility --- .../autostarter/AutoStartPermissionHelper.kt | 93 ++++++++++--------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt index 10dede3..8c31c1f 100644 --- a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt +++ b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt @@ -117,31 +117,32 @@ class AutoStartPermissionHelper private constructor() { * * @param context * @param open, if true it will attempt to open the activity, otherwise it will just check its existence + * @param newTask, if true when the activity is attempted to be opened it will add FLAG_ACTIVITY_NEW_TASK to the intent * @return true if the activity was opened or is confirmed that it exists (depending on [open]]), false otherwise */ - fun getAutoStartPermission(context: Context, open: Boolean = true): Boolean { + fun getAutoStartPermission(context: Context, open: Boolean = true, newTask: Boolean = false): Boolean { when (Build.BRAND.toLowerCase(Locale.ROOT)) { - BRAND_ASUS -> return autoStartAsus(context, open) + BRAND_ASUS -> return autoStartAsus(context, open, newTask) - BRAND_XIAOMI, BRAND_XIAOMI_POCO, BRAND_XIAOMI_REDMI -> return autoStartXiaomi(context, open) + BRAND_XIAOMI, BRAND_XIAOMI_POCO, BRAND_XIAOMI_REDMI -> return autoStartXiaomi(context, open, newTask) - BRAND_LETV -> return autoStartLetv(context, open) + BRAND_LETV -> return autoStartLetv(context, open, newTask) - BRAND_HONOR -> return autoStartHonor(context, open) + BRAND_HONOR -> return autoStartHonor(context, open, newTask) - BRAND_HUAWEI -> return autoStartHuawei(context, open) + BRAND_HUAWEI -> return autoStartHuawei(context, open, newTask) - BRAND_OPPO -> return autoStartOppo(context, open) + BRAND_OPPO -> return autoStartOppo(context, open, newTask) - BRAND_VIVO -> return autoStartVivo(context, open) + BRAND_VIVO -> return autoStartVivo(context, open, newTask) - BRAND_NOKIA -> return autoStartNokia(context, open) + BRAND_NOKIA -> return autoStartNokia(context, open, newTask) - BRAND_SAMSUNG -> return autoStartSamsung(context, open) + BRAND_SAMSUNG -> return autoStartSamsung(context, open, newTask) - BRAND_ONE_PLUS -> return autoStartOnePlus(context, open) + BRAND_ONE_PLUS -> return autoStartOnePlus(context, open, newTask) else -> { return false @@ -161,79 +162,79 @@ class AutoStartPermissionHelper private constructor() { packages = pm.getInstalledApplications(0) for (packageInfo in packages) { if (PACKAGES_TO_CHECK_FOR_PERMISSION.contains(packageInfo.packageName) - && getAutoStartPermission(context, false) + && getAutoStartPermission(context, open = false, newTask = false) ) return true } return false } - private fun autoStartXiaomi(context: Context, open: Boolean): Boolean { + private fun autoStartXiaomi(context: Context, open: Boolean, newTask: Boolean): Boolean { return autoStart( context, listOf(PACKAGE_XIAOMI_MAIN), - listOf(getIntent(PACKAGE_XIAOMI_MAIN, PACKAGE_XIAOMI_COMPONENT)), + listOf(getIntent(PACKAGE_XIAOMI_MAIN, PACKAGE_XIAOMI_COMPONENT, newTask)), open ) } - private fun autoStartAsus(context: Context, open: Boolean): Boolean { + private fun autoStartAsus(context: Context, open: Boolean, newTask: Boolean): Boolean { return autoStart( context, listOf(PACKAGE_ASUS_MAIN), listOf( - getIntent(PACKAGE_ASUS_MAIN, PACKAGE_ASUS_COMPONENT), - getIntent(PACKAGE_ASUS_MAIN, PACKAGE_ASUS_COMPONENT_FALLBACK) + getIntent(PACKAGE_ASUS_MAIN, PACKAGE_ASUS_COMPONENT, newTask), + getIntent(PACKAGE_ASUS_MAIN, PACKAGE_ASUS_COMPONENT_FALLBACK, newTask) ), open ) } - private fun autoStartLetv(context: Context, open: Boolean): Boolean { + private fun autoStartLetv(context: Context, open: Boolean, newTask: Boolean): Boolean { return autoStart( context, listOf(PACKAGE_LETV_MAIN), - listOf(getIntent(PACKAGE_LETV_MAIN, PACKAGE_LETV_COMPONENT)), + listOf(getIntent(PACKAGE_LETV_MAIN, PACKAGE_LETV_COMPONENT, newTask)), open ) } - private fun autoStartHonor(context: Context, open: Boolean): Boolean { + private fun autoStartHonor(context: Context, open: Boolean, newTask: Boolean): Boolean { return autoStart( context, listOf(PACKAGE_HONOR_MAIN), - listOf(getIntent(PACKAGE_HONOR_MAIN, PACKAGE_HONOR_COMPONENT)), + listOf(getIntent(PACKAGE_HONOR_MAIN, PACKAGE_HONOR_COMPONENT, newTask)), open ) } - private fun autoStartHuawei(context: Context, open: Boolean): Boolean { + private fun autoStartHuawei(context: Context, open: Boolean, newTask: Boolean): Boolean { return autoStart( context, listOf(PACKAGE_HUAWEI_MAIN), listOf( - getIntent(PACKAGE_HUAWEI_MAIN, PACKAGE_HUAWEI_COMPONENT), - getIntent(PACKAGE_HUAWEI_MAIN, PACKAGE_HUAWEI_COMPONENT_FALLBACK) + getIntent(PACKAGE_HUAWEI_MAIN, PACKAGE_HUAWEI_COMPONENT, newTask), + getIntent(PACKAGE_HUAWEI_MAIN, PACKAGE_HUAWEI_COMPONENT_FALLBACK, newTask) ), open ) } - private fun autoStartOppo(context: Context, open: Boolean): Boolean { + private fun autoStartOppo(context: Context, open: Boolean, newTask: Boolean): Boolean { return if (autoStart( context, listOf(PACKAGE_OPPO_MAIN, PACKAGE_OPPO_FALLBACK), listOf( - getIntent(PACKAGE_OPPO_MAIN, PACKAGE_OPPO_COMPONENT), - getIntent(PACKAGE_OPPO_FALLBACK, PACKAGE_OPPO_COMPONENT_FALLBACK), - getIntent(PACKAGE_OPPO_MAIN, PACKAGE_OPPO_COMPONENT_FALLBACK_A) + getIntent(PACKAGE_OPPO_MAIN, PACKAGE_OPPO_COMPONENT, newTask), + getIntent(PACKAGE_OPPO_FALLBACK, PACKAGE_OPPO_COMPONENT_FALLBACK, newTask), + getIntent(PACKAGE_OPPO_MAIN, PACKAGE_OPPO_COMPONENT_FALLBACK_A, newTask) ), open ) ) true - else launchOppoAppInfo(context, open) + else launchOppoAppInfo(context, open, newTask) } - private fun launchOppoAppInfo(context: Context, open: Boolean): Boolean { + private fun launchOppoAppInfo(context: Context, open: Boolean, newTask: Boolean): Boolean { return try { val i = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) i.addCategory(Intent.CATEGORY_DEFAULT) @@ -250,46 +251,46 @@ class AutoStartPermissionHelper private constructor() { } } - private fun autoStartVivo(context: Context, open: Boolean): Boolean { + private fun autoStartVivo(context: Context, open: Boolean, newTask: Boolean): Boolean { return autoStart( context, listOf(PACKAGE_VIVO_MAIN, PACKAGE_VIVO_FALLBACK), listOf( - getIntent(PACKAGE_VIVO_MAIN, PACKAGE_VIVO_COMPONENT), - getIntent(PACKAGE_VIVO_FALLBACK, PACKAGE_VIVO_COMPONENT_FALLBACK), - getIntent(PACKAGE_VIVO_MAIN, PACKAGE_VIVO_COMPONENT_FALLBACK_A) + getIntent(PACKAGE_VIVO_MAIN, PACKAGE_VIVO_COMPONENT, newTask), + getIntent(PACKAGE_VIVO_FALLBACK, PACKAGE_VIVO_COMPONENT_FALLBACK, newTask), + getIntent(PACKAGE_VIVO_MAIN, PACKAGE_VIVO_COMPONENT_FALLBACK_A, newTask) ), open ) } - private fun autoStartNokia(context: Context, open: Boolean): Boolean { + private fun autoStartNokia(context: Context, open: Boolean, newTask: Boolean): Boolean { return autoStart( context, listOf(PACKAGE_NOKIA_MAIN), - listOf(getIntent(PACKAGE_NOKIA_MAIN, PACKAGE_NOKIA_COMPONENT)), + listOf(getIntent(PACKAGE_NOKIA_MAIN, PACKAGE_NOKIA_COMPONENT, newTask)), open ) } - private fun autoStartSamsung(context: Context, open: Boolean): Boolean { + private fun autoStartSamsung(context: Context, open: Boolean, newTask: Boolean): Boolean { return autoStart( context, listOf(PACKAGE_SAMSUNG_MAIN), listOf( - getIntent(PACKAGE_SAMSUNG_MAIN, PACKAGE_SAMSUNG_COMPONENT), - getIntent(PACKAGE_SAMSUNG_MAIN, PACKAGE_SAMSUNG_COMPONENT_2), - getIntent(PACKAGE_SAMSUNG_MAIN, PACKAGE_SAMSUNG_COMPONENT_3) + getIntent(PACKAGE_SAMSUNG_MAIN, PACKAGE_SAMSUNG_COMPONENT, newTask), + getIntent(PACKAGE_SAMSUNG_MAIN, PACKAGE_SAMSUNG_COMPONENT_2, newTask), + getIntent(PACKAGE_SAMSUNG_MAIN, PACKAGE_SAMSUNG_COMPONENT_3, newTask) ), open ) } - private fun autoStartOnePlus(context: Context, open: Boolean): Boolean { + private fun autoStartOnePlus(context: Context, open: Boolean, newTask: Boolean): Boolean { return autoStart( context, listOf(PACKAGE_ONE_PLUS_MAIN), - listOf(getIntent(PACKAGE_ONE_PLUS_MAIN, PACKAGE_ONE_PLUS_COMPONENT)), + listOf(getIntent(PACKAGE_ONE_PLUS_MAIN, PACKAGE_ONE_PLUS_COMPONENT, newTask)), open ) } @@ -328,13 +329,14 @@ class AutoStartPermissionHelper private constructor() { * Generates an intent with the passed package and component name * @param packageName * @param componentName + * @param newTask * * @return the intent generated */ - private fun getIntent(packageName: String, componentName: String): Intent { + private fun getIntent(packageName: String, componentName: String, newTask: Boolean): Intent { return Intent().apply { component = ComponentName(packageName, componentName) - flags = Intent.FLAG_ACTIVITY_NEW_TASK + if (newTask) flags = Intent.FLAG_ACTIVITY_NEW_TASK } } @@ -399,4 +401,5 @@ class AutoStartPermissionHelper private constructor() { else areActivitiesFound(context, intents) } else false } -} \ No newline at end of file +} + From 8c4a3dc1bc9b79ac775b7b8e90ea8949a014134a Mon Sep 17 00:00:00 2001 From: awoisoak Date: Fri, 4 Jun 2021 13:57:07 +0900 Subject: [PATCH 3/7] Make optional the way autostart permission is considered available For backward compatibility with the library, by default autostart is considered available even if the library does not support the specific screen. --- .../judemanutd/autostarter/AutoStartPermissionHelper.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt index 8c31c1f..c2529ce 100644 --- a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt +++ b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt @@ -154,15 +154,18 @@ class AutoStartPermissionHelper private constructor() { * Checks whether the autostart permission is present in the manufacturer and supported by the library * * @param context + * @param onlyIfSupported if true, the method will only return true if the screen is supported by the library. + * If false, the method will return true as long as the permission exist even if the screen is not supported + * by the library. * @return true if autostart permission is present in the manufacturer and supported by the library, false otherwise */ - fun isAutoStartPermissionAvailable(context: Context): Boolean { + fun isAutoStartPermissionAvailable(context: Context, onlyIfSupported: Boolean = false): Boolean { val packages: List val pm = context.packageManager packages = pm.getInstalledApplications(0) for (packageInfo in packages) { if (PACKAGES_TO_CHECK_FOR_PERMISSION.contains(packageInfo.packageName) - && getAutoStartPermission(context, open = false, newTask = false) + && (!onlyIfSupported || getAutoStartPermission(context, open = false)) ) return true } return false From b944d2db4c24f5586de43530aefdc1207bb26827 Mon Sep 17 00:00:00 2001 From: awoisoak Date: Fri, 4 Jun 2021 14:04:19 +0900 Subject: [PATCH 4/7] Fix Samsung component This opens the main Battery Settings com.samsung.android.sm.battery.ui.BatteryActivity so we should only use it if we can't open the specific Sleeping Apps settings with: com.samsung.android.sm.battery.ui.usage.CheckableAppListActivity --- .../com/judemanutd/autostarter/AutoStartPermissionHelper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt index c2529ce..a4c3db1 100644 --- a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt +++ b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt @@ -87,7 +87,7 @@ class AutoStartPermissionHelper private constructor() { private val PACKAGE_SAMSUNG_MAIN = "com.samsung.android.lool" private val PACKAGE_SAMSUNG_COMPONENT = "com.samsung.android.sm.ui.battery.BatteryActivity" private val PACKAGE_SAMSUNG_COMPONENT_2 = "com.samsung.android.sm.battery.ui.usage.CheckableAppListActivity" - private val PACKAGE_SAMSUNG_COMPONENT_3 = "com.samsung.android.sm.battery.ui.usage.CheckableAppListActivity" + private val PACKAGE_SAMSUNG_COMPONENT_3 = "com.samsung.android.sm.battery.ui.BatteryActivity" /*** * One plus From a9ff55f57dcae4ec8a17a403708cd502439bd641 Mon Sep 17 00:00:00 2001 From: awoisoak Date: Mon, 7 Jun 2021 12:03:40 +0900 Subject: [PATCH 5/7] Support OnePlus specific intent action --- .../autostarter/AutoStartPermissionHelper.kt | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt index a4c3db1..234a729 100644 --- a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt +++ b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt @@ -95,6 +95,7 @@ class AutoStartPermissionHelper private constructor() { private val BRAND_ONE_PLUS = "oneplus" private val PACKAGE_ONE_PLUS_MAIN = "com.oneplus.security" private val PACKAGE_ONE_PLUS_COMPONENT = "com.oneplus.security.chainlaunch.view.ChainLaunchAppListActivity" + private val PACKAGE_ONE_PLUS_ACTION = "com.android.settings.action.BACKGROUND_OPTIMIZE" private val PACKAGES_TO_CHECK_FOR_PERMISSION = listOf( PACKAGE_ASUS_MAIN, @@ -295,7 +296,7 @@ class AutoStartPermissionHelper private constructor() { listOf(PACKAGE_ONE_PLUS_MAIN), listOf(getIntent(PACKAGE_ONE_PLUS_MAIN, PACKAGE_ONE_PLUS_COMPONENT, newTask)), open - ) + ) || autoStartFromAction(context, listOf(getIntentFromAction(PACKAGE_ONE_PLUS_ACTION, newTask)), open) } @Throws(Exception::class) @@ -343,6 +344,19 @@ class AutoStartPermissionHelper private constructor() { } } + /** + * Generates an intent with the passed action + * @param intentAction + * + * @return the intent generated + */ + private fun getIntentFromAction(intentAction: String, newTask: Boolean): Intent { + return Intent().apply { + action = "com.android.settings.action.BACKGROUND_OPTIMIZE" + if (newTask) flags = Intent.FLAG_ACTIVITY_NEW_TASK + } + } + /** * Will query the passed intent to check whether the Activity really exists * @@ -404,5 +418,19 @@ class AutoStartPermissionHelper private constructor() { else areActivitiesFound(context, intents) } else false } + + /** + * Will trigger the common autostart permission logic. If [open] is true it will attempt to open the specific + * manufacturer setting screen, otherwise it will just check for its existence + * + * @param context + * @param intentActions, list of known intent actions that open the corresponding manufacturer settings screens + * @param open, if true it will attempt to open the settings screen, otherwise it just check its existence + * @return true if the screen was opened or exists, false if it doesn't exist or could not be opened + */ + private fun autoStartFromAction(context: Context, intentActions: List, open: Boolean): Boolean { + return if (open) openAutoStartScreen(context, intentActions) + else areActivitiesFound(context, intentActions) + } } From 4b321a16f76942b50e9417664b02348c747267ba Mon Sep 17 00:00:00 2001 From: awoisoak Date: Wed, 9 Jun 2021 09:34:37 +0900 Subject: [PATCH 6/7] Fix intent --- .../autostarter/AutoStartPermissionHelper.kt | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt index 234a729..b0e6d58 100644 --- a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt +++ b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt @@ -97,20 +97,8 @@ class AutoStartPermissionHelper private constructor() { private val PACKAGE_ONE_PLUS_COMPONENT = "com.oneplus.security.chainlaunch.view.ChainLaunchAppListActivity" private val PACKAGE_ONE_PLUS_ACTION = "com.android.settings.action.BACKGROUND_OPTIMIZE" - private val PACKAGES_TO_CHECK_FOR_PERMISSION = listOf( - PACKAGE_ASUS_MAIN, - PACKAGE_XIAOMI_MAIN, - PACKAGE_LETV_MAIN, - PACKAGE_HONOR_MAIN, - PACKAGE_OPPO_MAIN, - PACKAGE_OPPO_FALLBACK, - PACKAGE_VIVO_MAIN, - PACKAGE_VIVO_FALLBACK, - PACKAGE_NOKIA_MAIN, - PACKAGE_HUAWEI_MAIN, - PACKAGE_SAMSUNG_MAIN, - PACKAGE_ONE_PLUS_MAIN - ) + private val PACKAGES_TO_CHECK_FOR_PERMISSION = listOf(PACKAGE_ASUS_MAIN, PACKAGE_XIAOMI_MAIN, PACKAGE_LETV_MAIN, PACKAGE_HONOR_MAIN, PACKAGE_OPPO_MAIN, + PACKAGE_OPPO_FALLBACK, PACKAGE_VIVO_MAIN, PACKAGE_VIVO_FALLBACK, PACKAGE_NOKIA_MAIN, PACKAGE_HUAWEI_MAIN, PACKAGE_SAMSUNG_MAIN, PACKAGE_ONE_PLUS_MAIN) /** * It will attempt to open the specific manufacturer settings screen with the autostart permission @@ -340,20 +328,21 @@ class AutoStartPermissionHelper private constructor() { private fun getIntent(packageName: String, componentName: String, newTask: Boolean): Intent { return Intent().apply { component = ComponentName(packageName, componentName) - if (newTask) flags = Intent.FLAG_ACTIVITY_NEW_TASK + if (newTask) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } } /** * Generates an intent with the passed action * @param intentAction + * @param newTask * * @return the intent generated */ private fun getIntentFromAction(intentAction: String, newTask: Boolean): Intent { return Intent().apply { - action = "com.android.settings.action.BACKGROUND_OPTIMIZE" - if (newTask) flags = Intent.FLAG_ACTIVITY_NEW_TASK + action = intentAction + if (newTask) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } } From 5b7a15797a0b70d89c40b65b272eb5adf37ccdae Mon Sep 17 00:00:00 2001 From: awoisoak Date: Wed, 9 Jun 2021 16:46:28 +0900 Subject: [PATCH 7/7] Make sure class is only instantiated once --- .../com/judemanutd/autostarter/AutoStartPermissionHelper.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt index b0e6d58..eb2cceb 100644 --- a/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt +++ b/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt @@ -311,9 +311,10 @@ class AutoStartPermissionHelper private constructor() { companion object { - @JvmStatic + private val myInstance by lazy { AutoStartPermissionHelper() } + fun getInstance(): AutoStartPermissionHelper { - return AutoStartPermissionHelper() + return myInstance } }