panic: add destructive option to reset repos to defaults

This commit is contained in:
Hans-Christoph Steiner 2019-05-29 21:00:41 +02:00
parent 72f5398b79
commit 3b53af0657
9 changed files with 121 additions and 13 deletions

View File

@ -43,6 +43,7 @@ public class PanicPreferencesFragment extends PreferenceFragment
private ListPreference prefApp;
private CheckBoxPreference prefExit;
private CheckBoxPreference prefHide;
private CheckBoxPreference prefResetRepos;
private PreferenceCategory categoryAppsToUninstall;
@Override
@ -54,6 +55,7 @@ public class PanicPreferencesFragment extends PreferenceFragment
prefApp = (ListPreference) findPreference(PREF_APP);
prefHide = (CheckBoxPreference) findPreference(Preferences.PREF_PANIC_HIDE);
prefHide.setTitle(getString(R.string.panic_hide_title, getString(R.string.app_name)));
prefResetRepos = (CheckBoxPreference) findPreference(Preferences.PREF_PANIC_RESET_REPOS);
categoryAppsToUninstall = (PreferenceCategory) findPreference("pref_panic_apps_to_uninstall");
if (PanicResponder.checkForDisconnectIntent(getActivity())) {
@ -77,9 +79,12 @@ public class PanicPreferencesFragment extends PreferenceFragment
if (packageName.equals(Panic.PACKAGE_NAME_NONE)) {
prefHide.setChecked(false);
prefHide.setEnabled(false);
prefResetRepos.setChecked(false);
prefResetRepos.setEnabled(false);
getActivity().setResult(Activity.RESULT_CANCELED);
} else {
prefHide.setEnabled(true);
prefResetRepos.setEnabled(true);
}
showPanicApp(packageName);
return true;
@ -212,6 +217,7 @@ public class PanicPreferencesFragment extends PreferenceFragment
prefApp.setSummary(pm.getApplicationLabel(pm.getApplicationInfo(packageName, 0)));
prefApp.setIcon(pm.getApplicationIcon(packageName));
prefHide.setEnabled(true);
prefResetRepos.setEnabled(true);
showWipeList();
} catch (PackageManager.NameNotFoundException e) {
// revert back to no app, just to be safe
@ -293,6 +299,7 @@ public class PanicPreferencesFragment extends PreferenceFragment
@Override
public void onCancel(DialogInterface dialogInterface) {
prefHide.setChecked(false);
prefResetRepos.setChecked(false);
}
});
builder.setView(R.layout.dialog_app_hiding);

View File

