mirror of
https://github.com/Hamza417/Inure.git
synced 2026-03-13 10:19:43 +08:00
Boot Manager framework rev
This commit is contained in:
@@ -334,4 +334,8 @@ object PackageUtils {
|
||||
}
|
||||
return ArrayUtils.deepCopy(packageInfoList)
|
||||
}
|
||||
|
||||
fun getIntentFilter(s: String): Intent {
|
||||
return Intent(s)
|
||||
}
|
||||
}
|
||||
@@ -290,6 +290,9 @@ abstract class ScopedFragment : Fragment(), SharedPreferences.OnSharedPreference
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param manualOverride if true, loader can be shown from anywhere
|
||||
*/
|
||||
open fun showLoader(manualOverride: Boolean = false) {
|
||||
if (requireArguments().getBoolean(BundleConstants.loading)) {
|
||||
loader = Loader.newInstance()
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.simple.inure.interfaces.utils;
|
||||
|
||||
public interface Copyable <T> {
|
||||
T copy();
|
||||
|
||||
T createForCopy();
|
||||
|
||||
void copyTo(T dest);
|
||||
}
|
||||
@@ -1,19 +1,18 @@
|
||||
package app.simple.inure.models;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import app.simple.inure.interfaces.utils.Copyable;
|
||||
|
||||
public class BootManagerModel implements Parcelable {
|
||||
public class BootManagerModel implements Copyable <BootManagerModel> {
|
||||
|
||||
private String packageName;
|
||||
private ArrayList <String> disabledComponents = new ArrayList <>();
|
||||
private ArrayList <String> enabledComponents = new ArrayList <>();
|
||||
private ArraySet <String> disabledComponents = new ArraySet <>();
|
||||
private ArraySet <String> enabledComponents = new ArraySet <>();
|
||||
private String name;
|
||||
private boolean enabled;
|
||||
|
||||
public BootManagerModel(String packageName, ArrayList <String> disabledComponents, ArrayList <String> enabledComponents, String name, boolean enabled) {
|
||||
public BootManagerModel(String packageName, ArraySet <String> disabledComponents, ArraySet <String> enabledComponents, String name, boolean enabled) {
|
||||
this.packageName = packageName;
|
||||
this.disabledComponents = disabledComponents;
|
||||
this.enabledComponents = enabledComponents;
|
||||
@@ -24,40 +23,6 @@ public class BootManagerModel implements Parcelable {
|
||||
public BootManagerModel() {
|
||||
}
|
||||
|
||||
protected BootManagerModel(Parcel in) {
|
||||
packageName = in.readString();
|
||||
disabledComponents = in.createStringArrayList();
|
||||
enabledComponents = in.createStringArrayList();
|
||||
name = in.readString();
|
||||
enabled = in.readByte() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(packageName);
|
||||
dest.writeStringList(disabledComponents);
|
||||
dest.writeStringList(enabledComponents);
|
||||
dest.writeString(name);
|
||||
dest.writeByte((byte) (enabled ? 1 : 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator <BootManagerModel> CREATOR = new Creator <>() {
|
||||
@Override
|
||||
public BootManagerModel createFromParcel(Parcel in) {
|
||||
return new BootManagerModel(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BootManagerModel[] newArray(int size) {
|
||||
return new BootManagerModel[size];
|
||||
}
|
||||
};
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
@@ -66,11 +31,11 @@ public class BootManagerModel implements Parcelable {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
public ArrayList <String> getDisabledComponents() {
|
||||
public ArraySet <String> getDisabledComponents() {
|
||||
return disabledComponents;
|
||||
}
|
||||
|
||||
public void setDisabledComponents(ArrayList <String> disabledComponents) {
|
||||
public void setDisabledComponents(ArraySet <String> disabledComponents) {
|
||||
this.disabledComponents = disabledComponents;
|
||||
}
|
||||
|
||||
@@ -78,16 +43,16 @@ public class BootManagerModel implements Parcelable {
|
||||
try {
|
||||
this.disabledComponents.add(disabledComponent);
|
||||
} catch (NullPointerException e) {
|
||||
this.disabledComponents = new ArrayList <>();
|
||||
this.disabledComponents = new ArraySet <>();
|
||||
this.disabledComponents.add(disabledComponent);
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList <String> getEnabledComponents() {
|
||||
public ArraySet <String> getEnabledComponents() {
|
||||
return enabledComponents;
|
||||
}
|
||||
|
||||
public void setEnabledComponents(ArrayList <String> enabledComponents) {
|
||||
public void setEnabledComponents(ArraySet <String> enabledComponents) {
|
||||
this.enabledComponents = enabledComponents;
|
||||
}
|
||||
|
||||
@@ -95,7 +60,7 @@ public class BootManagerModel implements Parcelable {
|
||||
try {
|
||||
this.enabledComponents.add(component);
|
||||
} catch (NullPointerException e) {
|
||||
this.enabledComponents = new ArrayList <>();
|
||||
this.enabledComponents = new ArraySet <>();
|
||||
this.enabledComponents.add(component);
|
||||
}
|
||||
}
|
||||
@@ -126,4 +91,23 @@ public class BootManagerModel implements Parcelable {
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BootManagerModel copy() {
|
||||
return new BootManagerModel(packageName, disabledComponents, enabledComponents, name, enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BootManagerModel createForCopy() {
|
||||
return new BootManagerModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTo(BootManagerModel dest) {
|
||||
dest.setPackageName(packageName);
|
||||
dest.setDisabledComponents(disabledComponents);
|
||||
dest.setEnabledComponents(enabledComponents);
|
||||
dest.setName(name);
|
||||
dest.setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,20 +43,17 @@ class BootManager : ScopedFragment() {
|
||||
override fun onBootComponentClicked(view: View, bootManagerModel: BootManagerModel, position: Int) {
|
||||
PopupBootManager(view).setOnPopupBootManagerCallbacks(object : PopupBootManager.Companion.PopupBootManagerCallbacks {
|
||||
override fun onEnableAllClicked() {
|
||||
bootManagerViewModel?.enableAllComponents(bootManagerModel, position)
|
||||
showLoader(manualOverride = true).also {
|
||||
bootManagerViewModel?.enableAllComponents(bootManagerModel.copy(), position)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDisableAllClicked() {
|
||||
bootManagerViewModel?.disableAllComponents(bootManagerModel, position)
|
||||
}
|
||||
}).also {
|
||||
bootManagerViewModel?.getBootManagerModelData()?.observe(viewLifecycleOwner) {
|
||||
if (it.isNotNull()) {
|
||||
adapterBootManager?.updateItem(it.first, it.second)
|
||||
bootManagerViewModel?.clearBootManagerModelData()
|
||||
showLoader(manualOverride = true).also {
|
||||
bootManagerViewModel?.disableAllComponents(bootManagerModel.copy(), position)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -66,6 +63,12 @@ class BootManager : ScopedFragment() {
|
||||
startPostponedEnterTransition()
|
||||
}
|
||||
}
|
||||
|
||||
bootManagerViewModel?.getBootManagerModelData()?.observe(viewLifecycleOwner) {
|
||||
adapterBootManager?.updateItem(it.first, it.second)
|
||||
bootManagerViewModel?.clearBootManagerModelData()
|
||||
hideLoader()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package app.simple.inure.viewmodels.panels
|
||||
|
||||
import android.app.Application
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
@@ -18,6 +20,17 @@ import java.util.stream.Collectors
|
||||
class BootManagerViewModel(application: Application) : RootViewModel(application) {
|
||||
|
||||
private val command = "pm query-receivers --components -a android.intent.action.BOOT_COMPLETED"
|
||||
private val bootCompletedIntent = "android.intent.action.BOOT_COMPLETED"
|
||||
|
||||
private val resolveInfoFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
PackageManager.MATCH_DIRECT_BOOT_AWARE or PackageManager.MATCH_DIRECT_BOOT_UNAWARE or
|
||||
PackageManager.MATCH_DISABLED_COMPONENTS or PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS or
|
||||
PackageManager.GET_RECEIVERS
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
PackageManager.GET_RECEIVERS or PackageManager.GET_DISABLED_COMPONENTS or
|
||||
PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS
|
||||
}
|
||||
|
||||
private val bootComponentData: MutableLiveData<ArrayList<BootManagerModel>> by lazy {
|
||||
MutableLiveData<ArrayList<BootManagerModel>>()
|
||||
@@ -46,86 +59,143 @@ class BootManagerViewModel(application: Application) : RootViewModel(application
|
||||
|
||||
private fun loadBootComponents() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
Shell.cmd(command).exec().let { result ->
|
||||
if (result.isSuccess) {
|
||||
val packageNames = result.out.map { it.split("/")[0] }.stream().distinct().collect(Collectors.toList())
|
||||
|
||||
val bootManagerModelArrayList = ArrayList<BootManagerModel>()
|
||||
packageNames.forEach { packageName ->
|
||||
val bootManagerModel = BootManagerModel()
|
||||
bootManagerModel.packageName = packageName
|
||||
bootManagerModel.name = PackageUtils.getApplicationName(applicationContext(), bootManagerModel.packageName)
|
||||
bootManagerModel.isEnabled = packageManager.isPackageInstalledAndEnabled(bootManagerModel.packageName)
|
||||
|
||||
result.out.forEach {
|
||||
if (it.startsWith(bootManagerModel.packageName)) {
|
||||
val componentName = bootManagerModel.packageName + it.substringAfter("/")
|
||||
if (ReceiversUtils.isEnabled(applicationContext(), bootManagerModel.packageName, componentName)) {
|
||||
bootManagerModel.addEnabledComponent(componentName)
|
||||
} else {
|
||||
bootManagerModel.addDisabledComponent(componentName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bootManagerModelArrayList.add(bootManagerModel)
|
||||
}
|
||||
|
||||
bootManagerModelArrayList.sortBy {
|
||||
it.name
|
||||
}
|
||||
|
||||
bootComponentData.postValue(bootManagerModelArrayList)
|
||||
val list = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
packageManager.queryBroadcastReceivers(PackageUtils.getIntentFilter(bootCompletedIntent), PackageManager.ResolveInfoFlags.of(resolveInfoFlags.toLong()))
|
||||
} else {
|
||||
Log.d("BootManagerViewModel", "loadBootComponents: ${result.err}")
|
||||
@Suppress("DEPRECATION")
|
||||
packageManager.queryBroadcastReceivers(PackageUtils.getIntentFilter(bootCompletedIntent), resolveInfoFlags)
|
||||
}
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
packageManager.queryBroadcastReceivers(PackageUtils.getIntentFilter(bootCompletedIntent), resolveInfoFlags)
|
||||
}
|
||||
|
||||
val bootManagerModelArrayList = ArrayList<BootManagerModel>()
|
||||
val packageNames = list.stream().map { it.activityInfo.packageName }.collect(Collectors.toList()).distinct()
|
||||
|
||||
packageNames.forEach { packageName ->
|
||||
val bootManagerModel = BootManagerModel()
|
||||
bootManagerModel.packageName = packageName
|
||||
bootManagerModel.name = PackageUtils.getApplicationName(applicationContext(), bootManagerModel.packageName)
|
||||
bootManagerModel.isEnabled = packageManager.isPackageInstalledAndEnabled(bootManagerModel.packageName)
|
||||
|
||||
list.forEach { resolveInfo ->
|
||||
if (resolveInfo.activityInfo.packageName.equals(bootManagerModel.packageName)) {
|
||||
val componentName = resolveInfo.activityInfo.name
|
||||
if (ReceiversUtils.isEnabled(applicationContext(), bootManagerModel.packageName, componentName)) {
|
||||
bootManagerModel.addEnabledComponent(componentName)
|
||||
} else {
|
||||
bootManagerModel.addDisabledComponent(componentName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bootManagerModelArrayList.add(bootManagerModel)
|
||||
}
|
||||
|
||||
bootManagerModelArrayList.sortBy {
|
||||
it.name
|
||||
}
|
||||
|
||||
bootComponentData.postValue(bootManagerModelArrayList)
|
||||
|
||||
// This method is also valid but it's not as efficient as the above method
|
||||
//
|
||||
// Shell.cmd(command).exec().let { result ->
|
||||
// if (result.isSuccess) {
|
||||
// val packageNames = result.out.map { it.split("/")[0] }.stream().distinct().collect(Collectors.toList())
|
||||
//
|
||||
// val bootManagerModelArrayList = ArrayList<BootManagerModel>()
|
||||
// packageNames.forEach { packageName ->
|
||||
// val bootManagerModel = BootManagerModel()
|
||||
// bootManagerModel.packageName = packageName
|
||||
// bootManagerModel.name = PackageUtils.getApplicationName(applicationContext(), bootManagerModel.packageName)
|
||||
// bootManagerModel.isEnabled = packageManager.isPackageInstalledAndEnabled(bootManagerModel.packageName)
|
||||
//
|
||||
// result.out.forEach {
|
||||
// if (it.startsWith(bootManagerModel.packageName)) {
|
||||
// val componentName = it.substringAfter("/")
|
||||
// if (ReceiversUtils.isEnabled(applicationContext(), bootManagerModel.packageName, componentName)) {
|
||||
// bootManagerModel.addEnabledComponent(componentName)
|
||||
// } else {
|
||||
// bootManagerModel.addDisabledComponent(componentName)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// bootManagerModelArrayList.add(bootManagerModel)
|
||||
// }
|
||||
//
|
||||
// bootManagerModelArrayList.sortBy {
|
||||
// it.name
|
||||
// }
|
||||
//
|
||||
// bootComponentData.postValue(bootManagerModelArrayList)
|
||||
// } else {
|
||||
// Log.d("BootManagerViewModel", "loadBootComponents: ${result.err}")
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
fun enableAllComponents(bootManagerModel: BootManagerModel, position: Int) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
var err = 0
|
||||
|
||||
bootManagerModel.disabledComponents.forEach { disabledComponent -> // Unnecessary but just to be sure :D
|
||||
Shell.cmd("pm enable $disabledComponent").submit {
|
||||
if (it.isSuccess) {
|
||||
bootManagerModel.enabledComponents.add(disabledComponent)
|
||||
(bootManagerModel.enabledComponents + bootManagerModel.disabledComponents).forEach { component ->
|
||||
Shell.cmd("pm enable ${bootManagerModel.packageName}/$component").exec().let { result ->
|
||||
if (result.isSuccess) {
|
||||
Log.d("BootManagerViewModel", "enableAllComponents: $component")
|
||||
} else {
|
||||
err++
|
||||
Log.e("BootManagerViewModel", "enableAllComponents: ${result.err}")
|
||||
}
|
||||
}
|
||||
}.also {
|
||||
if (err == 0) {
|
||||
bootManagerModel.disabledComponents.clear()
|
||||
bootManagerModelData.postValue(Pair(bootManagerModel, position))
|
||||
}
|
||||
|
||||
// Verify if all components are enabled ----------------------------------------------------------------------- |
|
||||
|
||||
(bootManagerModel.enabledComponents + bootManagerModel.disabledComponents).forEach { component ->
|
||||
if (ReceiversUtils.isEnabled(applicationContext(), bootManagerModel.packageName, component)) {
|
||||
bootManagerModel.addEnabledComponent(component)
|
||||
bootManagerModel.disabledComponents.remove(component)
|
||||
} else {
|
||||
bootManagerModel.addDisabledComponent(component)
|
||||
bootManagerModel.enabledComponents.remove(component)
|
||||
}
|
||||
}
|
||||
|
||||
bootManagerModelData.postValue(Pair(bootManagerModel, position))
|
||||
}
|
||||
}
|
||||
|
||||
fun disableAllComponents(bootManagerModel: BootManagerModel, position: Int) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
var err = 0
|
||||
|
||||
bootManagerModel.enabledComponents.forEach { enabledComponent ->
|
||||
Shell.cmd("pm disable $enabledComponent").submit {
|
||||
(bootManagerModel.enabledComponents + bootManagerModel.disabledComponents).forEach { component ->
|
||||
Shell.cmd("pm disable ${bootManagerModel.packageName}/$component").submit {
|
||||
if (it.isSuccess) {
|
||||
bootManagerModel.disabledComponents.add(enabledComponent)
|
||||
Log.d("BootManagerViewModel", "disabledComponent: $component")
|
||||
} else {
|
||||
err++
|
||||
Log.e("BootManagerViewModel", "disabledComponent: ${it.err}")
|
||||
}
|
||||
}
|
||||
}.also {
|
||||
if (err == 0) {
|
||||
bootManagerModel.enabledComponents.clear()
|
||||
bootManagerModelData.postValue(Pair(bootManagerModel, position))
|
||||
}
|
||||
|
||||
// Verify if all components are disabled ----------------------------------------------------------------------- |
|
||||
|
||||
(bootManagerModel.enabledComponents + bootManagerModel.disabledComponents).forEach { component ->
|
||||
if (ReceiversUtils.isEnabled(applicationContext(), bootManagerModel.packageName, component)) {
|
||||
bootManagerModel.addEnabledComponent(component)
|
||||
bootManagerModel.disabledComponents.remove(component)
|
||||
} else {
|
||||
bootManagerModel.addDisabledComponent(component)
|
||||
bootManagerModel.enabledComponents.remove(component)
|
||||
}
|
||||
}
|
||||
|
||||
bootManagerModelData.postValue(Pair(bootManagerModel, position))
|
||||
}
|
||||
}
|
||||
|
||||
fun clearBootManagerModelData() {
|
||||
bootManagerModelData.postValue(null)
|
||||
bootManagerModelData.value = null
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user