@ -21,26 +21,19 @@ import java.util.HashMap;
// See https://docs.github.com/en/rest/reference/repos#releases
public class AppUpdateManager {
public static final int FLAG_COMPAT_LOW_QUALITY = 0x0001 ;
public static final int FLAG_COMPAT_NO_EXT = 0x0002 ;
public static final int FLAG_COMPAT_MAGISK_CMD = 0x0004 ;
public static final int FLAG_COMPAT_NEED_32BIT = 0x0008 ;
public static final int FLAG_COMPAT_MALWARE = 0x0010 ;
public static final int FLAG_COMPAT_NO_ANSI = 0x0020 ;
public static final int FLAG_COMPAT_FORCE_ANSI = 0x0040 ;
public static final int FLAG_COMPAT_FORCE_HIDE = 0x0080 ;
public static final int FLAG_COMPAT_MMT_REBORN = 0x0100 ;
public static final int FLAG_COMPAT_NO_EXT = 0x0002 ;
public static final int FLAG_COMPAT_MAGISK_CMD = 0x0004 ;
public static final int FLAG_COMPAT_NEED_32BIT = 0x0008 ;
public static final int FLAG_COMPAT_MALWARE = 0x0010 ;
public static final int FLAG_COMPAT_NO_ANSI = 0x0020 ;
public static final int FLAG_COMPAT_FORCE_ANSI = 0x0040 ;
public static final int FLAG_COMPAT_FORCE_HIDE = 0x0080 ;
public static final int FLAG_COMPAT_MMT_REBORN = 0x0100 ;
public static final int FLAG_COMPAT_ZIP_WRAPPER = 0x0200 ;
private static final String TAG = "AppUpdateManager" ;
private static final AppUpdateManager INSTANCE = new AppUpdateManager ( ) ;
private static final String RELEASES_API_URL =
"https://api.github.com/repos/Fox2Code/FoxMagiskModuleManager/releases" ;
private static final String COMPAT_API_URL =
"https://api.github.com/repos/Fox2Code/FoxMagiskModuleManager/issues/4" ;
public static AppUpdateManager getAppUpdateManager ( ) {
return INSTANCE ;
}
private static final String RELEASES_API_URL = "https://api.github.com/repos/Fox2Code/FoxMagiskModuleManager/releases" ;
private static final String COMPAT_API_URL = "https://api.github.com/repos/Fox2Code/FoxMagiskModuleManager/issues/4" ;
private final HashMap < String , Integer > compatDataId = new HashMap < > ( ) ;
private final Object updateLock = new Object ( ) ;
private final File compatFile ;
@ -49,13 +42,10 @@ public class AppUpdateManager {
private long lastChecked ;
private boolean preReleaseNewer ;
private boolean lastCheckSuccess ;
private AppUpdateManager ( ) {
this . compatFile = new File ( MainApplication . getINSTANCE ( ) . getFilesDir ( ) , "compat.txt" ) ;
this . latestRelease = MainApplication . getBootSharedPreferences ( )
. getString ( "updater_latest_release" , BuildConfig . VERSION_NAME ) ;
this . latestPreRelease = MainApplication . getBootSharedPreferences ( )
. getString ( "updater_latest_pre_release" , BuildConfig . VERSION_NAME ) ;
this . latestRelease = MainApplication . getBootSharedPreferences ( ) . getString ( "updater_latest_release" , BuildConfig . VERSION_NAME ) ;
this . latestPreRelease = MainApplication . getBootSharedPreferences ( ) . getString ( "updater_latest_pre_release" , BuildConfig . VERSION_NAME ) ;
this . lastChecked = 0 ;
this . preReleaseNewer = true ;
if ( this . compatFile . isFile ( ) ) {
@ -67,24 +57,34 @@ public class AppUpdateManager {
}
}
public static AppUpdateManager getAppUpdateManager ( ) {
return INSTANCE ;
}
public static int getFlagsForModule ( String moduleId ) {
return INSTANCE . getCompatibilityFlags ( moduleId ) ;
}
public static boolean shouldForceHide ( String repoId ) {
if ( BuildConfig . DEBUG | | repoId . startsWith ( "repo_" ) | | repoId . equals ( "magisk_alt_repo" ) )
return false ;
return ! repoId . startsWith ( "repo_" ) & & ( INSTANCE . getCompatibilityFlags ( repoId ) & FLAG_COMPAT_FORCE_HIDE ) ! = 0 ;
}
// Return true if should show a notification
public boolean checkUpdate ( boolean force ) {
if ( ! BuildConfig . ENABLE_AUTO_UPDATER )
return false ;
if ( ! force & & this . peekShouldUpdate ( ) )
return true ;
if ( ! BuildConfig . ENABLE_AUTO_UPDATER ) return false ;
if ( ! force & & this . peekShouldUpdate ( ) ) return true ;
long lastChecked = this . lastChecked ;
if ( lastChecked ! = 0 & &
// Avoid spam calls by putting a 60 seconds timer
lastChecked < System . currentTimeMillis ( ) - 60000L )
return force & & this . peekShouldUpdate ( ) ;
synchronized ( this . updateLock ) {
if ( lastChecked ! = this . lastChecked )
return this . peekShouldUpdate ( ) ;
if ( lastChecked ! = this . lastChecked ) return this . peekShouldUpdate ( ) ;
boolean preReleaseNewer = true ;
try {
JSONArray releases = new JSONArray ( new String ( Http . doHttpGet (
RELEASES_API_URL , false ) , StandardCharsets . UTF_8 ) ) ;
JSONArray releases = new JSONArray ( new String ( Http . doHttpGet ( RELEASES_API_URL , false ) , StandardCharsets . UTF_8 ) ) ;
String latestRelease = null , latestPreRelease = null ;
for ( int i = 0 ; i < releases . length ( ) ; i + + ) {
JSONObject release = releases . getJSONObject ( i ) ;
@ -92,22 +92,18 @@ public class AppUpdateManager {
if ( release . getBoolean ( "draft" ) ) continue ;
boolean preRelease = release . getBoolean ( "prerelease" ) ;
String version = release . getString ( "tag_name" ) ;
if ( version . startsWith ( "v" ) )
version = version . substring ( 1 ) ;
if ( version . startsWith ( "v" ) ) version = version . substring ( 1 ) ;
if ( preRelease ) {
if ( latestPreRelease = = null )
latestPreRelease = version ;
if ( latestPreRelease = = null ) latestPreRelease = version ;
} else if ( latestRelease = = null ) {
latestRelease = version ;
if ( latestPreRelease = = null )
preReleaseNewer = false ;
if ( latestPreRelease = = null ) preReleaseNewer = false ;
}
if ( latestRelease ! = null & & latestPreRelease ! = null ) {
break ; // We read everything we needed to read.
}
}
if ( latestRelease ! = null )
this . latestRelease = latestRelease ;
if ( latestRelease ! = null ) this . latestRelease = latestRelease ;
if ( latestPreRelease ! = null ) {
this . latestPreRelease = latestPreRelease ;
this . preReleaseNewer = preReleaseNewer ;
@ -131,45 +127,42 @@ public class AppUpdateManager {
public void checkUpdateCompat ( ) {
if ( this . compatFile . exists ( ) ) {
long lastUpdate = this . compatFile . lastModified ( ) ;
if ( lastUpdate < = System . currentTimeMillis ( ) & &
lastUpdate + 600_000L > System . currentTimeMillis ( ) ) {
if ( lastUpdate < = System . currentTimeMillis ( ) & & lastUpdate + 600_000L > System . currentTimeMillis ( ) ) {
return ; // Skip update
}
}
try {
JSONObject object = new JSONObject ( new String ( Http . doHttpGet (
COMPAT_API_URL , false ) , StandardCharsets . UTF_8 ) ) ;
JSONObject object = new JSONObject ( new String ( Http . doHttpGet ( COMPAT_API_URL , false ) , StandardCharsets . UTF_8 ) ) ;
if ( object . isNull ( "body" ) ) {
compatDataId . clear ( ) ;
Files . write ( compatFile , new byte [ 0 ] ) ;
return ;
}
byte [ ] rawData = object . getString ( "body" )
. getBytes ( StandardCharsets . UTF_8 ) ;
byte [ ] rawData = object . getString ( "body" ) . getBytes ( StandardCharsets . UTF_8 ) ;
this . parseCompatibilityFlags ( new ByteArrayInputStream ( rawData ) ) ;
Files . write ( compatFile , rawData ) ;
if ( ! BuildConfig . ENABLE_AUTO_UPDATER )
this . lastCheckSuccess = true ;
if ( ! BuildConfig . ENABLE_AUTO_UPDATER ) this . lastCheckSuccess = true ;
} catch ( Exception e ) {
if ( ! BuildConfig . ENABLE_AUTO_UPDATER )
this . lastCheckSuccess = false ;
if ( ! BuildConfig . ENABLE_AUTO_UPDATER ) this . lastCheckSuccess = false ;
Log . e ( "AppUpdateManager" , "Failed to update compat list" , e ) ;
}
}
public boolean peekShouldUpdate ( ) {
if ( ! BuildConfig . ENABLE_AUTO_UPDATER )
return false ;
return ! ( BuildConfig . VERSION_NAME . equals ( this . latestRelease ) | |
( this . preReleaseNewer & &
BuildConfig . VERSION_NAME . equals ( this . latestPreRelease ) ) ) ;
if ( ! BuildConfig . ENABLE_AUTO_UPDATER ) return false ;
// Convert both BuildConfig.VERSION_NAME and latestRelease to int
int currentVersion = 0 , latestVersion = 0 ;
try {
currentVersion = Integer . parseInt ( BuildConfig . VERSION_NAME . replace ( "." , "" ) ) ;
latestVersion = Integer . parseInt ( this . latestRelease . replace ( "." , "" ) ) ;
} catch ( NumberFormatException ignored ) {
}
return currentVersion < latestVersion | | ( this . preReleaseNewer & & currentVersion < Integer . parseInt ( this . latestPreRelease . replace ( "." , "" ) ) ) ;
}
public boolean peekHasUpdate ( ) {
if ( ! BuildConfig . ENABLE_AUTO_UPDATER )
return false ;
return ! BuildConfig . VERSION_NAME . equals ( this . preReleaseNewer ?
this . latestPreRelease : this . latestRelease ) ;
if ( ! BuildConfig . ENABLE_AUTO_UPDATER ) return false ;
return ! BuildConfig . VERSION_NAME . equals ( this . preReleaseNewer ? this . latestPreRelease : this . latestRelease ) ;
}
public boolean isLastCheckSuccess ( ) {
@ -178,8 +171,7 @@ public class AppUpdateManager {
private void parseCompatibilityFlags ( InputStream inputStream ) throws IOException {
compatDataId . clear ( ) ;
BufferedReader bufferedReader = new BufferedReader (
new InputStreamReader ( inputStream , StandardCharsets . UTF_8 ) ) ;
BufferedReader bufferedReader = new BufferedReader ( new InputStreamReader ( inputStream , StandardCharsets . UTF_8 ) ) ;
String line ;
while ( ( line = bufferedReader . readLine ( ) ) ! = null ) {
line = line . trim ( ) ;
@ -231,16 +223,4 @@ public class AppUpdateManager {
Integer compatFlags = compatDataId . get ( moduleId ) ;
return compatFlags = = null ? 0 : compatFlags ;
}
public static int getFlagsForModule ( String moduleId ) {
return INSTANCE . getCompatibilityFlags ( moduleId ) ;
}
public static boolean shouldForceHide ( String repoId ) {
if ( BuildConfig . DEBUG | | repoId . startsWith ( "repo_" ) | |
repoId . equals ( "magisk_alt_repo" ) ) return false ;
return ! repoId . startsWith ( "repo_" ) & &
( INSTANCE . getCompatibilityFlags ( repoId ) &
FLAG_COMPAT_FORCE_HIDE ) ! = 0 ;
}
}