[insert awesome commit message here]

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/284/head
androidacy-user 1 year ago
parent 837cd46ce3
commit b5389d597c

@ -9,6 +9,7 @@ import android.widget.EditText;
import android.widget.Toast;
import com.fox2code.foxcompat.app.FoxActivity;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textview.MaterialTextView;
import org.json.JSONException;
@ -151,6 +152,21 @@ public class CrashHandler extends FoxActivity {
startActivity(getPackageManager().getLaunchIntentForPackage(getPackageName()));
});
}
// handle reset button
findViewById(R.id.reset).setOnClickListener(v -> {
// show a confirmation material dialog
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(R.string.reset_app);
builder.setMessage(R.string.reset_app_confirmation);
builder.setPositiveButton(R.string.reset, (dialog, which) -> {
// reset the app
MainApplication.getINSTANCE().resetApp();
});
builder.setNegativeButton(R.string.cancel, (dialog, which) -> {
// do nothing
});
builder.show();
});
}
public void copyCrashDetails(View view) {

@ -447,65 +447,27 @@ public class MainApplication extends FoxApplication implements androidx.work.Con
}
}
public void clearAppData() {
// Clear app data
try {
// Clearing app data
// We have to manually delete the files and directories
// because the cache directory is not cleared by the following method
File cacheDir;
cacheDir = this.getDataDir();
if (cacheDir != null && cacheDir.isDirectory()) {
String[] children = cacheDir.list();
if (children != null) {
for (String s : children) {
if (BuildConfig.DEBUG)
Timber.w("Deleting %s", s);
if (!s.equals("lib")) {
if (!new File(cacheDir, s).delete()) {
if (BuildConfig.DEBUG)
Timber.w("Failed to delete %s", s);
}
}
}
}
}
if (BuildConfig.DEBUG)
Timber.w("Deleting cache dir");
this.deleteSharedPreferences("mmm_boot");
this.deleteSharedPreferences("mmm");
this.deleteSharedPreferences("sentry");
this.deleteSharedPreferences("androidacy");
if (BuildConfig.DEBUG)
Timber.w("Deleting shared prefs");
this.getPackageManager().clearPackagePreferredActivities(this.getPackageName());
if (BuildConfig.DEBUG)
Timber.w("Done clearing app data");
} catch (
Exception e) {
Timber.e(e);
}
@SuppressLint("RestrictedApi")
// view is nullable because it's called from xml
public void resetApp() {
// cant show a dialog because android is throwing a fit so heres hoping anybody who calls this method is otherwise confirming that the user wants to reset the app
Timber.w("Resetting app...");
// recursively delete the app's data
((ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE)).clearApplicationUserData();
}
public boolean isInForeground() {
// determine if the app is in the foreground
ActivityManager activityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
if (activityManager != null) {
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses != null) {
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
for (String activeProcess : appProcess.pkgList) {
if (activeProcess.equals(this.getPackageName())) {
return true;
}
}
return false;
}
}
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses == null) {
return false;
}
final String packageName = this.getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
return true;
}
} else {
Timber.e("Failed to get activity manager");
}
return false;
}

