33import android .annotation .SuppressLint ;
44import android .app .AlarmManager ;
55import android .app .PendingIntent ;
6+ import android .app .ProgressDialog ;
67import android .content .Context ;
78import android .content .Intent ;
89import android .content .SharedPreferences ;
3637import com .fox2code .mmm .MainActivity ;
3738import com .fox2code .mmm .MainApplication ;
3839import com .fox2code .mmm .R ;
40+ import com .fox2code .mmm .androidacy .AndroidacyRepoData ;
3941import com .fox2code .mmm .background .BackgroundUpdateChecker ;
4042import com .fox2code .mmm .installer .InstallerInitializer ;
4143import com .fox2code .mmm .module .ActionButtonType ;
5355import com .mikepenz .aboutlibraries .LibsBuilder ;
5456import com .topjohnwu .superuser .internal .UiThreadHandler ;
5557
56- import org .jetbrains .annotations .NotNull ;
5758import org .json .JSONException ;
5859
5960import java .io .IOException ;
6061import java .util .HashSet ;
6162import java .util .Objects ;
6263import java .util .Random ;
6364
64- import okhttp3 .Call ;
65- import okhttp3 .Callback ;
66- import okhttp3 .OkHttpClient ;
67- import okhttp3 .Request ;
68- import okhttp3 .Response ;
69-
7065public class SettingsActivity extends FoxActivity implements LanguageActivity {
7166 private static final int LANGUAGE_SUPPORT_LEVEL = 1 ;
7267 private static final String TAG = "SettingsActivity" ;
@@ -96,7 +91,7 @@ public void refreshRosettaX() {
9691 int mPendingIntentId = 123456 ;
9792 PendingIntent mPendingIntent = PendingIntent .getActivity (this , mPendingIntentId ,
9893 mStartActivity , PendingIntent .FLAG_CANCEL_CURRENT | PendingIntent .FLAG_IMMUTABLE );
99- AlarmManager mgr = (AlarmManager )this .getSystemService (Context .ALARM_SERVICE );
94+ AlarmManager mgr = (AlarmManager ) this .getSystemService (Context .ALARM_SERVICE );
10095 mgr .set (AlarmManager .RTC , System .currentTimeMillis () + 100 , mPendingIntent );
10196 System .exit (0 ); // Exit app process
10297 }
@@ -280,51 +275,6 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
280275 "https://github.com/Fox2Code/FoxMagiskModuleManager" );
281276 return true ;
282277 });
283- // Create the pref_androidacy_repo_api_key text input
284- EditTextPreference prefAndroidacyRepoApiKey = new EditTextPreference (this .requireContext ());
285- prefAndroidacyRepoApiKey .setKey ("pref_androidacy_repo_api_key" );
286- prefAndroidacyRepoApiKey .setTitle (R .string .api_key );
287- prefAndroidacyRepoApiKey .setDialogTitle (R .string .api_key );
288- // Set the summary to the current androidacy_api_token
289- prefAndroidacyRepoApiKey .setSummary (MainApplication .getSharedPreferences ()
290- .getString ("androidacy_api_token" , "" ));
291- // On user input, save the new androidacy_api_token after validating it
292- prefAndroidacyRepoApiKey .setOnPreferenceChangeListener ((preference , newValue ) -> {
293- String newToken = String .valueOf (newValue );
294- if (newToken .length () == 0 ) {
295- MainApplication .getSharedPreferences ().edit ()
296- .remove ("androidacy_api_token" ).apply ();
297- return true ;
298- }
299- // Call the androidacy api to validate the token
300- OkHttpClient client = new OkHttpClient ();
301- Request request = new Request .Builder ()
302- .url ("https://production-api.androidacy.com/auth/me" )
303- .header ("Authorization" , "Bearer " + newToken )
304- .build ();
305- client .newCall (request ).enqueue (new Callback () {
306- @ Override
307- public void onFailure (@ NotNull Call call , @ NotNull IOException e ) {
308- // If the request failed, show an error message
309- new Handler (Looper .getMainLooper ()).post (() -> {
310- Toast .makeText (getContext (), R .string .api_key_invalid ,
311- Toast .LENGTH_SHORT ).show ();
312- });
313- }
314-
315- @ Override
316- public void onResponse (@ NotNull Call call , @ NotNull Response response ) {
317- // If the request succeeded, save the token
318- new Handler (Looper .getMainLooper ()).post (() -> {
319- MainApplication .getSharedPreferences ().edit ()
320- .putString ("androidacy_api_token" , newToken ).apply ();
321- Toast .makeText (getContext (), R .string .api_key_valid ,
322- Toast .LENGTH_SHORT ).show ();
323- });
324- }
325- });
326- return true ;
327- });
328278 findPreference ("pref_support" ).setOnPreferenceClickListener (p -> {
329279 devModeStep = 0 ;
330280 IntentHelper .openUrl (p .getContext (), "https://t.me/Fox2Code_Chat" );
@@ -342,7 +292,8 @@ public void onResponse(@NotNull Call call, @NotNull Response response) {
342292 BuildConfig .VERSION_CODE + ")" );
343293 }
344294
345- private SharedPreferences .Editor getCrashReportingEditor (FragmentActivity requireActivity ) {
295+ private SharedPreferences .Editor getCrashReportingEditor (FragmentActivity
296+ requireActivity ) {
346297 return requireActivity .getSharedPreferences ("crash_reporting" , Context .MODE_PRIVATE ).edit ();
347298 }
348299
@@ -398,6 +349,73 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
398349 Objects .requireNonNull ((Preference ) findPreference (
399350 "pref_androidacy_test_mode" )).setVisible (false );
400351 }
352+ String originalApiKey = MainApplication .getSharedPreferences ()
353+ .getString ("pref_androidacy_api_token" , "" );
354+ // Create the pref_androidacy_repo_api_key text input with validation
355+ EditTextPreference prefAndroidacyRepoApiKey = findPreference ("pref_androidacy_repo_api_key" );
356+ prefAndroidacyRepoApiKey .setKey ("pref_androidacy_repo_api_key" );
357+ prefAndroidacyRepoApiKey .setOnBindEditTextListener (editText -> {
358+ editText .setSingleLine ();
359+ // Make the single line wrap
360+ editText .setHorizontallyScrolling (false );
361+ // Set the height to the height of 2 lines
362+ editText .setHeight (editText .getLineHeight () * 2 );
363+ });
364+ prefAndroidacyRepoApiKey .setOnPreferenceChangeListener ((preference , newValue ) -> {
365+ // Curious if this actually works - so crash the app on purpose
366+ // throw new RuntimeException("This is a test crash");
367+ // get original api key
368+ String apiKey = String .valueOf (newValue );
369+ // Show progress dialog
370+ ProgressDialog progressDialog = new ProgressDialog (getContext ());
371+ progressDialog .setMessage (getString (R .string .checking_api_key ));
372+ progressDialog .setCancelable (false );
373+ progressDialog .show ();
374+ // Check the API key on a background thread
375+ new Thread (() -> {
376+ // If key is empty, just remove it and show a toast
377+ if (apiKey .isEmpty ()) {
378+ MainApplication .getSharedPreferences ().edit ()
379+ .remove ("pref_androidacy_repo_api_key" ).apply ();
380+ new Handler (Looper .getMainLooper ()).post (() -> {
381+ progressDialog .dismiss ();
382+ Toast .makeText (getContext (), R .string .api_key_removed , Toast .LENGTH_SHORT ).show ();
383+ });
384+ return ;
385+ } else {
386+ // If key < 64 chars, it's not valid
387+ if (apiKey .length () < 64 ) {
388+ new Handler (Looper .getMainLooper ()).post (() -> {
389+ progressDialog .dismiss ();
390+ Toast .makeText (getContext (), R .string .api_key_invalid , Toast .LENGTH_SHORT ).show ();
391+ });
392+ return ;
393+ }
394+ }
395+ // Check the API key
396+ boolean valid = AndroidacyRepoData .getInstance ().isValidToken (apiKey );
397+ // Update the UI on the main thread
398+ new Handler (Looper .getMainLooper ()).post (() -> {
399+ progressDialog .dismiss ();
400+ if (valid ) {
401+ // Show a success message
402+ Toast .makeText (getContext (), R .string .api_key_valid ,
403+ Toast .LENGTH_SHORT ).show ();
404+ // Save the API key
405+ MainApplication .getSharedPreferences ().edit ()
406+ .putString ("pref_androidacy_api_token" , apiKey ).apply ();
407+ } else {
408+ // Show an error message
409+ Toast .makeText (getContext (), R .string .api_key_invalid ,
410+ Toast .LENGTH_SHORT ).show ();
411+ // Restore the original API key
412+ MainApplication .getSharedPreferences ().edit ()
413+ .putString ("pref_androidacy_api_token" , originalApiKey ).apply ();
414+ }
415+ });
416+ }).start ();
417+ return true ;
418+ });
401419 }
402420
403421 @ SuppressLint ("RestrictedApi" )
@@ -411,7 +429,7 @@ public void updateCustomRepoList(boolean initial) {
411429 setRepoData (repoData , "pref_custom_repo_" + i );
412430 if (initial ) {
413431 Preference preference =
414- findPreference ("pref_custom_repo_" + i + "_delete" );
432+ findPreference ("pref_custom_repo_" + i + "_delete" );
415433 if (preference == null ) continue ;
416434 final int index = i ;
417435 preference .setOnPreferenceClickListener (preference1 -> {
@@ -450,7 +468,7 @@ public void updateCustomRepoList(boolean initial) {
450468 public void run () {
451469 try {
452470 customRepoData .quickPrePopulate ();
453- } catch (IOException | JSONException e ) {
471+ } catch (IOException | JSONException e ) {
454472 Log .e (TAG , "Failed to preload repo values" , e );
455473 }
456474 UiThreadHandler .handler .post (() -> updateCustomRepoList (false ));
0 commit comments