@ -2,6 +2,7 @@ package org.fdroid.fdroid.views.panic;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
@ -13,8 +14,12 @@ import info.guardianproject.panic.Panic;
import info.guardianproject.panic.PanicResponder;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.DBHelper;
import org.fdroid.fdroid.data.InstalledApp;
import org.fdroid.fdroid.data.InstalledAppProvider;
import org.fdroid.fdroid.data.Repo;
import org.fdroid.fdroid.data.RepoProvider;
import org.fdroid.fdroid.data.Schema;
import org.fdroid.fdroid.installer.Installer;
import org.fdroid.fdroid.installer.InstallerService;
import org.fdroid.fdroid.installer.PrivilegedInstaller;
@ -22,6 +27,8 @@ import org.fdroid.fdroid.views.hiding.HidingManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@ -102,6 +109,9 @@ public class PanicResponderActivity extends AppCompatActivity {
// ignored
}
lbm.unregisterReceiver(receiver);
if (preferences.panicResetRepos()) {
resetRepos(context);
}
if (preferences.panicHide()) {
HidingManager.hide(context);
}
@ -111,6 +121,9 @@ public class PanicResponderActivity extends AppCompatActivity {
}
}.start();
} else if (receivedTriggerFromConnectedApp) {
if (preferences.panicResetRepos()) {
resetRepos(this);
}
// Performing destructive panic response
if (preferences.panicHide()) {
Log.i(TAG, "Hiding app...");
@ -125,6 +138,33 @@ public class PanicResponderActivity extends AppCompatActivity {
finish();
}
static void resetRepos(Context context) {
HashSet<String> enabledAddresses = new HashSet<>();
HashSet<String> disabledAddresses = new HashSet<>();
String[] defaultReposItems = DBHelper.loadInitialRepos(context).toArray(new String[0]);
for (int i = 1; i < defaultReposItems.length; i += DBHelper.REPO_XML_ITEM_COUNT) {
if ("1".equals(defaultReposItems[i + 3])) {
enabledAddresses.add(defaultReposItems[i]);
} else {
disabledAddresses.add(defaultReposItems[i]);
}
}
List<Repo> repos = RepoProvider.Helper.all(context);
for (Repo repo : repos) {
ContentValues values = new ContentValues(1);
if (enabledAddresses.contains(repo.address)) {
values.put(Schema.RepoTable.Cols.IN_USE, true);
RepoProvider.Helper.update(context, repo, values);
} else if (disabledAddresses.contains(repo.address)) {
values.put(Schema.RepoTable.Cols.IN_USE, false);
RepoProvider.Helper.update(context, repo, values);
} else {
RepoProvider.Helper.remove(context, repo.getId());
}
}
}
private void exitAndClear() {
ExitActivity.exitAndRemoveFromRecentApps(this);
if (Build.VERSION.SDK_INT >= 21) {

View File

@ -26,6 +26,13 @@
android:summary="@string/panic_hide_summary"
android:title="@string/panic_hide_title"/>
<android.support.v7.preference.CheckBoxPreference
android:defaultValue="false"
android:enabled="false"
android:key="pref_panic_reset_repos"
android:summary="@string/panic_reset_repos_summary"
android:title="@string/panic_reset_repos_title"/>
</android.support.v7.preference.PreferenceCategory>
<android.support.v7.preference.PreferenceCategory

View File

@ -109,6 +109,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
public static final String PREF_PREVENT_SCREENSHOTS = "preventScreenshots";
public static final String PREF_PANIC_EXIT = "pref_panic_exit";
public static final String PREF_PANIC_HIDE = "pref_panic_hide";
public static final String PREF_PANIC_RESET_REPOS = "pref_panic_reset_repos";
public static final String PREF_PANIC_WIPE_SET = "panicWipeSet";
public static final String PREF_PANIC_TMP_SELECTED_SET = "panicTmpSelectedSet";
public static final String PREF_HIDE_ON_LONG_PRESS_SEARCH = "hideOnLongPressSearch";
@ -515,6 +516,10 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
return preferences.getBoolean(PREF_PANIC_HIDE, IGNORED_B);
}
public boolean panicResetRepos() {
return preferences.getBoolean(PREF_PANIC_RESET_REPOS, IGNORED_B);
}
public boolean hideOnLongPressSearch() {
return preferences.getBoolean(PREF_HIDE_ON_LONG_PRESS_SEARCH, IGNORED_B);
}

View File

@ -334,6 +334,8 @@ This often occurs with apps installed via Google Play or other sources, if they
<string name="panic_hide_summary">App will hide itself</string>
<string name="panic_hide_warning_title">Remember how to restore</string>
<string name="panic_hide_warning_message">In a panic event, this will remove %1$s from the launcher. Only typing \"%2$d\" in the fake %3$s app can restore it.</string>
<string name="panic_reset_repos_title">Reset repos</string>
<string name="panic_reset_repos_summary">Force the repo setup back to defaults</string>
<!-- The name of a fake calculator app used as a disguise -->
<string name="hiding_calculator">Calculator</string>

View File

@ -1,5 +1,6 @@
package org.fdroid.fdroid.data;
import android.content.ContentValues;
import android.content.ContextWrapper;
import org.fdroid.fdroid.TestUtils;
import org.junit.After;
@ -26,4 +27,10 @@ public abstract class FDroidProviderTest {
DBHelper.clearDbHelperSingleton();
}
protected Repo setEnabled(Repo repo, boolean enabled) {
ContentValues enable = new ContentValues(1);
enable.put(Schema.RepoTable.Cols.IN_USE, enabled);
RepoProvider.Helper.update(context, repo, enable);
return RepoProvider.Helper.findByAddress(context, repo.address);
}
}

View File

@ -77,13 +77,6 @@ public class RepoProviderTest extends FDroidProviderTest {
assertEquals(0, RepoProvider.Helper.countEnabledRepos(context));
}
private Repo setEnabled(Repo repo, boolean enabled) {
ContentValues enable = new ContentValues(1);
enable.put(RepoTable.Cols.IN_USE, enabled);
RepoProvider.Helper.update(context, repo, enable);
return RepoProvider.Helper.findByAddress(context, repo.address);
}
@Test
public void lastUpdated() {
assertNull(RepoProvider.Helper.lastUpdate(context));

View File

@ -35,12 +35,6 @@ public class Issue763MultiRepo extends MultiIndexUpdaterTest {
antoxRepo = createRepo("Tox", "https://pkg.tox.chat/fdroid/repo", context, antoxCert);
}
public void setEnabled(Repo repo, boolean enabled) {
ContentValues values = new ContentValues(1);
values.put(Schema.RepoTable.Cols.IN_USE, enabled ? 1 : 0);
RepoProvider.Helper.update(context, repo, values);
}
@Test
public void antoxRepo() throws IndexUpdater.UpdateException {
assertAntoxEmpty();

View File

@ -0,0 +1,53 @@
package org.fdroid.fdroid.views.panic;
import org.fdroid.fdroid.data.DBHelper;
import org.fdroid.fdroid.data.FDroidProviderTest;
import org.fdroid.fdroid.data.Repo;
import org.fdroid.fdroid.data.RepoProvider;
import org.fdroid.fdroid.data.RepoProviderTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.List;
import static org.junit.Assert.assertEquals;
@RunWith(RobolectricTestRunner.class)
public class PanicResponderActivityTest extends FDroidProviderTest {
/**
* The {@link DBHelper} class populates the default repos when it first creates a database.
* The names/URLs/signing certificates for these repos are all hard coded in the source/res.
*/
@Test
public void defaultRepos() {
List<Repo> defaultRepos = RepoProvider.Helper.all(context);
assertEquals(defaultRepos.size(), 4); // based on app/src/main/res/default_repo.xml
Repo gpRepo = RepoProvider.Helper.findByAddress(context, "https://guardianproject.info/fdroid/repo");
setEnabled(gpRepo, true);
assertEquals(2, RepoProvider.Helper.countEnabledRepos(context));
PanicResponderActivity.resetRepos(context);
assertEquals(1, RepoProvider.Helper.countEnabledRepos(context));
defaultRepos = RepoProvider.Helper.all(context);
assertEquals(4, defaultRepos.size());
RepoProviderTest.insertRepo(
context,
"https://mock-repo-1.example.com/fdroid/repo",
"Just a made up repo",
"ABCDEF1234567890",
"Mock Repo 1"
);
defaultRepos = RepoProvider.Helper.all(context);
assertEquals(5, defaultRepos.size());
assertEquals(2, RepoProvider.Helper.countEnabledRepos(context));
PanicResponderActivity.resetRepos(context);
defaultRepos = RepoProvider.Helper.all(context);
assertEquals(4, defaultRepos.size());
assertEquals(1, RepoProvider.Helper.countEnabledRepos(context));
}
}