@ -74,10 +74,7 @@ public class SetupActivity extends FoxActivity implements LanguageActivity {
ActivitySetupBinding binding = ActivitySetupBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// Show setup box. Put the setup_box in the main activity layout
View view = binding.setupBox;
// Make the setup_box linear layout the sole child of the root_container constraint layout
setContentView(view);
View view = binding.getRoot();
((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_background_update_check))).setChecked(BuildConfig.ENABLE_AUTO_UPDATER);
((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_crash_reporting))).setChecked(BuildConfig.DEFAULT_ENABLE_CRASH_REPORTING);
// assert that both switches match the build config on debug builds
@ -276,13 +273,11 @@ public class SetupActivity extends FoxActivity implements LanguageActivity {
Timber.d("Creating Realm databases");
// create the realm database for ReposList
// next, create the realm database for ReposList
RealmConfiguration config2 = new RealmConfiguration.Builder().name("ReposList.realm").directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build();
RealmConfiguration config2 = new RealmConfiguration.Builder().name("ReposList.realm").allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build();
// get the instance
Realm.getInstanceAsync(config2, new Realm.Callback() {
@Override
public void onSuccess(@NonNull Realm realm1) {
// drop the database if it exists
realm1.executeTransactionAsync(realm2 -> realm2.delete(ReposList.class));
// create androidacy_repo and magisk_alt_repo if they don't exist under ReposList
// each has id, name, donate, website, support, enabled, and lastUpdate and name
// create androidacy_repo

@ -41,6 +41,7 @@ import timber.log.Timber;
@SuppressWarnings("KotlinInternalInJava")
public final class AndroidacyRepoData extends RepoData {
public String[][] userInfo = new String[][]{{"role", null}, {"permissions", null}};
public static String token = MainApplication.getINSTANCE().getSharedPreferences("androidacy", 0).getString("pref_androidacy_api_token", null);
@ -140,6 +141,9 @@ public final class AndroidacyRepoData extends RepoData {
byte[] resp = Http.doHttpGet("https://" + this.host + "/auth/me?token=" + token + "&device_id=" + deviceId, false);
JSONObject jsonObject = new JSONObject(new String(resp));
memberLevel = jsonObject.getString("role");
JSONArray memberPermissions = jsonObject.getJSONArray("permissions");
// set role and permissions on userInfo property
userInfo = new String[][]{{"role", memberLevel}, {"permissions", String.valueOf(memberPermissions)}};
String status = jsonObject.getString("status");
if (status.equals("success")) {
return true;

@ -105,14 +105,16 @@ public class RepoData extends XRepo {
this.defaultName = url; // Set url as default name
this.forceHide = AppUpdateManager.shouldForceHide(this.id);
// this.enable is set from the database
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder()
.name("ReposList.realm")
.schemaVersion(1)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build();
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().name("ReposList.realm").allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build();
Realm realm = Realm.getInstance(realmConfiguration);
ReposList reposList = realm.where(ReposList.class).equalTo("id", this.id).findFirst();
if (BuildConfig.DEBUG) {
if (reposList == null) {
Timber.d("RepoData for %s not found in database", this.id);
} else {
Timber.d("RepoData for %s found in database", this.id);
}
}
Timber.d("RepoData: " + this.id + ". record in database: " + (reposList != null ? reposList.toString() : "none"));
this.enabled = (!this.forceHide && reposList != null && reposList.isEnabled());
this.defaultWebsite = "https://" + Uri.parse(url).getHost() + "/";
@ -140,6 +142,7 @@ public class RepoData extends XRepo {
Timber.w("Failed to load repo metadata from database: " + e.getMessage() + ". If this is a first time run, this is normal.");
}
}
realm.close();
}
private static boolean isNonNull(String str) {

@ -409,7 +409,7 @@ public final class RepoManager extends SyncManager {
private AndroidacyRepoData addAndroidacyRepoData() {
// cache dir is actually under app data
File cacheRoot = new File(this.mainApplication.getDataDir(), "repos/androidacy_repo");
File cacheRoot = this.mainApplication.getDataDirWithPath("realms/repos/androidacy_repo");
SharedPreferences sharedPreferences = this.mainApplication.getSharedPreferences("mmm_androidacy_repo", Context.MODE_PRIVATE);
AndroidacyRepoData repoData = new AndroidacyRepoData(cacheRoot, sharedPreferences, MainApplication.isAndroidacyTestMode());
this.repoData.put(ANDROIDACY_MAGISK_REPO_ENDPOINT, repoData);

@ -54,11 +54,7 @@ public class RepoUpdater {
Realm realm = Realm.getInstance(realmConfiguration);
RealmResults<ModuleListCache> results = realm.where(ModuleListCache.class).equalTo("repoId", this.repoData.id).findAll();
// reposlist realm
RealmConfiguration realmConfiguration2 = new RealmConfiguration.Builder()
.name("ReposList.realm")
.schemaVersion(1)
.modules(new ReposList())
.build();
RealmConfiguration realmConfiguration2 = new RealmConfiguration.Builder().name("ReposList.realm").allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build();
Realm realm2 = Realm.getInstance(realmConfiguration2);
ReposList reposList = realm2.where(ReposList.class).equalTo("id", this.repoData.id).findFirst();
this.toUpdate = Collections.emptyList();

@ -86,6 +86,7 @@ import java.util.Random;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.RealmResults;
import timber.log.Timber;
public class SettingsActivity extends FoxActivity implements LanguageActivity {
@ -383,9 +384,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
// Clear app data
new MaterialAlertDialogBuilder(requireContext()).setTitle(R.string.clear_data_dialogue_title).setMessage(R.string.clear_data_dialogue_message).setPositiveButton(R.string.yes, (dialog, which) -> {
// Clear app data
MainApplication.getINSTANCE().clearAppData();
// Restart app
ProcessHelper.restartApplicationProcess(requireContext());
MainApplication.getINSTANCE().resetApp();
}).setNegativeButton(R.string.no, (dialog, which) -> {
}).show();
return true;
@ -787,9 +786,32 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().name("ReposList.realm").allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build();
Realm realm = Realm.getInstance(realmConfiguration);
ReposList repoRealmResults = realm.where(ReposList.class).equalTo("id", "androidacy_repo").findFirst();
assert repoRealmResults != null;
if (repoRealmResults == null) {
// log the entries in the realm db and throw an illegal state exception
RealmResults<ReposList> reposListRealmResults = realm.where(ReposList.class).findAll();
if (reposListRealmResults.isEmpty()) {
throw new IllegalStateException("Realm db is empty");
}
for (ReposList reposList2 : reposListRealmResults) {
Timber.d("Realm db entry: %s %s %s", reposList2.getId(), reposList2.getName(), reposList2.isEnabled());
}
throw new IllegalStateException("Androidacy repo not found in realm db");
}
boolean androidacyRepoEnabledPref = repoRealmResults.isEnabled();
if (androidacyRepoEnabledPref) {
// get user role from AndroidacyRepoData.userInfo
String[][] userInfo = AndroidacyRepoData.getInstance().userInfo;
if (userInfo != null) {
String userRole = userInfo[0][1];
if (!Objects.equals(userRole, "Guest")) {
// Disable the pref_androidacy_repo_api_token preference
LongClickablePreference prefAndroidacyRepoApiD = Objects.requireNonNull(findPreference("pref_androidacy_repo_donate"));
prefAndroidacyRepoApiD.setEnabled(false);
prefAndroidacyRepoApiD.setSummary(R.string.upgraded_summary);
prefAndroidacyRepoApiD.setTitle(R.string.upgraded);
prefAndroidacyRepoApiD.setIcon(R.drawable.baseline_check_24);
}
}
String[] originalApiKeyRef = new String[]{MainApplication.getINSTANCE().getSharedPreferences("androidacy", 0).getString("pref_androidacy_api_token", "")};
// Get the dummy pref_androidacy_repo_api_token preference with id pref_androidacy_repo_api_token
// we have to use the id because the key is different
@ -913,7 +935,16 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
@SuppressLint("RestrictedApi")
public void updateCustomRepoList(boolean initial) {
final SharedPreferences sharedPreferences = Objects.requireNonNull(this.getPreferenceManager().getSharedPreferences());
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().name("ReposList.realm").allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build();
Realm realm = Realm.getInstance(realmConfiguration);
// get all repos that are not built-in
int CUSTOM_REPO_ENTRIES = 0;
RealmResults<ReposList> customRepoDataDB = realm.where(ReposList.class).findAll();
for (ReposList repo : customRepoDataDB) {
if (!repo.getId().equals("androidacy") && !repo.getId().equals("magisk_alt_repo")) {
CUSTOM_REPO_ENTRIES++;
}
}
final CustomRepoManager customRepoManager = RepoManager.getINSTANCE().getCustomRepoManager();
for (int i = 0; i < CUSTOM_REPO_ENTRIES; i++) {
CustomRepoData repoData = customRepoManager.getRepo(i);
@ -924,7 +955,9 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
continue;
final int index = i;
preference.setOnPreferenceClickListener(preference1 -> {
sharedPreferences.edit().remove("pref_custom_repo_" + index + "_enabled").apply();
realm.beginTransaction();
Objects.requireNonNull(realm.where(ReposList.class).equalTo("id", repoData.id).findFirst()).deleteFromRealm();
realm.commitTransaction();
customRepoManager.removeRepo(index);
updateCustomRepoList(false);
return true;
@ -939,6 +972,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
preference = findPreference("pref_custom_add_repo_button");
if (preference == null)
return;
int finalCUSTOM_REPO_ENTRIES = CUSTOM_REPO_ENTRIES;
preference.setOnPreferenceClickListener(preference1 -> {
final Context context = this.requireContext();
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
@ -984,7 +1018,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
input.addTextChangedListener(new TextWatcherAdapter() {
@Override
public void onTextChanged(@NonNull CharSequence charSequence, int i, int i1, int i2) {
positiveButton.setEnabled(customRepoManager.canAddRepo(charSequence.toString()) && customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES);
positiveButton.setEnabled(customRepoManager.canAddRepo(charSequence.toString()) && customRepoManager.getRepoCount() < finalCUSTOM_REPO_ENTRIES);
}
});
positiveButton.setEnabled(false);

@ -138,7 +138,20 @@
android:text="@string/restart" />
</LinearLayout>
</LinearLayout>
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10dp" android:gravity="fill" android:text="@string/reset_warning" android:textSize="16sp" />
<!-- reset app button -->
<com.google.android.material.button.MaterialButton
android:id="@+id/reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/reset_app" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>

@ -107,7 +107,7 @@
<string name="disable_low_quality_module_filter_pref">Show low-quality modules</string>
<string name="disable_low_quality_module_filter_desc">
Some modules do not declare their metadata properly, causing visual glitches,
and/or indicating poor module quality.\nTurn this off at your own risk!
and/or indicating poor module quality.\nTurn this on at your own risk!
</string>
<string name="dns_over_https_pref">DNS over HTTPS</string>
<string name="dns_over_https_desc">
@ -313,4 +313,8 @@
<string name="crash_details_copied">Copied stacktrace to clipboard!</string>
<string name="crash_full_stacktrace">Stacktrace:\n%1$s</string>
<string name="sentry_enable_nag">It looks like crash reporting is disabled. Please enable it to submit feedback.</string>
<string name="reset_app">Reset the app</string>
<string name="upgraded_summary">You\'re pretty awesome! Looks like you\'ve already upgraded your subscription and are supporting Androidacy.</string>
<string name="upgraded">Premium active</string>
<string name="reset_warning">If you keep seeing this screen, resetting the app might help. This will clear app data but will not effect installed modules.</string><string name="reset_app_message">This will completely remove all app data and close the app. Modules will not be uninstalled.</string><string name="reset">Reset</string><string name="reset_app_confirmation">This is going to completely wipe app data, but will not effect modules.</string>
</resources>

Loading…
Cancel
Save