11package com .fox2code .mmm .androidacy ;
22
3+ import android .annotation .SuppressLint ;
4+ import android .content .Intent ;
35import android .content .SharedPreferences ;
4- import android .os . Looper ;
6+ import android .net . Uri ;
57import android .util .Log ;
68import android .widget .Toast ;
79
2628
2729import java .io .File ;
2830import java .io .IOException ;
31+ import java .net .HttpURLConnection ;
32+ import java .net .URL ;
2933import java .security .MessageDigest ;
3034import java .security .NoSuchAlgorithmException ;
3135import java .util .ArrayList ;
@@ -64,7 +68,8 @@ public AndroidacyRepoData(File cacheRoot, SharedPreferences cachedPreferences, b
6468 if (!modulesJson .createNewFile ()) {
6569 throw new IOException ("Failed to create modules.json" );
6670 }
67- } catch (IOException e ) {
71+ } catch (
72+ IOException e ) {
6873 e .printStackTrace ();
6974 }
7075 }
@@ -144,7 +149,8 @@ public boolean isValidToken(String token) throws IOException, NoSuchAlgorithmExc
144149 String deviceId = generateDeviceId ();
145150 try {
146151 Http .doHttpGet ("https://" + this .host + "/auth/me?token=" + token + "&device_id=" + deviceId , false );
147- } catch (HttpException e ) {
152+ } catch (
153+ HttpException e ) {
148154 if (e .getErrorCode () == 401 ) {
149155 Log .w (TAG , "Invalid token, resetting..." );
150156 // Remove saved preference
@@ -159,6 +165,7 @@ public boolean isValidToken(String token) throws IOException, NoSuchAlgorithmExc
159165 return true ;
160166 }
161167
168+ @ SuppressLint ("RestrictedApi" )
162169 @ Override
163170 protected boolean prepare () throws NoSuchAlgorithmException {
164171 // If ANDROIDACY_CLIENT_ID is not set or is empty, disable this repo and return
@@ -168,28 +175,44 @@ protected boolean prepare() throws NoSuchAlgorithmException {
168175 editor .apply ();
169176 return false ;
170177 }
171- if (Http .needCaptchaAndroidacy ()) return false ;
178+ if (Http .needCaptchaAndroidacy ())
179+ return false ;
172180 // Implementation details discussed on telegram
173181 // First, ping the server to check if it's alive
174182 try {
175- Http .doHttpGet ("https://" + this .host + "/ping" , false );
176- } catch (Exception e ) {
183+ HttpURLConnection connection = (HttpURLConnection ) new URL ("https://" + this .host + "/ping" ).openConnection ();
184+ connection .setRequestMethod ("GET" );
185+ connection .setConnectTimeout (5000 );
186+ connection .setReadTimeout (5000 );
187+ connection .connect ();
188+ if (connection .getResponseCode () != 200 && connection .getResponseCode () != 204 ) {
189+ // If it's a 400, the app is probably outdated. Show a snackbar suggesting user update app and webview
190+ if (connection .getResponseCode () == 400 ) {
191+ // Show a dialog using androidacy_update_needed string
192+ new MaterialAlertDialogBuilder (MainApplication .getINSTANCE ())
193+ .setTitle (R .string .androidacy_update_needed )
194+ .setMessage (R .string .androidacy_update_needed_message )
195+ .setPositiveButton (R .string .update , (dialog , which ) -> {
196+ // Open the app's page on the Play Store
197+ Intent intent = new Intent (Intent .ACTION_VIEW );
198+ intent .setData (Uri .parse ("https://github.com/Fox2Code/FoxMagiskModuleManager/releases/latest" ));
199+ intent .setFlags (Intent .FLAG_ACTIVITY_NEW_TASK );
200+ MainApplication .getINSTANCE ().startActivity (intent );
201+ })
202+ .setNegativeButton (R .string .cancel , null )
203+ .show ();
204+ }
205+ return false ;
206+ }
207+ } catch (
208+ Exception e ) {
177209 Log .e (TAG , "Failed to ping server" , e );
178- // Inform user
179- Looper .prepare ();
180- MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder (MainApplication .getINSTANCE ().getBaseContext ());
181- builder .setTitle ("Androidacy Server Down" );
182- builder .setMessage ("The Androidacy server is down. Unfortunately, this means that you" +
183- " will not be able to download or view modules from the Androidacy repository" +
184- ". Please try again later." );
185- builder .setPositiveButton ("OK" , (dialog , which ) -> dialog .dismiss ());
186- builder .show ();
187- Looper .loop ();
188210 return false ;
189211 }
190212 String deviceId = generateDeviceId ();
191213 long time = System .currentTimeMillis ();
192- if (this .androidacyBlockade > time ) return true ; // fake it till you make it. Basically,
214+ if (this .androidacyBlockade > time )
215+ return true ; // fake it till you make it. Basically,
193216 // don'e fail just becaue we're rate limited. API and web rate limits are different.
194217 this .androidacyBlockade = time + 30_000L ;
195218 try {
@@ -206,7 +229,8 @@ protected boolean prepare() throws NoSuchAlgorithmException {
206229 }
207230 this .token = null ;
208231 }
209- } catch (IOException e ) {
232+ } catch (
233+ IOException e ) {
210234 if (HttpException .shouldTimeout (e )) {
211235 Log .e (TAG , "We are being rate limited!" , e );
212236 this .androidacyBlockade = time + 3_600_000L ;
@@ -222,7 +246,8 @@ protected boolean prepare() throws NoSuchAlgorithmException {
222246 try {
223247 JSONObject jsonObject = new JSONObject (token );
224248 token = jsonObject .getString ("token" );
225- } catch (JSONException e ) {
249+ } catch (
250+ JSONException e ) {
226251 Log .e (TAG , "Failed to parse token" , e );
227252 // Show a toast
228253 Toast .makeText (MainApplication .getINSTANCE (), R .string .androidacy_failed_to_parse_token , Toast .LENGTH_LONG ).show ();
@@ -239,7 +264,8 @@ protected boolean prepare() throws NoSuchAlgorithmException {
239264 SharedPreferences .Editor editor = MainApplication .getINSTANCE ().getSharedPreferences ("androidacy" , 0 ).edit ();
240265 editor .putString ("pref_androidacy_api_token" , token );
241266 editor .apply ();
242- } catch (Exception e ) {
267+ } catch (
268+ Exception e ) {
243269 if (HttpException .shouldTimeout (e )) {
244270 Log .e (TAG , "We are being rate limited!" , e );
245271 this .androidacyBlockade = time + 3_600_000L ;
@@ -324,7 +350,8 @@ protected List<RepoModule> populate(JSONObject jsonObject) throws JSONException,
324350 moduleInfo .minMagisk = // Allow 24.1 to mean 24100
325351 (Integer .parseInt (minMagisk .substring (0 , c )) * 1000 ) + (Integer .parseInt (minMagisk .substring (c + 1 )) * 100 );
326352 }
327- } catch (Exception e ) {
353+ } catch (
354+ Exception e ) {
328355 moduleInfo .minMagisk = 0 ;
329356 }
330357 moduleInfo .needRamdisk = jsonObject .optBoolean ("needRamdisk" , false );
@@ -370,13 +397,13 @@ public boolean tryLoadMetadata(RepoModule repoModule) {
370397
371398 @ Override
372399 public String getUrl () throws NoSuchAlgorithmException {
373- return this .token == null ? this .url :
374- this .url + "?token=" + this .token + "&v=" + BuildConfig .VERSION_CODE + "&c=" + BuildConfig .VERSION_NAME + "&device_id=" + generateDeviceId ();
400+ return this .token == null ? this .url : this .url + "?token=" + this .token + "&v=" + BuildConfig .VERSION_CODE + "&c=" + BuildConfig .VERSION_NAME + "&device_id=" + generateDeviceId ();
375401 }
376402
377403 private String injectToken (String url ) throws NoSuchAlgorithmException {
378404 // Do not inject token for non Androidacy urls
379- if (!AndroidacyUtil .isAndroidacyLink (url )) return url ;
405+ if (!AndroidacyUtil .isAndroidacyLink (url ))
406+ return url ;
380407 if (this .testMode ) {
381408 if (url .startsWith ("https://production-api.androidacy.com/" )) {
382409 Log .e (TAG , "Got non test mode url: " + AndroidacyUtil .hideToken (url ));
0 commit comments