You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FoxMagiskModuleManager/app/src/main/java/com/fox2code/mmm/ModuleHolder.java

239 lines
8.1 KiB
Java

package com.fox2code.mmm;
import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;
import androidx.annotation.StringRes;
import com.fox2code.mmm.installer.InstallerInitializer;
import com.fox2code.mmm.manager.ModuleInfo;
import com.fox2code.mmm.repo.RepoModule;
import com.fox2code.mmm.utils.IntentHelper;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
public final class ModuleHolder implements Comparable<ModuleHolder> {
private static final String TAG = "ModuleHolder";
public final String moduleId;
public final NotificationType notificationType;
public final Type separator;
public final int footerPx;
public ModuleInfo moduleInfo;
public RepoModule repoModule;
public ModuleHolder(String moduleId) {
this.moduleId = Objects.requireNonNull(moduleId);
this.notificationType = null;
this.separator = null;
this.footerPx = 0;
}
public ModuleHolder(NotificationType notificationType) {
this.moduleId = "";
this.notificationType = Objects.requireNonNull(notificationType);
this.separator = null;
this.footerPx = 0;
}
public ModuleHolder(Type separator) {
this.moduleId = "";
this.notificationType = null;
this.separator = separator;
this.footerPx = 0;
}
public ModuleHolder(int footerPx) {
this.moduleId = "";
this.notificationType = null;
this.separator = null;
this.footerPx = footerPx;
}
public boolean isModuleHolder() {
return this.notificationType == null && this.separator == null;
}
public ModuleInfo getMainModuleInfo() {
return this.repoModule != null ? this.repoModule.moduleInfo : this.moduleInfo;
}
public String getMainModuleName() {
ModuleInfo moduleInfo = this.getMainModuleInfo();
if (moduleInfo == null || moduleInfo.name == null)
throw new Error("Error for " + this.getType().name() + " id " + this.moduleId);
return moduleInfo.name;
}
public String getMainModuleConfig() {
if (this.moduleInfo == null) return null;
String config = this.moduleInfo.config;
if (config == null && this.repoModule != null) {
config = this.repoModule.moduleInfo.config;
}
return config;
}
public String getUpdateTimeText() {
if (this.repoModule == null) return "";
long timeStamp = this.repoModule.lastUpdated;
return timeStamp <= 0 ? "" :
MainApplication.formatTime(timeStamp);
}
public boolean hasFlag(int flag) {
return this.moduleInfo != null && this.moduleInfo.hasFlag(flag);
}
public Type getType() {
if (this.footerPx != 0) {
return Type.FOOTER;
} else if (this.separator != null) {
return Type.SEPARATOR;
} else if (this.notificationType != null) {
return Type.NOTIFICATION;
} else if (this.moduleInfo == null) {
return Type.INSTALLABLE;
} else if (this.repoModule == null) {
return Type.INSTALLED;
} else if (this.moduleInfo.versionCode <
this.repoModule.moduleInfo.versionCode) {
return Type.UPDATABLE;
} else {
return Type.INSTALLED;
}
}
public Type getCompareType(Type type) {
if (this.separator != null) {
return this.separator;
} else if (this.notificationType != null &&
this.notificationType.special) {
return Type.SPECIAL_NOTIFICATIONS;
} else {
return type;
}
}
public boolean shouldRemove() {
return this.notificationType != null ? this.notificationType.shouldRemove() :
this.moduleInfo == null && (this.repoModule == null);
}
public void getButtons(Context context, List<ActionButtonType> buttonTypeList, boolean showcaseMode) {
if (!this.isModuleHolder()) return;
if (this.moduleInfo != null && !showcaseMode) {
buttonTypeList.add(ActionButtonType.UNINSTALL);
}
if (this.repoModule != null) {
buttonTypeList.add(ActionButtonType.INFO);
}
if (this.repoModule != null && !showcaseMode &&
InstallerInitializer.peekMagiskPath() != null) {
buttonTypeList.add(ActionButtonType.UPDATE_INSTALL);
}
String config = this.getMainModuleConfig();
if (config != null) {
String pkg = IntentHelper.getPackageOfConfig(config);
try {
context.getPackageManager().getPackageInfo(pkg, 0);
buttonTypeList.add(ActionButtonType.CONFIG);
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Config package \"" + pkg +
"\" missing for module \"" + this.moduleId + "\"");
}
}
ModuleInfo moduleInfo = this.getMainModuleInfo();
if (moduleInfo.support != null) {
buttonTypeList.add(ActionButtonType.SUPPORT);
}
if (moduleInfo.donate != null) {
buttonTypeList.add(ActionButtonType.DONATE);
}
}
public boolean hasUpdate() {
return this.moduleInfo != null && this.repoModule != null &&
this.moduleInfo.versionCode < this.repoModule.moduleInfo.versionCode;
}
@Override
public int compareTo(ModuleHolder o) {
// Compare depend on type, also allow type spoofing
Type selfTypeReal = this.getType();
Type otherTypeReal = o.getType();
Type selfType = this.getCompareType(selfTypeReal);
Type otherType = o.getCompareType(otherTypeReal);
int compare = selfType.compareTo(otherType);
return compare != 0 ? compare :
selfTypeReal == otherTypeReal ?
selfTypeReal.compare(this, o) :
selfTypeReal.compareTo(otherTypeReal);
}
public enum Type implements Comparator<ModuleHolder> {
SEPARATOR(R.string.loading, false) {
@Override
@SuppressWarnings("ConstantConditions")
public int compare(ModuleHolder o1, ModuleHolder o2) {
return o1.separator.compareTo(o2.separator);
}
},
NOTIFICATION(R.string.loading, true) {
@Override
@SuppressWarnings("ConstantConditions")
public int compare(ModuleHolder o1, ModuleHolder o2) {
return o1.notificationType.compareTo(o2.notificationType);
}
},
UPDATABLE(R.string.updatable, true) {
@Override
public int compare(ModuleHolder o1, ModuleHolder o2) {
return Long.compare(o2.repoModule.lastUpdated, o1.repoModule.lastUpdated);
}
},
INSTALLED(R.string.installed, true) {
@Override
public int compare(ModuleHolder o1, ModuleHolder o2) {
return o1.getMainModuleName().compareTo(o2.getMainModuleName());
}
},
SPECIAL_NOTIFICATIONS(R.string.loading, true),
INSTALLABLE(R.string.online_repo, true) {
@Override
public int compare(ModuleHolder o1, ModuleHolder o2) {
return Long.compare(o2.repoModule.lastUpdated, o1.repoModule.lastUpdated);
}
},
FOOTER(R.string.loading, false);
@StringRes
public final int title;
public final boolean hasBackground;
Type(@StringRes int title, boolean hasBackground) {
this.title = title;
this.hasBackground = hasBackground;
}
// Note: This method should only be called if both element have the same type
@Override
public int compare(ModuleHolder o1, ModuleHolder o2) {
return 0;
}
}
@Override
public String toString() {
return "ModuleHolder{" +
"moduleId='" + moduleId + '\'' +
", notificationType=" + notificationType +
", separator=" + separator +
", footerPx=" + footerPx +
'}';
}
}