Add code style to repo and fix it

This commit is contained in:
Torsten Grote 2023-06-09 17:24:58 +00:00 committed by Hans-Christoph Steiner
parent 8107e2da73
commit 2048d6f478
242 changed files with 3527 additions and 3952 deletions

View File

@ -54,7 +54,7 @@ android {
// use proguard on debug too since we have unknowingly broken
// release builds before.
all {
manifestPlaceholders = [ applicationLabel: APP_NAME ]
manifestPlaceholders = [applicationLabel: APP_NAME]
minifyEnabled true
shrinkResources true
buildConfigField "String", "PRIVILEGED_EXTENSION_PACKAGE_NAME", privilegedExtensionApplicationId
@ -64,7 +64,7 @@ android {
}
debug {
getIsDefault().set(true)
manifestPlaceholders = [ applicationLabel: APP_NAME_DEBUG ]
manifestPlaceholders = [applicationLabel: APP_NAME_DEBUG]
applicationIdSuffix ".debug"
versionNameSuffix "-debug"
// testProguardFiles gets partially ignored for instrumentation tests
@ -87,7 +87,7 @@ android {
}
}
applicationVariants.all { variant ->
variant.resValue "string", "applicationId", variant.applicationId
variant.resValue "string", "applicationId", variant.applicationId
}
compileOptions {

View File

@ -1,86 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<!-- TODO bump our targetSdkVersion when we are ready for it -->
<issue id="ExpiredTargetSdkVersion" severity="ignore"/>
<issue id="ExpiredTargetSdkVersion" severity="ignore" />
<!-- TODO This should be handled as part of an overhaul of Bluetooth swap -->
<issue id="MissingPermission" severity="">
<ignore path="src/full/java/org/fdroid/fdroid/nearby/BluetoothManager.java"/>
<ignore path="src/full/java/org/fdroid/fdroid/nearby/SwapWorkflowActivity.java"/>
<ignore path="src/full/java/org/fdroid/fdroid/nearby/BluetoothManager.java" />
<ignore path="src/full/java/org/fdroid/fdroid/nearby/SwapWorkflowActivity.java" />
</issue>
<!-- Our translations are crowd-sourced -->
<issue id="MissingTranslation" severity="ignore"/>
<issue id="MissingTranslation" severity="ignore" />
<!-- to make CI fail on errors until this is fixed
https://github.com/rtyley/spongycastle/issues/7 -->
<issue id="InvalidPackage" severity="warning"/>
<issue id="InvalidPackage" severity="warning" />
<issue id="ImpliedQuantity" severity="error"/>
<issue id="DefaultLocale" severity="error"/>
<issue id="SimpleDateFormat" severity="error"/>
<issue id="NewApi" severity="error"/>
<issue id="InlinedApi" severity="error"/>
<issue id="ImpliedQuantity" severity="error" />
<issue id="DefaultLocale" severity="error" />
<issue id="SimpleDateFormat" severity="error" />
<issue id="NewApi" severity="error" />
<issue id="InlinedApi" severity="error" />
<!-- These are important to us, so promote from warning to error -->
<issue id="UnusedResources" severity="error">
<ignore path="src/main/res/drawable/category_**.png" />
<ignore path="src/main/res/values/dimens.xml"/>
<ignore path="src/main/res/values/styles.xml"/>
<ignore path="src/full/res/values/styles.xml"/>
<ignore path="src/main/res/values/dimens.xml" />
<ignore path="src/main/res/values/styles.xml" />
<ignore path="src/full/res/values/styles.xml" />
<!-- keep a single strings.xml for all build flavors -->
<ignore path="src/main/res/values**/strings.xml"/>
<ignore path="src/main/res/values**/strings.xml" />
</issue>
<issue id="AppCompatMethod" severity="error"/>
<issue id="NestedScrolling" severity="error"/>
<issue id="Typos" severity="error"/>
<issue id="StringFormatCount" severity="error"/>
<issue id="UnsafeProtectedBroadcastReceiver" severity="error"/>
<issue id="GetInstance" severity="error"/>
<issue id="PackageManagerGetSignatures" severity="error"/>
<issue id="HardwareIds" severity="error"/>
<issue id="AppCompatMethod" severity="error" />
<issue id="NestedScrolling" severity="error" />
<issue id="Typos" severity="error" />
<issue id="StringFormatCount" severity="error" />
<issue id="UnsafeProtectedBroadcastReceiver" severity="error" />
<issue id="GetInstance" severity="error" />
<issue id="PackageManagerGetSignatures" severity="error" />
<issue id="HardwareIds" severity="error" />
<issue id="TrustAllX509TrustManager" severity="error">
<!-- these come from included libraries -->
<ignore path="org/apache/commons/net/ftp/FTPSTrustManager.class"/>
<ignore path="org/bouncycastle/est/jcajce/JcaJceUtils$1.class"/>
<ignore path="org/bouncycastle/est/jcajce/JcaJceUtils$2.class"/>
<ignore path="org/apache/commons/net/util/TrustManagerUtils$TrustManager.class"/>
<ignore path="\*/bcpkix-jdk15to18-1.71.jar"/>
<ignore path="\*/commons-net-3.6.jar"/>
<!-- these come from included libraries -->
<ignore path="org/apache/commons/net/ftp/FTPSTrustManager.class" />
<ignore path="org/bouncycastle/est/jcajce/JcaJceUtils$1.class" />
<ignore path="org/bouncycastle/est/jcajce/JcaJceUtils$2.class" />
<ignore path="org/apache/commons/net/util/TrustManagerUtils$TrustManager.class" />
<ignore path="\*/bcpkix-jdk15to18-1.71.jar" />
<ignore path="\*/commons-net-3.6.jar" />
</issue>
<issue id="PluralsCandidate" severity="error"/>
<issue id="HardcodedText" severity="error"/>
<issue id="RtlCompat" severity="error"/>
<issue id="RtlEnabled" severity="error"/>
<issue id="PluralsCandidate" severity="error" />
<issue id="HardcodedText" severity="error" />
<issue id="RtlCompat" severity="error" />
<issue id="RtlEnabled" severity="error" />
<!-- both the correct and deprecated locales need to be present for
them to be recognized on all devices -->
<issue id="LocaleFolder" severity="error">
<ignore path="src/main/res/values-he"/>
<ignore path="src/main/res/values-id"/>
<ignore path="src/main/res/values-he" />
<ignore path="src/main/res/values-id" />
</issue>
<!-- Weblate doesn't handle these yet: https://github.com/WeblateOrg/weblate/issues/7520 -->
<issue id="MissingQuantity" severity="error">
<ignore path="src/main/res/values-cs"/>
<ignore path="src/main/res/values-fr"/>
<ignore path="src/main/res/values-lt"/>
<ignore path="src/main/res/values-sk"/>
<ignore path="src/main/res/values-cs" />
<ignore path="src/main/res/values-fr" />
<ignore path="src/main/res/values-lt" />
<ignore path="src/main/res/values-sk" />
</issue>
<issue id="SetWorldReadable" severity="error">
<ignore path="src/main/java/org/fdroid/fdroid/installer/ApkFileProvider.java"/>
<ignore path="src/main/java/org/fdroid/fdroid/installer/ApkFileProvider.java" />
</issue>
<issue id="ProtectedPermissions" severity="error">
<ignore path="src/debug/AndroidManifest.xml"/>
<ignore path="src/full/AndroidManifest.xml"/>
<ignore path="src/debug/AndroidManifest.xml" />
<ignore path="src/full/AndroidManifest.xml" />
</issue>
<!-- these should be fixed, but it'll be a chunk of work -->
<issue id="SetTextI18n" severity="error">
<ignore path="src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java"/>
<ignore path="src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java"/>
<ignore path="src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java" />
<ignore path="src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java" />
</issue>
</lint>

View File

@ -1,7 +1,10 @@
package org.fdroid.fdroid;
import static org.junit.Assert.fail;
import android.content.Context;
import android.util.Log;
import androidx.annotation.Nullable;
import java.io.File;
@ -10,8 +13,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static org.junit.Assert.fail;
public class AssetUtils {
private static final String TAG = "Utils";

View File

@ -5,11 +5,13 @@ import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

View File

@ -1,40 +1,5 @@
package org.fdroid.fdroid;
import android.Manifest;
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.content.Context;
import android.os.Build;
import androidx.core.content.ContextCompat;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.espresso.IdlingPolicies;
import androidx.test.espresso.ViewInteraction;
import androidx.test.rule.ActivityTestRule;
import androidx.test.rule.GrantPermissionRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject;
import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.UiSelector;
import android.util.Log;
import android.view.View;
import org.fdroid.fdroid.views.StatusBanner;
import org.fdroid.fdroid.views.main.MainActivity;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.swipeDown;
@ -48,11 +13,46 @@ import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import android.Manifest;
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import androidx.core.content.ContextCompat;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.espresso.IdlingPolicies;
import androidx.test.espresso.ViewInteraction;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.rule.GrantPermissionRule;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject;
import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.UiSelector;
import org.fdroid.fdroid.views.StatusBanner;
import org.fdroid.fdroid.views.main.MainActivity;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityEspressoTest {
@ -68,7 +68,7 @@ public class MainActivityEspressoTest {
*/
private static boolean canRunEspresso() {
if (Build.VERSION.SDK_INT < 25
|| (Build.SUPPORTED_ABIS[0].startsWith("arm") && isEmulator())) {
|| Build.SUPPORTED_ABIS[0].startsWith("arm") && isEmulator()) {
Log.e(TAG, "SKIPPING TEST: ARM emulators are too slow to run these tests in a useful way");
return false;
}
@ -122,7 +122,7 @@ public class MainActivityEspressoTest {
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.contains("Genymotion")
|| (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
|| Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")
|| "google_sdk".equals(Build.PRODUCT);
}
@ -267,7 +267,7 @@ public class MainActivityEspressoTest {
if (!BuildConfig.FLAVOR.startsWith("full")) {
return;
}
onView(Matchers.<View>instanceOf(StatusBanner.class)).check(matches(not(isDisplayed())));
onView(Matchers.instanceOf(StatusBanner.class)).check(matches(not(isDisplayed())));
onView(allOf(withText(R.string.menu_settings), isDisplayed())).perform(click());
onView(allOf(withText(R.string.main_menu__latest_apps), isDisplayed())).perform(click());
onView(allOf(withId(R.id.swipe_to_refresh), isDisplayed()))

View File

@ -1,5 +1,7 @@
package org.fdroid.fdroid;
import androidx.annotation.NonNull;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
@ -231,9 +233,9 @@ public class Netstat {
/**
* Types of connection protocol
***/
public static final byte TCP_CONNECTION = 0;
public static final byte UDP_CONNECTION = 1;
public static final byte RAW_CONNECTION = 2;
static final byte TCP_CONNECTION = 0;
static final byte UDP_CONNECTION = 1;
static final byte RAW_CONNECTION = 2;
/**
* <code>serialVersionUID</code>
*/
@ -282,11 +284,11 @@ public class Netstat {
return protocol;
}
public final void setProtocol(final byte protocol) {
final void setProtocol(final byte protocol) {
this.protocol = protocol;
}
public final String getProtocolAsString() {
final String getProtocolAsString() {
switch (protocol) {
case TCP_CONNECTION:
return "TCP";
@ -310,7 +312,7 @@ public class Netstat {
return pid;
}
public final void setPID(final int pid) {
final void setPID(final int pid) {
this.pid = pid;
}
@ -318,7 +320,7 @@ public class Netstat {
return pname;
}
public final void setPName(final String pname) {
final void setPName(final String pname) {
this.pname = pname;
}
@ -326,7 +328,7 @@ public class Netstat {
return localPort;
}
public final void setLocalPort(final int localPort) {
final void setLocalPort(final int localPort) {
this.localPort = localPort;
}
@ -334,7 +336,7 @@ public class Netstat {
return remoteAddress;
}
public final void setRemoteAddress(final String remoteAddress) {
final void setRemoteAddress(final String remoteAddress) {
this.remoteAddress = remoteAddress;
}
@ -342,7 +344,7 @@ public class Netstat {
return remotePort;
}
public final void setRemotePort(final int remotePort) {
final void setRemotePort(final int remotePort) {
this.remotePort = remotePort;
}
@ -350,22 +352,21 @@ public class Netstat {
return status;
}
public final void setStatus(final String status) {
final void setStatus(final String status) {
this.status = status;
}
@NonNull
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[Prot=").append(getProtocolAsString());
buf.append(",POwner=").append(powner);
buf.append(",PID=").append(pid);
buf.append(",PName=").append(pname);
buf.append(",LPort=").append(localPort);
buf.append(",RAddress=").append(remoteAddress);
buf.append(",RPort=").append(remotePort);
buf.append(",Status=").append(status);
buf.append("]");
return buf.toString();
return "[Prot=" + getProtocolAsString() +
",POwner=" + powner +
",PID=" + pid +
",PName=" + pname +
",LPort=" + localPort +
",RAddress=" + remoteAddress +
",RPort=" + remotePort +
",Status=" + status +
"]";
}
}

View File

@ -16,12 +16,12 @@
package org.fdroid.fdroid;
import android.util.Log;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject;
import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.UiSelector;
import androidx.test.uiautomator.UiWatcher;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
@ -38,83 +38,71 @@ class UiWatchers {
* This is a sample watcher looking for ANR and crashes. it closes it and moves on. You should
* create your own watchers and handle error logging properly for your type of tests.
*/
public void registerAnrAndCrashWatchers() {
UiDevice.getInstance().registerWatcher("ANR", new UiWatcher() {
@Override
public boolean checkForCondition() {
UiObject window = new UiObject(new UiSelector().className(
"com.android.server.am.AppNotRespondingDialog"));
String errorText = null;
if (window.exists()) {
try {
errorText = window.getText();
} catch (UiObjectNotFoundException e) {
Log.e(LOG_TAG, "dialog gone?", e);
}
onAnrDetected(errorText);
postHandler("Wait");
return true; // triggered
void registerAnrAndCrashWatchers() {
UiDevice.getInstance().registerWatcher("ANR", () -> {
UiObject window = new UiObject(new UiSelector().className(
"com.android.server.am.AppNotRespondingDialog"));
String errorText = null;
if (window.exists()) {
try {
errorText = window.getText();
} catch (UiObjectNotFoundException e) {
Log.e(LOG_TAG, "dialog gone?", e);
}
return false; // no trigger
onAnrDetected(errorText);
postHandler("Wait");
return true; // triggered
}
return false; // no trigger
});
// class names may have changed
UiDevice.getInstance().registerWatcher("ANR2", new UiWatcher() {
@Override
public boolean checkForCondition() {
UiObject window = new UiObject(new UiSelector().packageName("android")
.textContains("isn't responding."));
if (window.exists()) {
String errorText = null;
try {
errorText = window.getText();
} catch (UiObjectNotFoundException e) {
Log.e(LOG_TAG, "dialog gone?", e);
}
onAnrDetected(errorText);
postHandler("Wait");
return true; // triggered
UiDevice.getInstance().registerWatcher("ANR2", () -> {
UiObject window = new UiObject(new UiSelector().packageName("android")
.textContains("isn't responding."));
if (window.exists()) {
String errorText = null;
try {
errorText = window.getText();
} catch (UiObjectNotFoundException e) {
Log.e(LOG_TAG, "dialog gone?", e);
}
return false; // no trigger
onAnrDetected(errorText);
postHandler("Wait");
return true; // triggered
}
return false; // no trigger
});
UiDevice.getInstance().registerWatcher("CRASH", new UiWatcher() {
@Override
public boolean checkForCondition() {
UiObject window = new UiObject(new UiSelector().className(
"com.android.server.am.AppErrorDialog"));
if (window.exists()) {
String errorText = null;
try {
errorText = window.getText();
} catch (UiObjectNotFoundException e) {
Log.e(LOG_TAG, "dialog gone?", e);
}
onCrashDetected(errorText);
postHandler("OK");
return true; // triggered
UiDevice.getInstance().registerWatcher("CRASH", () -> {
UiObject window = new UiObject(new UiSelector().className(
"com.android.server.am.AppErrorDialog"));
if (window.exists()) {
String errorText = null;
try {
errorText = window.getText();
} catch (UiObjectNotFoundException e) {
Log.e(LOG_TAG, "dialog gone?", e);
}
return false; // no trigger
onCrashDetected(errorText);
postHandler("OK");
return true; // triggered
}
return false; // no trigger
});
UiDevice.getInstance().registerWatcher("CRASH2", new UiWatcher() {
@Override
public boolean checkForCondition() {
UiObject window = new UiObject(new UiSelector().packageName("android")
.textContains("has stopped"));
if (window.exists()) {
String errorText = null;
try {
errorText = window.getText();
} catch (UiObjectNotFoundException e) {
Log.e(LOG_TAG, "dialog gone?", e);
}
onCrashDetected(errorText);
postHandler("OK");
return true; // triggered
UiDevice.getInstance().registerWatcher("CRASH2", () -> {
UiObject window = new UiObject(new UiSelector().packageName("android")
.textContains("has stopped"));
if (window.exists()) {
String errorText = null;
try {
errorText = window.getText();
} catch (UiObjectNotFoundException e) {
Log.e(LOG_TAG, "dialog gone?", e);
}
return false; // no trigger
onCrashDetected(errorText);
postHandler("OK");
return true; // triggered
}
return false; // no trigger
});
Log.i(LOG_TAG, "Registered GUI Exception watchers");
}

View File

@ -1,13 +1,18 @@
package org.fdroid.fdroid.compat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import android.app.Instrumentation;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import android.util.Log;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import org.fdroid.fdroid.AssetUtils;
import org.fdroid.fdroid.data.SanitizedFile;
import org.junit.After;
@ -18,10 +23,6 @@ import org.junit.runner.RunWith;
import java.io.File;
import java.util.UUID;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
/**
* This test needs to run on the emulator, even though it technically could
@ -78,7 +79,6 @@ public class FileCompatTest {
assertTrue(destFile.getAbsolutePath() + " should exist after symlinking", destFile.exists());
}
/**
* Prefer internal over external storage, because external tends to be FAT filesystems,
* which don't support symlinks (which we test using this method).

View File

@ -156,7 +156,8 @@ public class ApkVerifierTest {
try {
apkVerifier.verifyApk();
} catch (ApkVerifier.ApkVerificationException | ApkVerifier.ApkPermissionUnequalException e) {
} catch (ApkVerifier.ApkVerificationException |
ApkVerifier.ApkPermissionUnequalException e) {
e.printStackTrace();
fail(e.getMessage());
}

View File

@ -1,5 +1,7 @@
package org.fdroid.fdroid.nearby;
import static org.junit.Assert.assertTrue;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
@ -15,8 +17,6 @@ import java.util.concurrent.TimeUnit;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceListener;
import static org.junit.Assert.assertTrue;
@RunWith(AndroidJUnit4.class)
public class BonjourManagerTest {

View File

@ -1,14 +1,20 @@
package org.fdroid.fdroid.nearby;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.util.Log;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Netstat;
import org.fdroid.fdroid.Utils;
@ -23,11 +29,6 @@ import java.net.ServerSocket;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* Test the nearby webserver in the emulator.
*/

View File

@ -1,5 +1,9 @@
package org.fdroid.fdroid.nearby;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@ -7,6 +11,9 @@ import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Test;
@ -17,13 +24,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@RunWith(AndroidJUnit4.class)
public class PublicSourceDirProviderTest {
public static final String TAG = "DataApkProviderTest";

View File

@ -1,6 +1,9 @@
package org.fdroid.fdroid.net;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.os.Build;
import android.util.Log;
@ -11,7 +14,6 @@ import org.fdroid.download.HttpDownloader;
import org.fdroid.download.HttpManager;
import org.fdroid.download.Mirror;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.ProgressListener;
import org.fdroid.fdroid.Utils;
import org.fdroid.index.v1.IndexV1UpdaterKt;
import org.junit.Test;
@ -26,10 +28,6 @@ import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class HttpDownloaderTest {
private static final String TAG = "HttpDownloaderTest";
@ -84,12 +82,7 @@ public class HttpDownloaderTest {
File destFile = File.createTempFile("dl-", "");
final DownloadRequest request = new DownloadRequest(path, mirrors, null, null, null);
final HttpDownloader httpDownloader = new HttpDownloader(httpManager, request, destFile);
httpDownloader.setListener(new ProgressListener() {
@Override
public void onProgress(long bytesRead, long totalBytes) {
receivedProgress = true;
}
});
httpDownloader.setListener((bytesRead, totalBytes) -> receivedProgress = true);
new Thread() {
@Override
public void run() {
@ -156,12 +149,9 @@ public class HttpDownloaderTest {
File destFile = File.createTempFile("dl-", "");
final DownloadRequest request = new DownloadRequest(path, mirrors, null, null, null);
final HttpDownloader httpDownloader = new HttpDownloader(httpManager, request, destFile);
httpDownloader.setListener(new ProgressListener() {
@Override
public void onProgress(long bytesRead, long totalBytes) {
receivedProgress = true;
latch.countDown();
}
httpDownloader.setListener((bytesRead, totalBytes) -> {
receivedProgress = true;
latch.countDown();
});
new Thread() {
@Override

View File

@ -1,5 +1,11 @@
package org.fdroid.fdroid.updater;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@ -8,6 +14,9 @@ import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import org.fdroid.fdroid.BuildConfig;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Hasher;
@ -30,15 +39,6 @@ import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@LargeTest
public class SwapRepoEmulatorTest {
public static final String TAG = "SwapRepoEmulatorTest";

View File

@ -1,12 +1,19 @@
package org.fdroid.fdroid.work;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.app.Instrumentation;
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkInfo;
import com.google.common.util.concurrent.ListenableFuture;
import org.apache.commons.io.FileUtils;
import org.fdroid.fdroid.compat.FileCompatTest;
import org.junit.Rule;
@ -16,10 +23,6 @@ import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* This test cannot run on Robolectric unfortunately since it does not support
* getting the timestamps from the files completely.

View File

@ -18,12 +18,16 @@
package org.fdroid.fdroid.work;
import static org.junit.Assert.assertEquals;
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkInfo;
import com.google.common.util.concurrent.ListenableFuture;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@ -31,8 +35,6 @@ import org.junit.Test;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import static org.junit.Assert.assertEquals;
/**
* This actually runs {@link FDroidMetricsWorker} on a device/emulator and
* submits a report to https://metrics.cleaninsights.org

View File

@ -3,11 +3,13 @@ package org.fdroid.fdroid.work;
import android.app.Instrumentation;
import android.content.Context;
import android.util.Log;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.work.Configuration;
import androidx.work.WorkManager;
import androidx.work.testing.SynchronousExecutor;
import androidx.work.testing.WorkManagerTestInitHelper;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

View File

@ -19,9 +19,10 @@
package org.fdroid.fdroid.nearby;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import androidx.appcompat.app.AppCompatActivity;
/**
* Dummy version for basic app flavor.
*/

View File

@ -21,6 +21,7 @@ package org.fdroid.fdroid.nearby;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.Nullable;
/**

View File

@ -20,10 +20,12 @@
package org.fdroid.fdroid.views.main;
import android.widget.FrameLayout;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.views.PreferencesFragment;
import org.fdroid.fdroid.views.updates.UpdatesViewBinder;
@ -51,14 +53,14 @@ class MainViewController extends RecyclerView.ViewHolder {
/**
* @see LatestViewBinder
*/
public void bindLatestView() {
void bindLatestView() {
new LatestViewBinder(activity, frame);
}
/**
* @see UpdatesViewBinder
*/
public void bindUpdates() {
void bindUpdates() {
if (updatesView == null) {
updatesView = new UpdatesViewBinder(activity, frame);
}
@ -66,7 +68,7 @@ class MainViewController extends RecyclerView.ViewHolder {
updatesView.bind();
}
public void unbindUpdates() {
void unbindUpdates() {
if (updatesView != null) {
updatesView.unbind();
}
@ -75,11 +77,11 @@ class MainViewController extends RecyclerView.ViewHolder {
/**
* @see CategoriesViewBinder
*/
public void bindCategoriesView() {
void bindCategoriesView() {
new CategoriesViewBinder(activity, frame);
}
public void bindSwapView() {
void bindSwapView() {
throw new IllegalStateException("unimplemented");
}
@ -96,7 +98,7 @@ class MainViewController extends RecyclerView.ViewHolder {
*
* @see SettingsView
*/
public void bindSettingsView() {
void bindSettingsView() {
activity.getLayoutInflater().inflate(R.layout.main_tab_settings, frame, true);
}
}

View File

@ -3,7 +3,7 @@ package org.fdroid.fdroid.views.main;
import android.content.Context;
class NearbyViewBinder {
public static void updateUsbOtg(Context context) {
static void updateUsbOtg(Context context) {
throw new IllegalStateException("unimplemented");
}
}

View File

@ -4,52 +4,56 @@
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:pathData="M36,49L72,49A4,4 0,0 1,76 53L76,75A4,4 0,0 1,72 79L36,79A4,4 0,0 1,32 75L32,53A4,4 0,0 1,36 49z"
android:fillColor="#1976D2"/>
<path
android:pathData="M78.237,28.517C78.782,28.941 78.88,29.727 78.456,30.271L72.991,37.298C72.567,37.843 71.782,37.941 71.237,37.517C70.692,37.094 70.594,36.308 71.018,35.763L76.483,28.737C76.907,28.192 77.692,28.094 78.237,28.517Z"
android:fillColor="#8AB000"
android:fillType="evenOdd"/>
<path
android:pathData="M29.763,28.517C29.218,28.941 29.12,29.727 29.544,30.271L35.009,37.298C35.433,37.843 36.218,37.941 36.763,37.517C37.308,37.094 37.406,36.308 36.982,35.763L31.517,28.737C31.093,28.192 30.308,28.094 29.763,28.517Z"
android:fillColor="#8AB000"
android:fillType="evenOdd"/>
<path
android:pathData="M32,74V75C32,77.209 33.791,79 36,79H72C74.209,79 76,77.209 76,75V74C76,76.209 74.209,78 72,78H36C33.791,78 32,76.209 32,74Z"
android:fillColor="#263238"
android:fillAlpha="0.2"
android:fillType="evenOdd"/>
<path
android:pathData="M32,54V53C32,50.791 33.791,49 36,49H72C74.209,49 76,50.791 76,53V54C76,51.791 74.209,50 72,50H36C33.791,50 32,51.791 32,54Z"
android:fillColor="#ffffff"
android:fillAlpha="0.2"
android:fillType="evenOdd"/>
<path
android:pathData="M36,33L72,33A4,4 0,0 1,76 37L76,43A4,4 0,0 1,72 47L36,47A4,4 0,0 1,32 43L32,37A4,4 0,0 1,36 33z"
android:fillColor="#B2EB0B"/>
<path
android:pathData="M32,42V43C32,45.209 33.791,47 36,47H72C74.209,47 76,45.209 76,43V42C76,44.209 74.209,46 72,46H36C33.791,46 32,44.209 32,42Z"
android:fillColor="#263238"
android:fillAlpha="0.2"
android:fillType="evenOdd"/>
<path
android:pathData="M32,38V37C32,34.791 33.791,33 36,33H72C74.209,33 76,34.791 76,37V38C76,35.791 74.209,34 72,34H36C33.791,34 32,35.791 32,38Z"
android:fillColor="#ffffff"
android:fillAlpha="0.2"
android:fillType="evenOdd"/>
<path
android:pathData="M29.764,28.517C29.219,28.941 29.121,29.727 29.545,30.272L32.855,34.528C32.319,35.208 32,36.067 32,37V43C32,45.209 33.791,47 36,47H72C74.209,47 76,45.209 76,43V37C76,36.067 75.68,35.209 75.145,34.528L78.456,30.272C78.88,29.727 78.782,28.941 78.237,28.517C77.692,28.094 76.907,28.192 76.483,28.737L73.057,33.141C72.72,33.049 72.366,33 72,33H36C35.634,33 35.28,33.049 34.944,33.141L31.518,28.737C31.094,28.192 30.309,28.094 29.764,28.517ZM36,49C33.791,49 32,50.791 32,53V75C32,77.209 33.791,79 36,79H72C74.209,79 76,77.209 76,75V53C76,50.791 74.209,49 72,49H36Z"
android:fillType="evenOdd">
<aapt:attr name="android:fillColor">
<gradient
android:gradientRadius="111.714"
android:centerX="16.0875"
android:centerY="15.6388"
android:type="radial">
<item android:offset="0" android:color="#19FFFFFF"/>
<item android:offset="1" android:color="#00FFFFFF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M36,49L72,49A4,4 0,0 1,76 53L76,75A4,4 0,0 1,72 79L36,79A4,4 0,0 1,32 75L32,53A4,4 0,0 1,36 49z"
android:fillColor="#1976D2" />
<path
android:pathData="M78.237,28.517C78.782,28.941 78.88,29.727 78.456,30.271L72.991,37.298C72.567,37.843 71.782,37.941 71.237,37.517C70.692,37.094 70.594,36.308 71.018,35.763L76.483,28.737C76.907,28.192 77.692,28.094 78.237,28.517Z"
android:fillColor="#8AB000"
android:fillType="evenOdd" />
<path
android:pathData="M29.763,28.517C29.218,28.941 29.12,29.727 29.544,30.271L35.009,37.298C35.433,37.843 36.218,37.941 36.763,37.517C37.308,37.094 37.406,36.308 36.982,35.763L31.517,28.737C31.093,28.192 30.308,28.094 29.763,28.517Z"
android:fillColor="#8AB000"
android:fillType="evenOdd" />
<path
android:pathData="M32,74V75C32,77.209 33.791,79 36,79H72C74.209,79 76,77.209 76,75V74C76,76.209 74.209,78 72,78H36C33.791,78 32,76.209 32,74Z"
android:fillColor="#263238"
android:fillAlpha="0.2"
android:fillType="evenOdd" />
<path
android:pathData="M32,54V53C32,50.791 33.791,49 36,49H72C74.209,49 76,50.791 76,53V54C76,51.791 74.209,50 72,50H36C33.791,50 32,51.791 32,54Z"
android:fillColor="#ffffff"
android:fillAlpha="0.2"
android:fillType="evenOdd" />
<path
android:pathData="M36,33L72,33A4,4 0,0 1,76 37L76,43A4,4 0,0 1,72 47L36,47A4,4 0,0 1,32 43L32,37A4,4 0,0 1,36 33z"
android:fillColor="#B2EB0B" />
<path
android:pathData="M32,42V43C32,45.209 33.791,47 36,47H72C74.209,47 76,45.209 76,43V42C76,44.209 74.209,46 72,46H36C33.791,46 32,44.209 32,42Z"
android:fillColor="#263238"
android:fillAlpha="0.2"
android:fillType="evenOdd" />
<path
android:pathData="M32,38V37C32,34.791 33.791,33 36,33H72C74.209,33 76,34.791 76,37V38C76,35.791 74.209,34 72,34H36C33.791,34 32,35.791 32,38Z"
android:fillColor="#ffffff"
android:fillAlpha="0.2"
android:fillType="evenOdd" />
<path
android:pathData="M29.764,28.517C29.219,28.941 29.121,29.727 29.545,30.272L32.855,34.528C32.319,35.208 32,36.067 32,37V43C32,45.209 33.791,47 36,47H72C74.209,47 76,45.209 76,43V37C76,36.067 75.68,35.209 75.145,34.528L78.456,30.272C78.88,29.727 78.782,28.941 78.237,28.517C77.692,28.094 76.907,28.192 76.483,28.737L73.057,33.141C72.72,33.049 72.366,33 72,33H36C35.634,33 35.28,33.049 34.944,33.141L31.518,28.737C31.094,28.192 30.309,28.094 29.764,28.517ZM36,49C33.791,49 32,50.791 32,53V75C32,77.209 33.791,79 36,79H72C74.209,79 76,77.209 76,75V53C76,50.791 74.209,49 72,49H36Z"
android:fillType="evenOdd">
<aapt:attr name="android:fillColor">
<gradient
android:gradientRadius="111.714"
android:centerX="16.0875"
android:centerY="15.6388"
android:type="radial">
<item
android:offset="0"
android:color="#19FFFFFF" />
<item
android:offset="1"
android:color="#00FFFFFF" />
</gradient>
</aapt:attr>
</path>
</vector>

View File

@ -1,73 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen android:title="@string/about_title"
<PreferenceScreen
android:title="@string/about_title"
android:key="pref_about" />
<PreferenceCategory android:title="@string/preference_category__my_apps">
<PreferenceScreen android:title="@string/preference_manage_installed_apps">
<intent
android:action="android.intent.action.MAIN"
android:targetPackage="@string/applicationId"
android:targetClass="org.fdroid.fdroid.views.installed.InstalledAppsActivity"/>
android:action="android.intent.action.MAIN"
android:targetPackage="@string/applicationId"
android:targetClass="org.fdroid.fdroid.views.installed.InstalledAppsActivity" />
</PreferenceScreen>
<PreferenceScreen
android:title="@string/menu_manage"
android:summary="@string/repositories_summary">
android:title="@string/menu_manage"
android:summary="@string/repositories_summary">
<intent
android:action="android.intent.action.MAIN"
android:targetPackage="@string/applicationId"
android:targetClass="org.fdroid.fdroid.views.ManageReposActivity"/>
android:action="android.intent.action.MAIN"
android:targetPackage="@string/applicationId"
android:targetClass="org.fdroid.fdroid.views.ManageReposActivity" />
</PreferenceScreen>
<PreferenceScreen
android:key="installHistory"
android:visible="false"
android:title="@string/install_history"
android:summary="@string/install_history_summary">
android:key="installHistory"
android:visible="false"
android:title="@string/install_history"
android:summary="@string/install_history_summary">
<intent
android:action="android.intent.action.MAIN"
android:targetPackage="@string/applicationId"
android:targetClass="org.fdroid.fdroid.views.InstallHistoryActivity"/>
android:action="android.intent.action.MAIN"
android:targetPackage="@string/applicationId"
android:targetClass="org.fdroid.fdroid.views.InstallHistoryActivity" />
</PreferenceScreen>
</PreferenceCategory>
<PreferenceCategory android:title="@string/updates">
<org.fdroid.fdroid.views.LiveSeekBarPreference
android:key="overWifi"
android:title="@string/over_wifi"
android:defaultValue="@integer/defaultOverWifi"
android:layout="@layout/preference_seekbar"/>
android:key="overWifi"
android:title="@string/over_wifi"
android:defaultValue="@integer/defaultOverWifi"
android:layout="@layout/preference_seekbar" />
<org.fdroid.fdroid.views.LiveSeekBarPreference
android:key="overData"
android:title="@string/over_data"
android:defaultValue="@integer/defaultOverData"
android:layout="@layout/preference_seekbar"/>
android:key="overData"
android:title="@string/over_data"
android:defaultValue="@integer/defaultOverData"
android:layout="@layout/preference_seekbar" />
<SwitchPreferenceCompat
android:title="@string/update_auto_download"
android:summary="@string/update_auto_download_summary"
android:key="updateAutoDownload"/>
android:title="@string/update_auto_download"
android:summary="@string/update_auto_download_summary"
android:key="updateAutoDownload" />
<org.fdroid.fdroid.views.LiveSeekBarPreference
android:key="updateIntervalSeekBarPosition"
android:title="@string/update_interval"
android:defaultValue="@integer/defaultUpdateInterval"
android:layout="@layout/preference_seekbar"/>
android:key="updateIntervalSeekBarPosition"
android:title="@string/update_interval"
android:defaultValue="@integer/defaultUpdateInterval"
android:layout="@layout/preference_seekbar" />
<SwitchPreferenceCompat
android:title="@string/notify"
android:defaultValue="true"
android:key="updateNotify"/>
android:title="@string/notify"
android:defaultValue="true"
android:key="updateNotify" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/display"
android:key="pref_category_display">
<PreferenceCategory
android:title="@string/display"
android:key="pref_category_display">
<ListPreference
android:title="@string/pref_language"
android:key="language"/>
android:title="@string/pref_language"
android:key="language" />
<ListPreference
android:title="@string/theme"
android:key="theme"
android:defaultValue="@string/defaultTheme"
android:entries="@array/themeNames"
android:entryValues="@array/themeValues"/>
android:title="@string/theme"
android:key="theme"
android:defaultValue="@string/defaultTheme"
android:entries="@array/themeNames"
android:entryValues="@array/themeValues" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="usePureBlackDarkTheme"
@ -75,116 +77,117 @@
android:title="@string/use_pure_black_dark_theme" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/appcompatibility"
android:key="pref_category_appcompatibility">
<PreferenceCategory
android:title="@string/appcompatibility"
android:key="pref_category_appcompatibility">
<SwitchPreferenceCompat
android:title="@string/show_incompat_versions"
android:defaultValue="false"
android:key="incompatibleVersions"/>
android:title="@string/show_incompat_versions"
android:defaultValue="false"
android:key="incompatibleVersions" />
<MultiSelectListPreference
android:title="@string/show_anti_feature_apps"
android:defaultValue="@array/antifeaturesValuesDefault"
android:key="showAntiFeatures"
android:entries="@array/antifeaturesNames"
android:entryValues="@array/antifeaturesValues"/>
android:entryValues="@array/antifeaturesValues" />
<SwitchPreference
android:title="@string/force_touch_apps"
android:defaultValue="false"
android:key="ignoreTouchscreen"/>
android:title="@string/force_touch_apps"
android:defaultValue="false"
android:key="ignoreTouchscreen" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/proxy">
<SwitchPreferenceCompat
android:key="useTor"
android:summary="@string/useTorSummary"
android:title="@string/useTor"/>
android:key="useTor"
android:summary="@string/useTorSummary"
android:title="@string/useTor" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="enableProxy"
android:title="@string/enable_proxy_title"
android:summary="@string/enable_proxy_summary"/>
android:defaultValue="false"
android:key="enableProxy"
android:title="@string/enable_proxy_title"
android:summary="@string/enable_proxy_summary" />
<EditTextPreference
android:key="proxyHost"
android:title="@string/proxy_host"
android:summary="@string/proxy_host_summary"
android:dependency="enableProxy"/>
android:key="proxyHost"
android:title="@string/proxy_host"
android:summary="@string/proxy_host_summary"
android:dependency="enableProxy" />
<EditTextPreference
android:key="proxyPort"
android:title="@string/proxy_port"
android:summary="@string/proxy_port_summary"
android:dependency="enableProxy"/>
android:key="proxyPort"
android:title="@string/proxy_port"
android:summary="@string/proxy_port_summary"
android:dependency="enableProxy" />
</PreferenceCategory>
<PreferenceCategory
android:key="pref_category_privacy"
android:title="@string/privacy">
android:key="pref_category_privacy"
android:title="@string/privacy">
<SwitchPreferenceCompat
android:key="promptToSendCrashReports"
android:title="@string/prompt_to_send_crash_reports"
android:summary="@string/prompt_to_send_crash_reports_summary"
android:defaultValue="true"/>
android:key="promptToSendCrashReports"
android:title="@string/prompt_to_send_crash_reports"
android:summary="@string/prompt_to_send_crash_reports_summary"
android:defaultValue="true" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="preventScreenshots"
android:summary="@string/preventScreenshots_summary"
android:title="@string/preventScreenshots_title"/>
android:defaultValue="false"
android:key="preventScreenshots"
android:summary="@string/preventScreenshots_summary"
android:title="@string/preventScreenshots_title" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/other"
android:key="pref_category_other">
android:title="@string/other"
android:key="pref_category_other">
<ListPreference
android:title="@string/cache_downloaded"
android:key="keepCacheFor"
android:defaultValue="86400000"
android:entries="@array/keepCacheNames"
android:entryValues="@array/keepCacheValues"/>
android:title="@string/cache_downloaded"
android:key="keepCacheFor"
android:defaultValue="86400000"
android:entries="@array/keepCacheNames"
android:entryValues="@array/keepCacheValues" />
<SwitchPreferenceCompat
android:title="@string/expert"
android:defaultValue="false"
android:key="expert"/>
android:title="@string/expert"
android:defaultValue="false"
android:key="expert" />
<CheckBoxPreference
android:key="unstableUpdates"
android:title="@string/unstable_updates"
android:summary="@string/unstable_updates_summary"
android:defaultValue="false"
android:dependency="expert"/>
android:key="unstableUpdates"
android:title="@string/unstable_updates"
android:summary="@string/unstable_updates_summary"
android:defaultValue="false"
android:dependency="expert" />
<CheckBoxPreference
android:key="keepInstallHistory"
android:title="@string/keep_install_history"
android:summary="@string/keep_install_history_summary"
android:defaultValue="false"
android:dependency="expert"/>
android:key="keepInstallHistory"
android:title="@string/keep_install_history"
android:summary="@string/keep_install_history_summary"
android:defaultValue="false"
android:dependency="expert" />
<CheckBoxPreference
android:key="sendToFdroidMetrics"
android:title="@string/send_to_fdroid_metrics"
android:summary="@string/send_to_fdroid_metrics_summary"
android:defaultValue="false"
android:dependency="expert"/>
android:key="sendToFdroidMetrics"
android:title="@string/send_to_fdroid_metrics"
android:summary="@string/send_to_fdroid_metrics_summary"
android:defaultValue="false"
android:dependency="expert" />
<CheckBoxPreference
android:key="hideAllNotifications"
android:title="@string/hide_all_notifications"
android:summary="@string/hide_all_notifications_summary"
android:defaultValue="false"
android:dependency="expert"/>
android:key="hideAllNotifications"
android:title="@string/hide_all_notifications"
android:summary="@string/hide_all_notifications_summary"
android:defaultValue="false"
android:dependency="expert" />
<CheckBoxPreference
android:key="sendVersionAndUUIDToServers"
android:title="@string/send_version_and_uuid"
android:summary="@string/send_version_and_uuid_summary"
android:defaultValue="false"
android:dependency="expert"/>
android:key="sendVersionAndUUIDToServers"
android:title="@string/send_version_and_uuid"
android:summary="@string/send_version_and_uuid_summary"
android:defaultValue="false"
android:dependency="expert" />
<CheckBoxPreference
android:key="forceOldIndex"
android:title="@string/force_old_index"
android:summary="@string/force_old_index_summary"
android:defaultValue="false"
android:dependency="expert"/>
android:key="forceOldIndex"
android:title="@string/force_old_index"
android:summary="@string/force_old_index_summary"
android:defaultValue="false"
android:dependency="expert" />
<CheckBoxPreference
android:title="@string/system_installer"
android:defaultValue="false"
android:key="privilegedInstaller"
android:persistent="false"
android:dependency="expert"/>
android:title="@string/system_installer"
android:defaultValue="false"
android:key="privilegedInstaller"
android:persistent="false"
android:dependency="expert" />
</PreferenceCategory>
</PreferenceScreen>

View File

@ -45,10 +45,12 @@
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- Some Android ROMs still require Bluetooth permission above SDK 30 -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="32" />
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
@ -70,8 +72,7 @@
android:label="@string/swap"
android:launchMode="singleTask"
android:parentActivityName=".views.main.MainActivity"
android:screenOrientation="portrait">
</activity>
android:screenOrientation="portrait"></activity>
<activity
android:name=".panic.PanicPreferencesActivity"
@ -116,6 +117,7 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".nearby.WifiStateChangeReceiver">
<intent-filter>
<action android:name="android.net.wifi.STATE_CHANGE" />

View File

@ -15,15 +15,15 @@ import android.os.Process;
import android.text.TextUtils;
import android.util.Log;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.nearby.peers.BluetoothPeer;
import java.lang.ref.WeakReference;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/**
* Manage the {@link android.bluetooth.BluetoothAdapter}in a {@link HandlerThread}.
* The start process is in {@link HandlerThread#onLooperPrepared()} so that it is

View File

@ -14,7 +14,9 @@ import android.os.Process;
import android.text.TextUtils;
import android.util.Log;
import org.fdroid.database.Repository;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R;
@ -31,9 +33,6 @@ import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceInfo;
import javax.jmdns.ServiceListener;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/**
* Manage {@link JmDNS} in a {@link HandlerThread}. The start process is in
* {@link HandlerThread#onLooperPrepared()} so that it is always started before

View File

@ -41,7 +41,6 @@ import org.fdroid.fdroid.BuildConfig;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
@ -57,6 +56,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.StringTokenizer;
import java.util.TimeZone;
@ -72,7 +72,8 @@ import fi.iki.elonen.NanoHTTPD.Response.IStatus;
* <p>
* This is mostly just synced from {@code SimpleWebServer.java} from NanoHTTPD.
*
* @see <a href="https://github.com/NanoHttpd/nanohttpd/blob/nanohttpd-project-2.3.1/webserver/src/main/java/fi/iki/elonen/SimpleWebServer.java">webserver/src/main/java/fi/iki/elonen/SimpleWebServer.java</a>
* @see
* <a href="https://github.com/NanoHttpd/nanohttpd/blob/nanohttpd-project-2.3.1/webserver/src/main/java/fi/iki/elonen/SimpleWebServer.java">webserver/src/main/java/fi/iki/elonen/SimpleWebServer.java</a>
*/
public class LocalHTTPD extends NanoHTTPD {
private static final String TAG = "LocalHTTPD";
@ -159,17 +160,20 @@ public class LocalHTTPD extends NanoHTTPD {
}
protected Response getInternalErrorResponse(String s) {
return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, NanoHTTPD.MIME_PLAINTEXT, "INTERNAL ERROR: " + s);
return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, NanoHTTPD.MIME_PLAINTEXT,
"INTERNAL ERROR: " + s);
}
protected Response getNotFoundResponse() {
return newFixedLengthResponse(Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT, "Error 404, file not found.");
return newFixedLengthResponse(Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT, "Error 404, file not " +
"found.");
}
protected String listDirectory(String uri, File f) {
String heading = "Directory " + uri;
StringBuilder msg =
new StringBuilder("<html><head><title>" + heading + "</title><style><!--\n" + "span.dirname { font-weight: bold; }\n" + "span.filesize { font-size: 75%; }\n"
new StringBuilder("<html><head><title>" + heading + "</title><style><!--\n" + "span.dirname { " +
"font-weight: bold; }\n" + "span.filesize { font-size: 75%; }\n"
+ "// -->\n" + "</style>" + "</head><body><h1>" + heading + "</h1>");
String up = null;
@ -181,39 +185,32 @@ public class LocalHTTPD extends NanoHTTPD {
}
}
List<String> files = Arrays.asList(f.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return new File(dir, name).isFile();
}
}));
List<String> files =
Arrays.asList(Objects.requireNonNull(f.list((dir, name) -> new File(dir, name).isFile())));
Collections.sort(files);
List<String> directories = Arrays.asList(f.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return new File(dir, name).isDirectory();
}
}));
List<String> directories =
Arrays.asList(Objects.requireNonNull(f.list((dir, name) -> new File(dir, name).isDirectory())));
Collections.sort(directories);
if (up != null || directories.size() + files.size() > 0) {
msg.append("<ul>");
if (up != null || directories.size() > 0) {
msg.append("<section class=\"directories\">");
if (up != null) {
msg.append("<li><a rel=\"directory\" href=\"").append(up).append("\"><span class=\"dirname\">..</span></a></li>");
msg.append("<li><a rel=\"directory\" href=\"").append(up).append("\"><span class=\"dirname\">." +
".</span></a></li>");
}
for (String directory : directories) {
String dir = directory + "/";
msg.append("<li><a rel=\"directory\" href=\"").append(encodeUri(uri + dir)).append("\"><span class=\"dirname\">").append(dir).append("</span></a></li>");
msg.append("<li><a rel=\"directory\" href=\"").append(encodeUri(uri + dir)).append("\"><span " +
"class=\"dirname\">").append(dir).append("</span></a></li>");
}
msg.append("</section>");
}
if (files.size() > 0) {
msg.append("<section class=\"files\">");
for (String file : files) {
msg.append("<li><a href=\"").append(encodeUri(uri + file)).append("\"><span class=\"filename\">").append(file).append("</span></a>");
msg.append("<li><a href=\"").append(encodeUri(uri + file)).append("\"><span class=\"filename" +
"\">").append(file).append("</span></a>");
File curFile = new File(f, file);
long len = curFile.length();
msg.append("&nbsp;<span class=\"filesize\">(");
@ -296,7 +293,8 @@ public class LocalHTTPD extends NanoHTTPD {
if (f.isDirectory() && !uri.endsWith("/")) {
uri += "/";
Response res =
newFixedLengthResponse(Response.Status.REDIRECT, NanoHTTPD.MIME_HTML, "<html><body>Redirected: <a href=\"" + uri + "\">" + uri + "</a></body></html>");
newFixedLengthResponse(Response.Status.REDIRECT, NanoHTTPD.MIME_HTML, "<html><body>Redirected: " +
"<a href=\"" + uri + "\">" + uri + "</a></body></html>");
res.addHeader("Location", uri);
return res;
}
@ -386,7 +384,8 @@ public class LocalHTTPD extends NanoHTTPD {
Response res;
try {
// Calculate etag
String etag = Integer.toHexString((file.getAbsolutePath() + file.lastModified() + "" + file.length()).hashCode());
String etag =
Integer.toHexString((file.getAbsolutePath() + file.lastModified() + "" + file.length()).hashCode());
// Support (simple) skipping:
long startFrom = 0;
@ -412,7 +411,8 @@ public class LocalHTTPD extends NanoHTTPD {
boolean headerIfRangeMissingOrMatching = (ifRange == null || etag.equals(ifRange));
String ifNoneMatch = header.get("if-none-match");
boolean headerIfNoneMatchPresentAndMatching = ifNoneMatch != null && ("*".equals(ifNoneMatch) || ifNoneMatch.equals(etag));
boolean headerIfNoneMatchPresentAndMatching =
ifNoneMatch != null && ("*".equals(ifNoneMatch) || ifNoneMatch.equals(etag));
// Change return code and add Content-Range header when skipping is
// requested

View File

@ -8,14 +8,14 @@ import android.os.Message;
import android.os.Process;
import android.util.Log;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences;
import java.io.IOException;
import java.net.BindException;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/**
* Manage {@link LocalHTTPD} in a {@link HandlerThread};
*/

View File

@ -165,7 +165,8 @@ public final class LocalRepoKeyStore {
keyManagers = new KeyManager[]{
wrappedKeyManager,
};
} catch (UnrecoverableKeyException | KeyStoreException | NoSuchAlgorithmException | CertificateException | OperatorCreationException | IOException e) {
} catch (UnrecoverableKeyException | KeyStoreException | NoSuchAlgorithmException |
CertificateException | OperatorCreationException | IOException e) {
Log.e(TAG, "Error loading keystore", e);
}
}
@ -215,7 +216,8 @@ public final class LocalRepoKeyStore {
zipSigner.setKeys("kerplapp", cert, priv, DEFAULT_SIG_ALG, null);
zipSigner.signZip(input.getAbsolutePath(), output.getAbsolutePath());
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException | GeneralSecurityException | IOException e) {
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException |
GeneralSecurityException | IOException e) {
Log.e(TAG, "Unable to sign local repo index", e);
}
}

View File

@ -6,6 +6,9 @@ import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.apache.commons.io.FileUtils;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences;
@ -40,9 +43,6 @@ import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* The {@link SwapService} deals with managing the entire workflow from selecting apps to
* swap, to invoking this class to prepare the webroot, to enabling various communication protocols.

View File

@ -6,6 +6,8 @@ import android.content.Intent;
import android.os.Process;
import android.util.Log;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils;
@ -14,8 +16,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/**
* Handles setting up and generating the local repo used to swap apps, including
* the {@code index.jar}, the symlinks to the shared APKs, etc.

View File

@ -25,11 +25,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Process;
import android.util.Log;
import androidx.core.content.ContextCompat;
import org.fdroid.fdroid.Utils;
import org.fdroid.index.SigningException;
import org.fdroid.index.v1.IndexV1UpdaterKt;
@ -44,8 +45,6 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import androidx.core.content.ContextCompat;
/**
* An {@link IntentService} subclass for scanning removable "external storage"
* for F-Droid package repos, e.g. SD Cards. This is intended to support

View File

@ -2,7 +2,6 @@ package org.fdroid.fdroid.nearby;
import static java.util.Objects.requireNonNull;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@ -13,10 +12,8 @@ import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
@ -63,11 +60,7 @@ public class SelectAppsView extends SwapView {
listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
toggleAppSelected(position);
}
});
listView.setOnItemClickListener((parent, v, position, id) -> toggleAppSelected(position));
afterAppsLoaded();
}
@ -129,7 +122,7 @@ public class SelectAppsView extends SwapView {
filteredPackages.addAll(allPackages);
} else {
String query = requireNonNull(searchTerm).toLowerCase(Locale.US);
for (InstalledApp app: allPackages) {
for (InstalledApp app : allPackages) {
if (app.name.toLowerCase(Locale.US).contains(query)) {
filteredPackages.add(app);
}
@ -190,12 +183,9 @@ public class SelectAppsView extends SwapView {
checkBox.setOnCheckedChangeListener(null);
checkBox.setChecked(listView.isItemChecked(position));
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
listView.setItemChecked(position, isChecked);
toggleAppSelected(position);
}
checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
listView.setItemChecked(position, isChecked);
toggleAppSelected(position);
});
}
}

View File

@ -1,7 +1,6 @@
package org.fdroid.fdroid.nearby;
import android.Manifest;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -14,7 +13,6 @@ import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ImageView;
@ -22,6 +20,10 @@ import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.switchmaterial.SwitchMaterial;
@ -32,9 +34,6 @@ import org.fdroid.fdroid.nearby.peers.Peer;
import java.util.ArrayList;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import cc.mvdan.accesspoint.WifiApControl;
@SuppressWarnings("LineLength")
@ -131,12 +130,7 @@ public class StartSwapView extends SwapView {
private void uiInitButtons() {
MaterialButton sendFDroidButton = findViewById(R.id.btn_send_fdroid);
sendFDroidButton.setEllipsize(TextUtils.TruncateAt.END);
findViewById(R.id.btn_send_fdroid).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
getActivity().sendFDroid();
}
});
findViewById(R.id.btn_send_fdroid).setOnClickListener(v -> getActivity().sendFDroid());
}
/**
@ -160,12 +154,9 @@ public class StartSwapView extends SwapView {
}
}
peopleNearbyList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Peer peer = peopleNearbyAdapter.getItem(position);
onPeerSelected(peer);
}
peopleNearbyList.setOnItemClickListener((parent, view, position, id) -> {
Peer peer = peopleNearbyAdapter.getItem(position);
onPeerSelected(peer);
});
}

View File

@ -15,8 +15,14 @@ import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.app.ServiceCompat;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.fdroid.database.Repository;
import org.fdroid.download.Downloader;
@ -49,18 +55,11 @@ import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.app.ServiceCompat;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import cc.mvdan.accesspoint.WifiApControl;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import kotlin.Pair;
/**
* Central service which manages all of the different moving parts of swap
@ -396,30 +395,30 @@ public class SwapService extends Service {
private void askServerToSwapWithUs(final Repository repo) {
compositeDisposable.add(
Completable.fromAction(() -> {
String swapBackUri = Utils.getLocalRepoUri(FDroidApp.repo).toString();
HttpURLConnection conn = null;
try {
URL url = new URL(repo.getAddress().replace("/fdroid/repo", "/request-swap"));
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
String swapBackUri = Utils.getLocalRepoUri(FDroidApp.repo).toString();
HttpURLConnection conn = null;
try {
URL url = new URL(repo.getAddress().replace("/fdroid/repo", "/request-swap"));
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
try (OutputStream outputStream = conn.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(outputStream)) {
writer.write("repo=" + swapBackUri);
writer.flush();
}
try (OutputStream outputStream = conn.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(outputStream)) {
writer.write("repo=" + swapBackUri);
writer.flush();
}
int responseCode = conn.getResponseCode();
Utils.debugLog(TAG, "Asking server at " + repo.getAddress() + " to swap with us in return (by " +
"POSTing to \"/request-swap\" with repo \"" + swapBackUri + "\"): " + responseCode);
} finally {
if (conn != null) {
conn.disconnect();
}
}
})
int responseCode = conn.getResponseCode();
Utils.debugLog(TAG, "Asking server at " + repo.getAddress() + " to swap with us in return (by " +
"POSTing to \"/request-swap\" with repo \"" + swapBackUri + "\"): " + responseCode);
} finally {
if (conn != null) {
conn.disconnect();
}
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.onErrorComplete(e -> {
@ -567,12 +566,7 @@ public class SwapService extends Service {
}
}
private final Preferences.ChangeListener httpsEnabledListener = new Preferences.ChangeListener() {
@Override
public void onPreferenceChange() {
restartWiFiServices();
}
};
private final Preferences.ChangeListener httpsEnabledListener = this::restartWiFiServices;
private final BroadcastReceiver onWifiChange = new BroadcastReceiver() {
@Override

View File

@ -1,6 +1,5 @@
package org.fdroid.fdroid.nearby;
import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -101,7 +100,7 @@ public class SwapSuccessView extends SwapView {
app.packageName = a.getPackageName();
app.iconFile = FileV2.fromPath("icons/" + a.getIcon());
try {
PackageInfo packageInfo = getContext().getPackageManager().getPackageInfo(app.packageName, 0);
PackageInfo packageInfo = getContext().getPackageManager().getPackageInfo(app.packageName, 0);
app.installedVersionCode = packageInfo.versionCode;
} catch (PackageManager.NameNotFoundException ignored) {
}
@ -222,12 +221,12 @@ public class SwapSuccessView extends SwapView {
ViewHolder(View view) {
super(view);
localBroadcastManager = LocalBroadcastManager.getInstance(getContext());
progressView = (ProgressBar) view.findViewById(R.id.progress);
nameView = (TextView) view.findViewById(R.id.name);
iconView = (ImageView) view.findViewById(android.R.id.icon);
btnInstall = (Button) view.findViewById(R.id.btn_install);
statusInstalled = (TextView) view.findViewById(R.id.status_installed);
statusIncompatible = (TextView) view.findViewById(R.id.status_incompatible);
progressView = view.findViewById(R.id.progress);
nameView = view.findViewById(R.id.name);
iconView = view.findViewById(android.R.id.icon);
btnInstall = view.findViewById(R.id.btn_install);
statusInstalled = view.findViewById(R.id.status_installed);
statusIncompatible = view.findViewById(R.id.status_incompatible);
}
public void setApp(@NonNull App app) {
@ -389,16 +388,9 @@ public class SwapSuccessView extends SwapView {
@Override
public void onReceive(Context context, Intent intent) {
int statusCode = intent.getIntExtra(UpdateService.EXTRA_STATUS_CODE, -1);
switch (statusCode) {
case UpdateService.STATUS_COMPLETE_WITH_CHANGES:
Utils.debugLog(TAG, "Swap repo has updates, notifying the list adapter.");
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
}
});
break;
if (statusCode == UpdateService.STATUS_COMPLETE_WITH_CHANGES) {
Utils.debugLog(TAG, "Swap repo has updates, notifying the list adapter.");
getActivity().runOnUiThread(() -> adapter.notifyDataSetChanged());
}
}
};

View File

@ -1,17 +1,16 @@
package org.fdroid.fdroid.nearby;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
import org.fdroid.fdroid.R;
import androidx.annotation.ColorInt;
import androidx.annotation.LayoutRes;
import androidx.core.content.ContextCompat;
import org.fdroid.fdroid.R;
/**
* A {@link android.view.View} that registers to handle the swap events from
* {@link SwapService}.

View File

@ -1,11 +1,11 @@
package org.fdroid.fdroid.nearby;
import android.annotation.TargetApi;
import static org.fdroid.fdroid.views.main.MainActivity.ACTION_REQUEST_SWAP;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
@ -27,13 +27,22 @@ import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.switchmaterial.SwitchMaterial;
@ -62,20 +71,9 @@ import java.util.Stack;
import java.util.Timer;
import java.util.TimerTask;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import cc.mvdan.accesspoint.WifiApControl;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import static org.fdroid.fdroid.views.main.MainActivity.ACTION_REQUEST_SWAP;
/**
* This is the core of the UI for the whole nearby swap experience. Each
* screen is implemented as a {@link View} with the related logic in this
@ -334,16 +332,13 @@ public class SwapWorkflowActivity extends AppCompatActivity {
next.setIcon(drawableResId);
}
next.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
next.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
sendNext();
return true;
}
next.setOnMenuItemClickListener(item -> {
sendNext();
return true;
});
}
void sendNext() {
private void sendNext() {
int currentLayoutResId = currentView.getLayoutResId();
switch (currentLayoutResId) {
case R.layout.swap_select_apps:
@ -470,36 +465,27 @@ public class SwapWorkflowActivity extends AppCompatActivity {
&& FDroidApp.subnetInfo.isInRange(host); // on the same subnet as we are
}
public void promptToSelectWifiNetwork() {
private void promptToSelectWifiNetwork() {
new AlertDialog.Builder(this)
.setTitle(R.string.swap_join_same_wifi)
.setMessage(R.string.swap_join_same_wifi_desc)
.setNeutralButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Do nothing
}
.setNeutralButton(R.string.cancel, (dialog, which) -> {
// Do nothing
})
.setPositiveButton(R.string.wifi, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SwapService.putWifiEnabledBeforeSwap(wifiManager.isWifiEnabled());
wifiManager.setWifiEnabled(true);
Intent intent = new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
.setPositiveButton(R.string.wifi, (dialog, which) -> {
SwapService.putWifiEnabledBeforeSwap(wifiManager.isWifiEnabled());
wifiManager.setWifiEnabled(true);
Intent intent = new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
})
.setNegativeButton(R.string.wifi_ap, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= 26) {
showTetheringSettings();
} else if (!Settings.System.canWrite(getBaseContext())) {
requestWriteSettingsPermission();
} else {
setupWifiAP();
}
.setNegativeButton(R.string.wifi_ap, (dialog, which) -> {
if (Build.VERSION.SDK_INT >= 26) {
showTetheringSettings();
} else if (!Settings.System.canWrite(getBaseContext())) {
requestWriteSettingsPermission();
} else {
setupWifiAP();
}
})
.create().show();
@ -1051,12 +1037,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
// TODO: Listen for "Connecting..." state and reflect that in the view too.
private void setUpJoinWifi() {
currentView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK));
}
});
currentView.setOnClickListener(v -> startActivity(new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK)));
TextView descriptionView = container.findViewById(R.id.text_description);
ImageView wifiIcon = container.findViewById(R.id.wifi_icon);
TextView ssidView = container.findViewById(R.id.wifi_ssid);
@ -1098,21 +1079,18 @@ public class SwapWorkflowActivity extends AppCompatActivity {
}
viewWifiNetwork.setOnClickListener(v -> promptToSelectWifiNetwork());
wifiSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Context context = getApplicationContext();
if (isChecked) {
if (wifiApControl != null && wifiApControl.isEnabled()) {
setupWifiAP();
} else {
wifiManager.setWifiEnabled(true);
}
BonjourManager.start(context);
wifiSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
Context context = getApplicationContext();
if (isChecked) {
if (wifiApControl != null && wifiApControl.isEnabled()) {
setupWifiAP();
} else {
wifiManager.setWifiEnabled(true);
}
BonjourManager.setVisible(context, isChecked);
SwapService.putWifiVisibleUserPreference(isChecked);
BonjourManager.start(context);
}
BonjourManager.setVisible(context, isChecked);
SwapService.putWifiVisibleUserPreference(isChecked);
});
scanQrButton.setOnClickListener(v -> inflateSwapView(R.layout.swap_wifi_qr));

View File

@ -19,17 +19,17 @@
package org.fdroid.fdroid.nearby;
import android.annotation.TargetApi;
import android.app.IntentService;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Process;
import android.util.Log;
import android.widget.Toast;
import androidx.documentfile.provider.DocumentFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.fdroid.database.Repository;
@ -53,8 +53,6 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import androidx.documentfile.provider.DocumentFile;
/**
* An {@link IntentService} subclass for handling asynchronous scanning of a
* removable storage device like an SD Card or USB OTG thumb drive using the

View File

@ -27,15 +27,12 @@ import android.content.UriPermission;
import android.database.ContentObserver;
import android.hardware.usb.UsbManager;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import org.fdroid.fdroid.views.main.NearbyViewBinder;
import androidx.annotation.RequiresApi;
/**
* This is just a shim to receive {@link UsbManager#ACTION_USB_ACCESSORY_ATTACHED}

View File

@ -26,7 +26,6 @@ import android.content.Intent;
import android.database.ContentObserver;
import android.hardware.usb.UsbManager;
import android.net.Uri;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
@ -34,8 +33,6 @@ import org.fdroid.fdroid.views.main.NearbyViewBinder;
import java.util.HashMap;
import androidx.annotation.RequiresApi;
/**
* This is just a shim to receive {@link UsbManager#ACTION_USB_DEVICE_DETACHED}
* events.

View File

@ -10,6 +10,19 @@ import android.net.wifi.WifiManager;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.work.Constraints;
import androidx.work.Data;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import androidx.work.WorkRequest;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import org.apache.commons.net.util.SubnetUtils;
import org.fdroid.database.Repository;
import org.fdroid.fdroid.BuildConfig;
@ -28,18 +41,6 @@ import java.security.cert.Certificate;
import java.util.Enumeration;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.work.Constraints;
import androidx.work.Data;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import androidx.work.WorkRequest;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import cc.mvdan.accesspoint.WifiApControl;
/**

View File

@ -5,10 +5,10 @@ import android.bluetooth.BluetoothDevice;
import android.os.Parcel;
import android.text.TextUtils;
import org.fdroid.fdroid.R;
import androidx.annotation.Nullable;
import org.fdroid.fdroid.R;
public class BluetoothPeer implements Peer {
private static final String BLUETOOTH_NAME_TAG = "FDroid:";

View File

@ -4,13 +4,13 @@ import android.net.Uri;
import android.os.Parcel;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import org.fdroid.fdroid.FDroidApp;
import javax.jmdns.ServiceInfo;
import javax.jmdns.impl.FDroidServiceInfo;
import androidx.annotation.Nullable;
public class BonjourPeer extends WifiPeer {
private static final String TAG = "BonjourPeer";

View File

@ -6,6 +6,9 @@ import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.appbar.MaterialToolbar;
import org.fdroid.fdroid.FDroidApp;
@ -13,9 +16,6 @@ import org.fdroid.fdroid.R;
import java.util.regex.Pattern;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
/**
* A very hacky calculator which is barely functional.
* It is just meant to pass a very casual inspection.

View File

@ -3,12 +3,12 @@ package org.fdroid.fdroid.panic;
import android.content.Context;
import android.util.AttributeSet;
import org.fdroid.fdroid.R;
import androidx.core.content.ContextCompat;
import androidx.preference.CheckBoxPreference;
import androidx.preference.PreferenceViewHolder;
import org.fdroid.fdroid.R;
public class DestructiveCheckBoxPreference extends CheckBoxPreference {
public DestructiveCheckBoxPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);

View File

@ -3,12 +3,12 @@ package org.fdroid.fdroid.panic;
import android.content.Context;
import android.util.AttributeSet;
import org.fdroid.fdroid.R;
import androidx.core.content.ContextCompat;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import org.fdroid.fdroid.R;
public class DestructivePreference extends Preference {
public DestructivePreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);

View File

@ -1,7 +1,6 @@
package org.fdroid.fdroid.panic;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
@ -17,19 +16,16 @@ public class ExitActivity extends AppCompatActivity {
System.exit(0);
}
public static void exitAndRemoveFromRecentApps(final AppCompatActivity activity) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(activity, ExitActivity.class);
static void exitAndRemoveFromRecentApps(final AppCompatActivity activity) {
activity.runOnUiThread(() -> {
Intent intent = new Intent(activity, ExitActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
| Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NO_ANIMATION);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
| Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NO_ANIMATION);
activity.startActivity(intent);
}
activity.startActivity(intent);
});
}

View File

@ -2,19 +2,18 @@ package org.fdroid.fdroid.panic;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.NotificationManagerCompat;
import org.fdroid.fdroid.BuildConfig;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.views.main.MainActivity;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.NotificationManagerCompat;
/**
* This class is encapsulating all methods related to hiding the app from the launcher
* and restoring it.
@ -47,18 +46,8 @@ public class HidingManager {
builder.setMessage(context.getString(R.string.hiding_dialog_message, appName,
HidingManager.getUnhidePin(context), context.getString(R.string.hiding_calculator)));
builder.setPositiveButton(context.getString(R.string.panic_hide_title, appName),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
hide(context);
}
});
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
(dialog, which) -> hide(context));
builder.setNegativeButton(R.string.cancel, (dialogInterface, i) -> dialogInterface.cancel());
builder.setView(R.layout.dialog_app_hiding);
builder.create().show();
}

View File

@ -1,15 +1,14 @@
package org.fdroid.fdroid.panic;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.appbar.MaterialToolbar;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R;
import androidx.appcompat.app.AppCompatActivity;
public class PanicPreferencesActivity extends AppCompatActivity {
@Override

View File

@ -54,20 +54,20 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
public void onCreatePreferences(Bundle bundle, String s) {
addPreferencesFromResource(R.xml.preferences_panic);
pm = getActivity().getPackageManager();
prefExit = (CheckBoxPreference) findPreference(Preferences.PREF_PANIC_EXIT);
prefApp = (ListPreference) findPreference(PREF_APP);
prefHide = (CheckBoxPreference) findPreference(Preferences.PREF_PANIC_HIDE);
pm = requireActivity().getPackageManager();
prefExit = findPreference(Preferences.PREF_PANIC_EXIT);
prefApp = findPreference(PREF_APP);
prefHide = 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");
prefResetRepos = findPreference(Preferences.PREF_PANIC_RESET_REPOS);
categoryAppsToUninstall = findPreference("pref_panic_apps_to_uninstall");
if (PanicResponder.checkForDisconnectIntent(getActivity())) {
if (PanicResponder.checkForDisconnectIntent(requireActivity())) {
// the necessary action should have been performed by the check already
getActivity().finish();
requireActivity().finish();
return;
}
String connectIntentSender = PanicResponder.getConnectIntentSender(getActivity());
String connectIntentSender = PanicResponder.getConnectIntentSender(requireActivity());
// if there's a connecting app and it is not the old one
if (!TextUtils.isEmpty(connectIntentSender) && !TextUtils.equals(connectIntentSender, PanicResponder
.getTriggerPackageName(getActivity()))) {
@ -75,24 +75,21 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
showOptInDialog();
}
prefApp.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String packageName = (String) newValue;
PanicResponder.setTriggerPackageName(getActivity(), packageName);
if (packageName.equals(Panic.PACKAGE_NAME_NONE)) {
prefHide.setChecked(false);
prefHide.setEnabled(false);
prefResetRepos.setChecked(false);
prefResetRepos.setEnabled(false);
getActivity().setResult(AppCompatActivity.RESULT_CANCELED);
} else {
prefHide.setEnabled(true);
prefResetRepos.setEnabled(true);
}
showPanicApp(packageName);
return true;
prefApp.setOnPreferenceChangeListener((preference, newValue) -> {
String packageName = (String) newValue;
PanicResponder.setTriggerPackageName(requireActivity(), packageName);
if (packageName.equals(Panic.PACKAGE_NAME_NONE)) {
prefHide.setChecked(false);
prefHide.setEnabled(false);
prefResetRepos.setChecked(false);
prefResetRepos.setEnabled(false);
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED);
} else {
prefHide.setEnabled(true);
prefResetRepos.setEnabled(true);
}
showPanicApp(packageName);
return true;
});
showPanicApp(PanicResponder.getTriggerPackageName(getActivity()));
}
@ -181,17 +178,14 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
if (entries.size() <= 1) {
// bring the user to Ripple if no other panic apps are available
prefApp.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id=info.guardianproject.ripple"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivity(intent);
}
return true;
prefApp.setOnPreferenceClickListener(preference -> {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id=info.guardianproject.ripple"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (intent.resolveActivity(requireActivity().getPackageManager()) != null) {
startActivity(intent);
}
return true;
});
}
@ -201,9 +195,9 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
prefApp.setSummary(getString(R.string.panic_app_setting_summary));
prefApp.setIcon(null); // otherwise re-setting view resource doesn't work
Drawable icon = ContextCompat.getDrawable(getActivity(), R.drawable.ic_cancel);
Drawable icon = ContextCompat.getDrawable(requireActivity(), R.drawable.ic_cancel);
TypedValue typedValue = new TypedValue();
Resources.Theme theme = getActivity().getTheme();
Resources.Theme theme = requireActivity().getTheme();
theme.resolveAttribute(R.attr.appListItem, typedValue, true);
@ColorInt int color = typedValue.data;
icon.setColorFilter(color, PorterDuff.Mode.SRC_IN);
@ -223,30 +217,24 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
showWipeList();
} catch (PackageManager.NameNotFoundException e) {
// revert back to no app, just to be safe
PanicResponder.setTriggerPackageName(getActivity(), Panic.PACKAGE_NAME_NONE);
PanicResponder.setTriggerPackageName(requireActivity(), Panic.PACKAGE_NAME_NONE);
showPanicApp(Panic.PACKAGE_NAME_NONE);
}
}
}
private void showOptInDialog() {
DialogInterface.OnClickListener okListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
PanicResponder.setTriggerPackageName(getActivity());
showPanicApp(PanicResponder.getTriggerPackageName(getActivity()));
getActivity().setResult(AppCompatActivity.RESULT_OK);
}
DialogInterface.OnClickListener okListener = (dialogInterface, i) -> {
PanicResponder.setTriggerPackageName(requireActivity());
showPanicApp(PanicResponder.getTriggerPackageName(getActivity()));
requireActivity().setResult(AppCompatActivity.RESULT_OK);
};
DialogInterface.OnClickListener cancelListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
getActivity().setResult(AppCompatActivity.RESULT_CANCELED);
getActivity().finish();
}
DialogInterface.OnClickListener cancelListener = (dialogInterface, i) -> {
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED);
requireActivity().finish();
};
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
builder.setTitle(getString(R.string.panic_app_dialog_title));
CharSequence app = getString(R.string.panic_app_unknown_app);
@ -268,7 +256,7 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
@Nullable
private String getCallingPackageName() {
ComponentName componentName = getActivity().getCallingActivity();
ComponentName componentName = requireActivity().getCallingActivity();
String packageName = null;
if (componentName != null) {
packageName = componentName.getPackageName();
@ -278,31 +266,20 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
private void showHideConfirmationDialog() {
String appName = getString(R.string.app_name);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
builder.setTitle(R.string.panic_hide_warning_title);
builder.setMessage(getString(R.string.panic_hide_warning_message, appName,
HidingManager.getUnhidePin(getActivity()), getString(R.string.hiding_calculator)));
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// enable "exit" if "hiding" gets enabled
prefExit.setChecked(true);
// dismiss, but not cancel dialog
dialogInterface.dismiss();
}
HidingManager.getUnhidePin(requireActivity()), getString(R.string.hiding_calculator)));
builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
// enable "exit" if "hiding" gets enabled
prefExit.setChecked(true);
// dismiss, but not cancel dialog
dialogInterface.dismiss();
});
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
prefHide.setChecked(false);
prefResetRepos.setChecked(false);
}
builder.setNegativeButton(R.string.cancel, (dialogInterface, i) -> dialogInterface.cancel());
builder.setOnCancelListener(dialogInterface -> {
prefHide.setChecked(false);
prefResetRepos.setChecked(false);
});
builder.setView(R.layout.dialog_app_hiding);
builder.create().show();

View File

@ -6,6 +6,9 @@ import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.App;
@ -19,8 +22,6 @@ import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import info.guardianproject.panic.Panic;
import info.guardianproject.panic.PanicResponder;

View File

@ -3,6 +3,9 @@ package org.fdroid.fdroid.panic;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.views.installed.InstalledAppListAdapter;
@ -10,9 +13,6 @@ import org.fdroid.fdroid.views.installed.InstalledAppListItemController;
import java.util.Set;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
public class SelectInstalledAppListAdapter extends InstalledAppListAdapter {
private final Set<String> selectedApps;

View File

@ -2,6 +2,10 @@ package org.fdroid.fdroid.panic;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import org.fdroid.fdroid.AppUpdateStatusManager;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.App;
@ -10,10 +14,6 @@ import org.fdroid.fdroid.views.installed.InstalledAppListItemController;
import java.util.Set;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
/**
* Shows the currently installed apps as a selectable list.
*/

View File

@ -26,6 +26,10 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.MaterialToolbar;
import org.fdroid.database.AppListItem;
@ -38,10 +42,6 @@ import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.data.DBHelper;
import org.fdroid.fdroid.views.installed.InstalledAppListAdapter;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class SelectInstalledAppsActivity extends AppCompatActivity {

View File

@ -2,15 +2,15 @@ package org.fdroid.fdroid.views.main;
import android.widget.FrameLayout;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.views.PreferencesFragment;
import org.fdroid.fdroid.views.updates.UpdatesViewBinder;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.views.PreferencesFragment;
import org.fdroid.fdroid.views.updates.UpdatesViewBinder;
/**
* Decides which view on the main screen to attach to a given {@link FrameLayout}. This class
* doesn't know which view it will be rendering at the time it is constructed. Rather, at some

View File

@ -22,6 +22,10 @@ import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.nearby.SDCardScannerService;
@ -30,11 +34,7 @@ import org.fdroid.fdroid.nearby.TreeUriScannerIntentService;
import java.io.File;
import java.util.List;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.util.concurrent.Executor;
/**
* A splash screen encouraging people to start the swap process. The swap
@ -81,16 +81,13 @@ public class NearbyViewBinder {
ImageView nearbySplash = swapView.findViewById(R.id.image);
Button startButton = swapView.findViewById(R.id.find_people_button);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final String coarseLocation = Manifest.permission.ACCESS_COARSE_LOCATION;
if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(activity, coarseLocation)) {
ActivityCompat.requestPermissions(activity, new String[]{coarseLocation},
MainActivity.REQUEST_LOCATION_PERMISSIONS);
} else {
ContextCompat.startForegroundService(activity, new Intent(activity, SwapService.class));
}
startButton.setOnClickListener(v -> {
final String coarseLocation = Manifest.permission.ACCESS_COARSE_LOCATION;
if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(activity, coarseLocation)) {
ActivityCompat.requestPermissions(activity, new String[]{coarseLocation},
MainActivity.REQUEST_LOCATION_PERMISSIONS);
} else {
ContextCompat.startForegroundService(activity, new Intent(activity, SwapService.class));
}
});
@ -116,18 +113,17 @@ public class NearbyViewBinder {
readExternalStorageText.setVisibility(View.VISIBLE);
Button requestReadExternalStorage = swapView.findViewById(R.id.request_read_external_storage_button);
requestReadExternalStorage.setVisibility(View.VISIBLE);
requestReadExternalStorage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if ((externalStorage == null || !externalStorage.canRead()) && PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(activity, writeExternalStorage)) {
ActivityCompat.requestPermissions(activity, new String[]{writeExternalStorage},
MainActivity.REQUEST_STORAGE_PERMISSIONS);
} else {
Toast.makeText(activity,
activity.getString(R.string.scan_removable_storage_toast, externalStorage),
Toast.LENGTH_SHORT).show();
SDCardScannerService.scan(activity);
}
requestReadExternalStorage.setOnClickListener(v -> {
if ((externalStorage == null || !externalStorage.canRead())
&& PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(activity,
writeExternalStorage)) {
ActivityCompat.requestPermissions(activity, new String[]{writeExternalStorage},
MainActivity.REQUEST_STORAGE_PERMISSIONS);
} else {
Toast.makeText(activity,
activity.getString(R.string.scan_removable_storage_toast, externalStorage),
Toast.LENGTH_SHORT).show();
SDCardScannerService.scan(activity);
}
});
}
@ -185,12 +181,10 @@ public class NearbyViewBinder {
}
requestStorageVolume.setVisibility(View.VISIBLE);
requestStorageVolume.setOnClickListener(new View.OnClickListener() {
@Override
@RequiresApi(api = 24)
public void onClick(View v) {
List<UriPermission> list = context.getContentResolver().getPersistedUriPermissions();
if (list != null) for (UriPermission uriPermission : list) {
requestStorageVolume.setOnClickListener(v -> {
List<UriPermission> list = context.getContentResolver().getPersistedUriPermissions();
if (list != null) {
for (UriPermission uriPermission : list) {
Uri uri = uriPermission.getUri();
if (uri.getPath().equals(String.format("/tree/%s:", storageVolume.getUuid()))) {
intent.setData(uri);
@ -198,23 +192,23 @@ public class NearbyViewBinder {
return;
}
}
}
AppCompatActivity activity = null;
if (context instanceof AppCompatActivity) {
activity = (AppCompatActivity) context;
} else if (swapView != null && swapView.getContext() instanceof AppCompatActivity) {
activity = (AppCompatActivity) swapView.getContext();
}
AppCompatActivity activity = null;
if (context instanceof AppCompatActivity) {
activity = (AppCompatActivity) context;
} else if (swapView != null && swapView.getContext() instanceof AppCompatActivity) {
activity = (AppCompatActivity) swapView.getContext();
}
if (activity != null) {
activity.startActivityForResult(intent, MainActivity.REQUEST_STORAGE_ACCESS);
} else {
// scan in the background without requesting permissions
Toast.makeText(context.getApplicationContext(),
context.getString(R.string.scan_removable_storage_toast, externalStorage),
Toast.LENGTH_SHORT).show();
SDCardScannerService.scan(context);
}
if (activity != null) {
activity.startActivityForResult(intent, MainActivity.REQUEST_STORAGE_ACCESS);
} else {
// scan in the background without requesting permissions
Toast.makeText(context.getApplicationContext(),
context.getString(R.string.scan_removable_storage_toast, externalStorage),
Toast.LENGTH_SHORT).show();
SDCardScannerService.scan(context);
}
});
}

View File

@ -5,5 +5,7 @@
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path android:fillColor="#000" android:pathData="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" />
<path
android:fillColor="#000"
android:pathData="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" />
</vector>

View File

@ -4,7 +4,7 @@
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="#FFFFFF"
android:pathData="M12,7c-0.55,0 -1,0.45 -1,1v3L8,11c-0.55,0 -1,0.45 -1,1s0.45,1 1,1h3v3c0,0.55 0.45,1 1,1s1,-0.45 1,-1v-3h3c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1h-3L13,8c0,-0.55 -0.45,-1 -1,-1zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M12,7c-0.55,0 -1,0.45 -1,1v3L8,11c-0.55,0 -1,0.45 -1,1s0.45,1 1,1h3v3c0,0.55 0.45,1 1,1s1,-0.45 1,-1v-3h3c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1h-3L13,8c0,-0.55 -0.45,-1 -1,-1zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z" />
</vector>

View File

@ -4,7 +4,7 @@
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="#FFFFFF"
android:pathData="M4,8h4L8,4L4,4v4zM10,20h4v-4h-4v4zM4,20h4v-4L4,16v4zM4,14h4v-4L4,10v4zM10,14h4v-4h-4v4zM16,4v4h4L20,4h-4zM10,8h4L14,4h-4v4zM16,14h4v-4h-4v4zM16,20h4v-4h-4v4z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M4,8h4L8,4L4,4v4zM10,20h4v-4h-4v4zM4,20h4v-4L4,16v4zM4,14h4v-4L4,10v4zM10,14h4v-4h-4v4zM16,4v4h4L20,4h-4zM10,8h4L14,4h-4v4zM16,14h4v-4h-4v4zM16,20h4v-4h-4v4z" />
</vector>

View File

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFF" android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/>
<vector android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="#FFFFFF"
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z" />
</vector>

View File

@ -4,7 +4,7 @@
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="#FFFFFF"
android:pathData="M17,7l-4.29,-4.29c-0.63,-0.63 -1.71,-0.19 -1.71,0.7v6.18L7.11,5.7c-0.39,-0.39 -1.02,-0.39 -1.41,0 -0.39,0.39 -0.39,1.02 0,1.41L10.59,12 5.7,16.89c-0.39,0.39 -0.39,1.02 0,1.41 0.39,0.39 1.02,0.39 1.41,0L11,14.41v6.18c0,0.89 1.08,1.34 1.71,0.71L17,17c0.39,-0.39 0.39,-1.02 0,-1.41L13.41,12 17,8.42c0.39,-0.39 0.39,-1.03 0,-1.42zM13,5.83l1.88,1.88L13,9.59L13,5.83zM14.88,16.29L13,18.17v-3.76l1.88,1.88z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M17,7l-4.29,-4.29c-0.63,-0.63 -1.71,-0.19 -1.71,0.7v6.18L7.11,5.7c-0.39,-0.39 -1.02,-0.39 -1.41,0 -0.39,0.39 -0.39,1.02 0,1.41L10.59,12 5.7,16.89c-0.39,0.39 -0.39,1.02 0,1.41 0.39,0.39 1.02,0.39 1.41,0L11,14.41v6.18c0,0.89 1.08,1.34 1.71,0.71L17,17c0.39,-0.39 0.39,-1.02 0,-1.41L13.41,12 17,8.42c0.39,-0.39 0.39,-1.03 0,-1.42zM13,5.83l1.88,1.88L13,9.59L13,5.83zM14.88,16.29L13,18.17v-3.76l1.88,1.88z" />
</vector>

View File

@ -4,7 +4,7 @@
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="#FFFFFF"
android:pathData="M15.98,10.28l-1.38,1.38c-0.2,0.2 -0.2,0.51 0,0.71l1.38,1.38c0.28,0.28 0.75,0.15 0.85,-0.23 0.11,-0.5 0.17,-1 0.17,-1.52 0,-0.51 -0.06,-1.01 -0.18,-1.48 -0.09,-0.38 -0.56,-0.52 -0.84,-0.24zM20.1,7.78c-0.25,-0.55 -0.98,-0.67 -1.4,-0.24 -0.26,0.26 -0.31,0.64 -0.17,0.98 0.46,1.07 0.72,2.24 0.72,3.47 0,1.24 -0.26,2.42 -0.73,3.49 -0.14,0.32 -0.09,0.69 0.16,0.94 0.41,0.41 1.1,0.29 1.35,-0.23 0.63,-1.3 0.98,-2.76 0.98,-4.3 -0.01,-1.45 -0.33,-2.85 -0.91,-4.11zM11.41,12L15,8.42c0.39,-0.39 0.39,-1.02 0,-1.42l-4.29,-4.29c-0.63,-0.63 -1.71,-0.19 -1.71,0.7v6.18L5.11,5.7c-0.39,-0.39 -1.02,-0.39 -1.41,0 -0.39,0.39 -0.39,1.02 0,1.41L8.59,12 3.7,16.89c-0.39,0.39 -0.39,1.02 0,1.41 0.39,0.39 1.02,0.39 1.41,0L9,14.41v6.18c0,0.89 1.08,1.34 1.71,0.71L15,17c0.39,-0.39 0.39,-1.02 0,-1.42L11.41,12zM11,5.83l1.88,1.88L11,9.59L11,5.83zM11,18.17v-3.76l1.88,1.88L11,18.17z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M15.98,10.28l-1.38,1.38c-0.2,0.2 -0.2,0.51 0,0.71l1.38,1.38c0.28,0.28 0.75,0.15 0.85,-0.23 0.11,-0.5 0.17,-1 0.17,-1.52 0,-0.51 -0.06,-1.01 -0.18,-1.48 -0.09,-0.38 -0.56,-0.52 -0.84,-0.24zM20.1,7.78c-0.25,-0.55 -0.98,-0.67 -1.4,-0.24 -0.26,0.26 -0.31,0.64 -0.17,0.98 0.46,1.07 0.72,2.24 0.72,3.47 0,1.24 -0.26,2.42 -0.73,3.49 -0.14,0.32 -0.09,0.69 0.16,0.94 0.41,0.41 1.1,0.29 1.35,-0.23 0.63,-1.3 0.98,-2.76 0.98,-4.3 -0.01,-1.45 -0.33,-2.85 -0.91,-4.11zM11.41,12L15,8.42c0.39,-0.39 0.39,-1.02 0,-1.42l-4.29,-4.29c-0.63,-0.63 -1.71,-0.19 -1.71,0.7v6.18L5.11,5.7c-0.39,-0.39 -1.02,-0.39 -1.41,0 -0.39,0.39 -0.39,1.02 0,1.41L8.59,12 3.7,16.89c-0.39,0.39 -0.39,1.02 0,1.41 0.39,0.39 1.02,0.39 1.41,0L9,14.41v6.18c0,0.89 1.08,1.34 1.71,0.71L15,17c0.39,-0.39 0.39,-1.02 0,-1.42L11.41,12zM11,5.83l1.88,1.88L11,9.59L11,5.83zM11,18.17v-3.76l1.88,1.88L11,18.17z" />
</vector>

View File

@ -4,37 +4,37 @@
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="#FFFFFF"
android:pathData="M5,11h4c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2H5C3.9,3 3,3.9 3,5v4C3,10.1 3.9,11 5,11zM5,5h4v4H5V5z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M5,21h4c1.1,0 2,-0.9 2,-2v-4c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v4C3,20.1 3.9,21 5,21zM5,15h4v4H5V15z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M13,5v4c0,1.1 0.9,2 2,2h4c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2h-4C13.9,3 13,3.9 13,5zM19,9h-4V5h4V9z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M21,20.5v-1c0,-0.28 -0.22,-0.5 -0.5,-0.5h-1c-0.28,0 -0.5,0.22 -0.5,0.5v1c0,0.28 0.22,0.5 0.5,0.5h1C20.78,21 21,20.78 21,20.5z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M13,13.5v1c0,0.28 0.22,0.5 0.5,0.5h1c0.28,0 0.5,-0.22 0.5,-0.5v-1c0,-0.28 -0.22,-0.5 -0.5,-0.5h-1C13.22,13 13,13.22 13,13.5z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M16.5,15h-1c-0.28,0 -0.5,0.22 -0.5,0.5v1c0,0.28 0.22,0.5 0.5,0.5h1c0.28,0 0.5,-0.22 0.5,-0.5v-1C17,15.22 16.78,15 16.5,15z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M13,17.5v1c0,0.28 0.22,0.5 0.5,0.5h1c0.28,0 0.5,-0.22 0.5,-0.5v-1c0,-0.28 -0.22,-0.5 -0.5,-0.5h-1C13.22,17 13,17.22 13,17.5z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M15.5,21h1c0.28,0 0.5,-0.22 0.5,-0.5v-1c0,-0.28 -0.22,-0.5 -0.5,-0.5h-1c-0.28,0 -0.5,0.22 -0.5,0.5v1C15,20.78 15.22,21 15.5,21z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M17.5,19h1c0.28,0 0.5,-0.22 0.5,-0.5v-1c0,-0.28 -0.22,-0.5 -0.5,-0.5h-1c-0.28,0 -0.5,0.22 -0.5,0.5v1C17,18.78 17.22,19 17.5,19z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M18.5,13h-1c-0.28,0 -0.5,0.22 -0.5,0.5v1c0,0.28 0.22,0.5 0.5,0.5h1c0.28,0 0.5,-0.22 0.5,-0.5v-1C19,13.22 18.78,13 18.5,13z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M19.5,17h1c0.28,0 0.5,-0.22 0.5,-0.5v-1c0,-0.28 -0.22,-0.5 -0.5,-0.5h-1c-0.28,0 -0.5,0.22 -0.5,0.5v1C19,16.78 19.22,17 19.5,17z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M5,11h4c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2H5C3.9,3 3,3.9 3,5v4C3,10.1 3.9,11 5,11zM5,5h4v4H5V5z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M5,21h4c1.1,0 2,-0.9 2,-2v-4c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v4C3,20.1 3.9,21 5,21zM5,15h4v4H5V15z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M13,5v4c0,1.1 0.9,2 2,2h4c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2h-4C13.9,3 13,3.9 13,5zM19,9h-4V5h4V9z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M21,20.5v-1c0,-0.28 -0.22,-0.5 -0.5,-0.5h-1c-0.28,0 -0.5,0.22 -0.5,0.5v1c0,0.28 0.22,0.5 0.5,0.5h1C20.78,21 21,20.78 21,20.5z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M13,13.5v1c0,0.28 0.22,0.5 0.5,0.5h1c0.28,0 0.5,-0.22 0.5,-0.5v-1c0,-0.28 -0.22,-0.5 -0.5,-0.5h-1C13.22,13 13,13.22 13,13.5z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M16.5,15h-1c-0.28,0 -0.5,0.22 -0.5,0.5v1c0,0.28 0.22,0.5 0.5,0.5h1c0.28,0 0.5,-0.22 0.5,-0.5v-1C17,15.22 16.78,15 16.5,15z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M13,17.5v1c0,0.28 0.22,0.5 0.5,0.5h1c0.28,0 0.5,-0.22 0.5,-0.5v-1c0,-0.28 -0.22,-0.5 -0.5,-0.5h-1C13.22,17 13,17.22 13,17.5z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M15.5,21h1c0.28,0 0.5,-0.22 0.5,-0.5v-1c0,-0.28 -0.22,-0.5 -0.5,-0.5h-1c-0.28,0 -0.5,0.22 -0.5,0.5v1C15,20.78 15.22,21 15.5,21z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M17.5,19h1c0.28,0 0.5,-0.22 0.5,-0.5v-1c0,-0.28 -0.22,-0.5 -0.5,-0.5h-1c-0.28,0 -0.5,0.22 -0.5,0.5v1C17,18.78 17.22,19 17.5,19z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M18.5,13h-1c-0.28,0 -0.5,0.22 -0.5,0.5v1c0,0.28 0.22,0.5 0.5,0.5h1c0.28,0 0.5,-0.22 0.5,-0.5v-1C19,13.22 18.78,13 18.5,13z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M19.5,17h1c0.28,0 0.5,-0.22 0.5,-0.5v-1c0,-0.28 -0.22,-0.5 -0.5,-0.5h-1c-0.28,0 -0.5,0.22 -0.5,0.5v1C19,16.78 19.22,17 19.5,17z" />
</vector>

View File

@ -6,5 +6,5 @@
android:tint="?attr/colorControlNormal">
<path
android:fillColor="#FFFFFF"
android:pathData="M12,11c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,13c0,-3.56 -3.11,-6.4 -6.75,-5.95 -2.62,0.32 -4.78,2.41 -5.18,5.02 -0.33,2.15 0.49,4.11 1.93,5.4 0.48,0.43 1.23,0.33 1.56,-0.23l0.01,-0.01c0.24,-0.42 0.14,-0.93 -0.22,-1.26 -1.03,-0.93 -1.59,-2.37 -1.22,-3.94 0.33,-1.42 1.48,-2.57 2.9,-2.91C13.65,8.49 16,10.47 16,13c0,1.18 -0.52,2.23 -1.33,2.96 -0.36,0.32 -0.47,0.84 -0.23,1.26l0.01,0.01c0.31,0.53 1.03,0.69 1.5,0.28C17.2,16.41 18,14.8 18,13zM10.83,3.07c-4.62,0.52 -8.35,4.33 -8.78,8.96 -0.35,3.7 1.32,7.02 4.02,9.01 0.48,0.35 1.16,0.2 1.46,-0.31 0.25,-0.43 0.14,-0.99 -0.26,-1.29 -2.28,-1.69 -3.65,-4.55 -3.16,-7.7 0.54,-3.5 3.46,-6.29 6.98,-6.68C15.91,4.51 20,8.28 20,13c0,2.65 -1.29,4.98 -3.27,6.44 -0.4,0.3 -0.51,0.85 -0.26,1.29 0.3,0.52 0.98,0.66 1.46,0.31C20.4,19.22 22,16.3 22,13c0,-5.91 -5.13,-10.62 -11.17,-9.93z"/>
android:pathData="M12,11c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,13c0,-3.56 -3.11,-6.4 -6.75,-5.95 -2.62,0.32 -4.78,2.41 -5.18,5.02 -0.33,2.15 0.49,4.11 1.93,5.4 0.48,0.43 1.23,0.33 1.56,-0.23l0.01,-0.01c0.24,-0.42 0.14,-0.93 -0.22,-1.26 -1.03,-0.93 -1.59,-2.37 -1.22,-3.94 0.33,-1.42 1.48,-2.57 2.9,-2.91C13.65,8.49 16,10.47 16,13c0,1.18 -0.52,2.23 -1.33,2.96 -0.36,0.32 -0.47,0.84 -0.23,1.26l0.01,0.01c0.31,0.53 1.03,0.69 1.5,0.28C17.2,16.41 18,14.8 18,13zM10.83,3.07c-4.62,0.52 -8.35,4.33 -8.78,8.96 -0.35,3.7 1.32,7.02 4.02,9.01 0.48,0.35 1.16,0.2 1.46,-0.31 0.25,-0.43 0.14,-0.99 -0.26,-1.29 -2.28,-1.69 -3.65,-4.55 -3.16,-7.7 0.54,-3.5 3.46,-6.29 6.98,-6.68C15.91,4.51 20,8.28 20,13c0,2.65 -1.29,4.98 -3.27,6.44 -0.4,0.3 -0.51,0.85 -0.26,1.29 0.3,0.52 0.98,0.66 1.46,0.31C20.4,19.22 22,16.3 22,13c0,-5.91 -5.13,-10.62 -11.17,-9.93z" />
</vector>

View File

@ -1,6 +1,12 @@
<vector android:height="24dp" android:viewportHeight="634.0"
android:viewportWidth="720.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillAlpha="1" android:fillColor="#f9f9f9"
<vector android:height="24dp"
android:viewportHeight="634.0"
android:viewportWidth="720.0"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillAlpha="1"
android:fillColor="#f9f9f9"
android:pathData="M105,0L105,321.3L0,387.7L0,405.9L105,339.5L105,392L104.6,392L104.6,407.5L105,407.5L105,633L120,633L120,407.5L209,407.5L209,633L224,633L224,407.5L393,407.5L498.7,633.1L514.6,633.6L408.7,407.5L624.5,407.5L624.5,633L639.5,633L639.5,470.5L720,435.9L720,419L639.5,453.6L639.5,67.1L720,67.1L720,51.5L120,51.5L120,0L105,0zM120,67.1L233.4,67.1L385.7,392L120,392L120,67.1zM249.1,67.1L624.5,67.1L624.5,392L401.4,392L249.1,67.1z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>

View File

@ -1,34 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="130dp"
android:layout_alignParentTop="true"
tools:showIn="@layout/swap_start_swap">
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="130dp"
android:layout_alignParentTop="true"
tools:showIn="@layout/swap_start_swap">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:srcCompat="@drawable/swap_start_header"/>
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:srcCompat="@drawable/swap_start_header" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:padding="20dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:paddingEnd="30dp"
android:gravity="center"
android:textAlignment="center"
android:text="@string/swap_intro"
android:textColor="@android:color/white"
android:textSize="18sp"
tools:ignore="UnusedAttribute"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:padding="20dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:paddingEnd="30dp"
android:gravity="center"
android:textAlignment="center"
android:text="@string/swap_intro"
android:textColor="@android:color/white"
android:textSize="18sp"
tools:ignore="UnusedAttribute" />
</RelativeLayout>

View File

@ -1,301 +1,300 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".panic.CalculatorActivity"
android:fitsSystemWindows="true">
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".panic.CalculatorActivity"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/topAppBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:liftOnScroll="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
android:id="@+id/topAppBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:liftOnScroll="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" />
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" />
</com.google.android.material.appbar.AppBarLayout>
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:gravity="bottom|end"
android:padding="5dp"
android:textAlignment="textEnd"
android:textSize="22sp"
android:typeface="monospace"
app:layout_constraintBottom_toTopOf="@+id/ce"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/topAppBarLayout"
tools:text="1337+42" />
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:gravity="bottom|end"
android:padding="5dp"
android:textAlignment="textEnd"
android:textSize="22sp"
android:typeface="monospace"
app:layout_constraintBottom_toTopOf="@+id/ce"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/topAppBarLayout"
tools:text="1337+42" />
<Button
android:id="@+id/times"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="op"
android:text="×"
app:layout_constraintBottom_toTopOf="@+id/seven"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" />
android:id="@+id/times"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="op"
android:text="×"
app:layout_constraintBottom_toTopOf="@+id/seven"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/divided"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="op"
android:text="÷"
app:layout_constraintBottom_toTopOf="@+id/eight"
app:layout_constraintStart_toEndOf="@+id/times"
tools:ignore="HardcodedText" />
android:id="@+id/divided"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="op"
android:text="÷"
app:layout_constraintBottom_toTopOf="@+id/eight"
app:layout_constraintStart_toEndOf="@+id/times"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/c"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="c"
android:text="C"
app:layout_constraintBottom_toTopOf="@+id/nine"
app:layout_constraintStart_toEndOf="@+id/divided"
tools:ignore="HardcodedText" />
android:id="@+id/c"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="c"
android:text="C"
app:layout_constraintBottom_toTopOf="@+id/nine"
app:layout_constraintStart_toEndOf="@+id/divided"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/seven"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="7"
app:layout_constraintBottom_toTopOf="@+id/four"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" />
android:id="@+id/seven"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="7"
app:layout_constraintBottom_toTopOf="@+id/four"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/eight"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="8"
app:layout_constraintBottom_toTopOf="@+id/five"
app:layout_constraintStart_toEndOf="@+id/seven"
tools:ignore="HardcodedText" />
android:id="@+id/eight"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="8"
app:layout_constraintBottom_toTopOf="@+id/five"
app:layout_constraintStart_toEndOf="@+id/seven"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/nine"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="9"
app:layout_constraintBottom_toTopOf="@+id/six"
app:layout_constraintStart_toEndOf="@+id/eight"
tools:ignore="HardcodedText" />
android:id="@+id/nine"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="9"
app:layout_constraintBottom_toTopOf="@+id/six"
app:layout_constraintStart_toEndOf="@+id/eight"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/ce"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:onClick="ce"
android:text="CE"
app:layout_constraintBottom_toTopOf="@+id/plus"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/nine"
tools:ignore="HardcodedText" />
android:id="@+id/ce"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:onClick="ce"
android:text="CE"
app:layout_constraintBottom_toTopOf="@+id/plus"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/nine"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/four"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="4"
app:layout_constraintBottom_toTopOf="@+id/one"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" />
android:id="@+id/four"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="4"
app:layout_constraintBottom_toTopOf="@+id/one"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/five"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="5"
app:layout_constraintBottom_toTopOf="@+id/two"
app:layout_constraintStart_toEndOf="@+id/four"
tools:ignore="HardcodedText" />
android:id="@+id/five"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="5"
app:layout_constraintBottom_toTopOf="@+id/two"
app:layout_constraintStart_toEndOf="@+id/four"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/six"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="6"
app:layout_constraintBottom_toTopOf="@+id/three"
app:layout_constraintStart_toEndOf="@+id/five"
tools:ignore="HardcodedText" />
android:id="@+id/six"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="6"
app:layout_constraintBottom_toTopOf="@+id/three"
app:layout_constraintStart_toEndOf="@+id/five"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/plus"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:onClick="op"
android:text="+"
app:layout_constraintBottom_toTopOf="@+id/minus"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/six"
tools:ignore="HardcodedText" />
android:id="@+id/plus"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:onClick="op"
android:text="+"
app:layout_constraintBottom_toTopOf="@+id/minus"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/six"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/minus"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:onClick="op"
android:text="-"
app:layout_constraintBottom_toTopOf="@+id/equals"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/three"
tools:ignore="HardcodedText" />
android:id="@+id/minus"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:onClick="op"
android:text="-"
app:layout_constraintBottom_toTopOf="@+id/equals"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/three"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/one"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="1"
app:layout_constraintBottom_toTopOf="@+id/zero"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" />
android:id="@+id/one"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="1"
app:layout_constraintBottom_toTopOf="@+id/zero"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/two"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="2"
app:layout_constraintBottom_toTopOf="@+id/comma"
app:layout_constraintStart_toEndOf="@+id/one"
tools:ignore="HardcodedText" />
android:id="@+id/two"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="2"
app:layout_constraintBottom_toTopOf="@+id/comma"
app:layout_constraintStart_toEndOf="@+id/one"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/three"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="3"
app:layout_constraintBottom_toTopOf="@+id/percent"
app:layout_constraintStart_toEndOf="@+id/two"
tools:ignore="HardcodedText" />
android:id="@+id/three"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="3"
app:layout_constraintBottom_toTopOf="@+id/percent"
app:layout_constraintStart_toEndOf="@+id/two"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/zero"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" />
android:id="@+id/zero"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/comma"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="."
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/zero"
tools:ignore="HardcodedText" />
android:id="@+id/comma"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="number"
android:text="."
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/zero"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/percent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="op"
android:text="%"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/comma"
tools:ignore="HardcodedText" />
android:id="@+id/percent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="op"
android:text="%"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/comma"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/equals"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:onClick="op"
android:text="="
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/three"
app:layout_constraintTop_toTopOf="@+id/three"
tools:ignore="HardcodedText" />
android:id="@+id/equals"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:onClick="op"
android:text="="
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/three"
app:layout_constraintTop_toTopOf="@+id/three"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,31 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:liftOnScroll="true">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:liftOnScroll="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/panic_settings"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" />
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/panic_settings"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
class="org.fdroid.fdroid.panic.PanicPreferencesFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:id="@+id/fragment_container"
class="org.fdroid.fdroid.panic.PanicPreferencesFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@ -1,18 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".views.main.MainActivity"
android:background="?attr/mainTabSwapBackground">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".views.main.MainActivity"
android:background="?attr/mainTabSwapBackground">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
<ImageView
android:id="@+id/image"
android:layout_width="0dp"
android:layout_height="0dp"
@ -25,9 +24,9 @@
android:layout_marginTop="36dp"
app:tint="?attr/mainTabSwapSplashTint"
android:scaleType="fitXY"
tools:targetApi="jelly_bean"/>
tools:targetApi="jelly_bean" />
<TextView
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
@ -41,9 +40,9 @@
android:textColor="?attr/lightGrayTextColor"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
app:layout_constraintTop_toTopOf="parent" />
<Button
<Button
android:id="@+id/find_people_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -53,9 +52,11 @@
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="24dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp"/>
android:layout_marginTop="24dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp" />
<TextView
<TextView
android:id="@+id/both_parties_need_fdroid_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
@ -69,9 +70,9 @@
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="24dp"
android:layout_marginRight="24dp"
android:layout_marginLeft="24dp"/>
android:layout_marginLeft="24dp" />
<TextView
<TextView
android:id="@+id/read_external_storage_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
@ -81,14 +82,18 @@
android:textColor="?attr/lightGrayTextColor"
android:textAlignment="center"
android:gravity="center"
android:layout_marginEnd="24dp" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginRight="24dp"
android:layout_marginStart="24dp" app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="24dp" android:layout_marginTop="48dp"
android:layout_marginStart="24dp"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="24dp"
android:layout_marginTop="48dp"
app:layout_constraintTop_toBottomOf="@+id/both_parties_need_fdroid_text"
android:visibility="gone"
tools:visibility="visible"/>
<Button
tools:visibility="visible" />
<Button
android:id="@+id/request_read_external_storage_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -96,14 +101,17 @@
android:text="@string/nearby_splash__request_permission"
style="@style/DetailsSecondaryButtonStyle"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp" android:layout_marginRight="8dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginTop="24dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="24dp"
app:layout_constraintTop_toBottomOf="@+id/read_external_storage_text"
android:visibility="gone"
tools:visibility="visible"/>
tools:visibility="visible" />
<TextView
<TextView
android:id="@+id/storage_volume_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
@ -113,13 +121,17 @@
android:textColor="?attr/lightGrayTextColor"
android:textAlignment="center"
android:gravity="center"
android:layout_marginEnd="24dp" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginRight="24dp"
android:layout_marginStart="24dp" app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="24dp" android:layout_marginTop="48dp"
android:layout_marginStart="24dp"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="24dp"
android:layout_marginTop="48dp"
app:layout_constraintTop_toBottomOf="@+id/request_read_external_storage_button"
android:visibility="gone"/>
<Button
android:visibility="gone" />
<Button
android:id="@+id/request_storage_volume_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -127,11 +139,14 @@
android:text="@string/nearby_splash__request_permission"
style="@style/DetailsSecondaryButtonStyle"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp" android:layout_marginRight="8dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginTop="24dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="24dp"
app:layout_constraintTop_toBottomOf="@+id/storage_volume_text"
android:visibility="gone"/>
android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -46,7 +45,7 @@
android:layout_toStartOf="@id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:mode="twoLine" >
android:mode="twoLine">
<TextView
android:id="@+id/application_label"

View File

@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"></RelativeLayout>

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:fitsSystemWindows="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:liftOnScroll="true">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:liftOnScroll="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" />
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
android:id="@+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>

View File

@ -1,96 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/listPreferredItemHeight"
android:paddingBottom="2dip"
android:paddingTop="2dip">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/listPreferredItemHeight"
android:paddingBottom="2dip"
android:paddingTop="2dip">
<ImageView
android:id="@android:id/icon"
android:layout_width="48dip"
android:layout_height="48dip"
android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:layout_marginLeft="10dp"
android:layout_marginTop="6dip"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
tools:src="@drawable/ic_launcher"/>
android:id="@android:id/icon"
android:layout_width="48dip"
android:layout_height="48dip"
android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:layout_marginLeft="10dp"
android:layout_marginTop="6dip"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
tools:src="@drawable/ic_launcher" />
<LinearLayout
android:id="@+id/button_or_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:orientation="vertical"
android:gravity="end"
android:layout_marginEnd="?attr/listPreferredItemPaddingEnd"
android:layout_marginRight="10dp">
android:id="@+id/button_or_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:orientation="vertical"
android:gravity="end"
android:layout_marginEnd="?attr/listPreferredItemPaddingEnd"
android:layout_marginRight="10dp">
<Button
android:id="@+id/btn_install"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/swap_light_blue"
android:textColor="@android:color/white"
android:maxEms="10"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/menu_install"
tools:ignore="UnusedAttribute"/>
android:id="@+id/btn_install"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/swap_light_blue"
android:textColor="@android:color/white"
android:maxEms="10"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/menu_install"
tools:ignore="UnusedAttribute" />
<TextView
android:id="@+id/status_installed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic"
android:text="@string/app_installed"/>
android:id="@+id/status_installed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic"
android:text="@string/app_installed" />
<TextView
android:id="@+id/status_incompatible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic"
android:textColor="@color/swap_incompatible"
android:text="@string/app_incompatible"/>
android:id="@+id/status_incompatible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic"
android:textColor="@color/swap_incompatible"
android:text="@string/app_incompatible" />
</LinearLayout>
<TextView
android:id="@+id/name"
android:layout_toEndOf="@android:id/icon"
android:layout_toRightOf="@android:id/icon"
android:layout_toStartOf="@+id/button_or_text"
android:layout_toLeftOf="@+id/button_or_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:layout_marginLeft="10dp"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="F-Droid"/>
android:id="@+id/name"
android:layout_toEndOf="@android:id/icon"
android:layout_toRightOf="@android:id/icon"
android:layout_toStartOf="@+id/button_or_text"
android:layout_toLeftOf="@+id/button_or_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:layout_marginLeft="10dp"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="F-Droid" />
<ProgressBar
android:id="@+id/progress"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
style="?android:attr/progressBarStyleHorizontal"
android:paddingStart="5dp"
android:paddingLeft="5dp"
android:paddingEnd="5dp"
android:paddingRight="5dp"
android:layout_toEndOf="@android:id/icon"
android:layout_toRightOf="@android:id/icon"
android:layout_toStartOf="@+id/button_or_text"
android:layout_toLeftOf="@+id/button_or_text"
android:layout_below="@+id/name"
/>
android:id="@+id/progress"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
style="?android:attr/progressBarStyleHorizontal"
android:paddingStart="5dp"
android:paddingLeft="5dp"
android:paddingEnd="5dp"
android:paddingRight="5dp"
android:layout_toEndOf="@android:id/icon"
android:layout_toRightOf="@android:id/icon"
android:layout_toStartOf="@+id/button_or_text"
android:layout_toLeftOf="@+id/button_or_text"
android:layout_below="@+id/name" />
</RelativeLayout>

View File

@ -1,76 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.nearby.SwapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_confirm"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/swap_blue"
android:padding="18dp">
<org.fdroid.fdroid.nearby.SwapView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_confirm"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/swap_blue"
android:padding="18dp">
<!-- Padding is 32px * 0.56 = 18dip -->
<ImageView
android:id="@+id/icon"
swap:srcCompat="@drawable/ic_launcher"
android:contentDescription="@string/icon"
android:layout_alignParentTop="true"
android:layout_width="117.6dp"
android:layout_height="117.6dp"
android:layout_centerHorizontal="true"/>
android:id="@+id/icon"
swap:srcCompat="@drawable/ic_launcher"
android:contentDescription="@string/icon"
android:layout_alignParentTop="true"
android:layout_width="117.6dp"
android:layout_height="117.6dp"
android:layout_centerHorizontal="true" />
<!-- 210 * 0.56 = 117.6 -->
<TextView
android:id="@+id/text_title"
android:text="@string/swap_welcome"
style="@style/SwapTheme.Wizard.ReceiveSwap.MainText"
android:layout_below="@id/icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="28sp"
android:lines="1"/>
android:id="@+id/text_title"
android:text="@string/swap_welcome"
style="@style/SwapTheme.Wizard.ReceiveSwap.MainText"
android:layout_below="@id/icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="28sp"
android:lines="1" />
<!-- 60 * 0.56 = 33.6 -->
<!-- Temporarily making it smaller than 33.6 until we figure out how to
prevent line breaks on the hyphen in F-Droid. -->
<TextView
android:id="@+id/text_description"
tools:text="@string/swap_confirm_connect"
style="@style/SwapTheme.Wizard.Text"
android:layout_below="@id/text_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25.75sp"/>
android:id="@+id/text_description"
tools:text="@string/swap_confirm_connect"
style="@style/SwapTheme.Wizard.Text"
android:layout_below="@id/text_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25.75sp" />
<!-- 46px * 0.56 = 25.76sp -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="@+id/text_description"
android:layout_centerInParent="true"
android:layout_marginTop="45dp">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="@+id/text_description"
android:layout_centerInParent="true"
android:layout_marginTop="45dp">
<!-- 80px * 0.56 = 45dp -->
<Button
android:id="@+id/confirm_receive_yes"
android:text="@string/no"
android:backgroundTint="@color/swap_deny"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="25dp"
android:layout_marginRight="25dp"
tools:ignore="UnusedAttribute"/>
android:id="@+id/confirm_receive_yes"
android:text="@string/no"
android:backgroundTint="@color/swap_deny"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="25dp"
android:layout_marginRight="25dp"
tools:ignore="UnusedAttribute" />
<Button
android:id="@+id/confirm_receive_no"
android:text="@string/yes"
android:backgroundTint="@color/swap_light_blue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="UnusedAttribute"/>
android:id="@+id/confirm_receive_no"
android:text="@string/yes"
android:backgroundTint="@color/swap_light_blue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="UnusedAttribute" />
</LinearLayout>

View File

@ -1,41 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.nearby.SwapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
swap:toolbarTitle="@string/swap_connecting"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.fdroid.fdroid.nearby.SwapView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
swap:toolbarTitle="@string/swap_connecting"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/progress_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:textSize="20sp"
android:padding="30dp"
android:textAlignment="center"
android:gravity="center"/>
android:id="@+id/progress_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:textSize="20sp"
android:padding="30dp"
android:textAlignment="center"
android:gravity="center" />
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_centerInParent="true"
android:layout_below="@+id/progress_text"/>
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_centerInParent="true"
android:layout_below="@+id/progress_text" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@+id/progress_text"
android:id="@+id/try_again"
android:backgroundTint="@color/swap_light_blue"
android:textColor="@android:color/white"
android:visibility="gone"
android:text="@string/try_again"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@+id/progress_text"
android:id="@+id/try_again"
android:backgroundTint="@color/swap_light_blue"
android:textColor="@android:color/white"
android:visibility="gone"
android:text="@string/try_again" />
</org.fdroid.fdroid.nearby.SwapView>

View File

@ -1,33 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.nearby.SwapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_join_same_wifi"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/swap_blue"
tools:context=".nearby.SwapWorkflowActivity">
<org.fdroid.fdroid.nearby.SwapView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_join_same_wifi"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/swap_blue"
tools:context=".nearby.SwapWorkflowActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text_description"
android:layout_gravity="center_horizontal"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
style="@style/SwapTheme.Wizard.MainText"
android:text="@string/swap_join_same_wifi"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text_description"
android:layout_gravity="center_horizontal"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
style="@style/SwapTheme.Wizard.MainText"
android:text="@string/swap_join_same_wifi" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/wifi_icon"
swap:srcCompat="@drawable/ic_wifi"
android:layout_below="@+id/text_description"
android:layout_centerHorizontal="true"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/wifi_icon"
swap:srcCompat="@drawable/ic_wifi"
android:layout_below="@+id/text_description"
android:layout_centerHorizontal="true" />
<!--
<Button style="@style/SwapTheme.Wizard.OptionButton"
@ -37,24 +36,24 @@
-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/swap_no_wifi_network"
android:id="@+id/wifi_ssid"
style="@style/SwapTheme.Wizard.WifiSSID"
android:layout_below="@id/wifi_icon"
android:layout_centerHorizontal="true"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/swap_no_wifi_network"
android:id="@+id/wifi_ssid"
style="@style/SwapTheme.Wizard.WifiSSID"
android:layout_below="@id/wifi_icon"
android:layout_centerHorizontal="true" />
<!--android:layout_above="@id/wifi_available_networks_prompt"-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/swap_view_available_networks"
android:id="@+id/wifi_available_networks_prompt"
style="@style/SwapTheme.Wizard.Text"
android:layout_centerHorizontal="true"
android:layout_below="@id/wifi_ssid"
android:paddingBottom="20dp"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/swap_view_available_networks"
android:id="@+id/wifi_available_networks_prompt"
style="@style/SwapTheme.Wizard.Text"
android:layout_centerHorizontal="true"
android:layout_below="@id/wifi_ssid"
android:paddingBottom="20dp" />
<!-- android:layout_above="@id/btn_learn_more_about_wifi" -->
</org.fdroid.fdroid.nearby.SwapView>

View File

@ -1,38 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.nearby.SwapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_nfc_title"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/swap_blue"
android:paddingTop="38.8dp"> <!-- 69px * 96dpi / 160dpi -->
<org.fdroid.fdroid.nearby.SwapView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_nfc_title"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/swap_blue"
android:paddingTop="38.8dp"> <!-- 69px * 96dpi / 160dpi -->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/icon_nfc"
swap:srcCompat="@drawable/nfc_touch"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/icon_nfc"
swap:srcCompat="@drawable/nfc_touch"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<TextView
android:id="@+id/text_description"
android:text="@string/swap_nfc_description"
style="@style/SwapTheme.Wizard.MainText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/icon_nfc"/>
android:id="@+id/text_description"
android:text="@string/swap_nfc_description"
style="@style/SwapTheme.Wizard.MainText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/icon_nfc" />
<CheckBox
android:id="@+id/checkbox_dont_show"
android:text="@string/swap_dont_show_again"
style="@style/SwapTheme.Wizard.Text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/text_description"
android:layout_centerHorizontal="true"/>
android:id="@+id/checkbox_dont_show"
android:text="@string/swap_dont_show_again"
style="@style/SwapTheme.Wizard.Text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/text_description"
android:layout_centerHorizontal="true" />
</org.fdroid.fdroid.nearby.SwapView>

View File

@ -1,46 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeight"
android:orientation="horizontal"
android:minHeight="?attr/listPreferredItemHeight"
android:paddingBottom="4dip"
android:paddingTop="4dip">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeight"
android:orientation="horizontal"
android:minHeight="?attr/listPreferredItemHeight"
android:paddingBottom="4dip"
android:paddingTop="4dip">
<RelativeLayout
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginLeft="?attr/listPreferredItemPaddingLeft"
android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:layout_gravity="center_vertical">
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginLeft="?attr/listPreferredItemPaddingLeft"
android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:layout_gravity="center_vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srcCompat="@drawable/circle"
app:tint="@color/swap_light_grey_icon"/>
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srcCompat="@drawable/circle"
app:tint="@color/swap_light_grey_icon" />
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerInParent="true"
tools:src="@drawable/ic_bluetooth"/>
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerInParent="true"
tools:src="@drawable/ic_bluetooth" />
</RelativeLayout>
<TextView
android:id="@+id/peer_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="?attr/listPreferredItemPaddingLeft"
android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:textSize="20sp"
android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="Nexus 4"/>
android:id="@+id/peer_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="?attr/listPreferredItemPaddingLeft"
android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:textSize="20sp"
android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="Nexus 4" />
</LinearLayout>

View File

@ -1,18 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.nearby.SelectAppsView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
swap:toolbarTitle="@string/swap_choose_apps"
android:id="@+id/select_apps"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.fdroid.fdroid.nearby.SelectAppsView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
swap:toolbarTitle="@string/swap_choose_apps"
android:id="@+id/select_apps"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
</org.fdroid.fdroid.nearby.SelectAppsView>

View File

@ -1,53 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.nearby.SwapView
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_send_fdroid"
android:background="@color/swap_blue"
android:layout_height="match_parent"
android:layout_width="wrap_content">
<org.fdroid.fdroid.nearby.SwapView xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_send_fdroid"
android:background="@color/swap_blue"
android:layout_height="match_parent"
android:layout_width="wrap_content">
<ScrollView android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout android:orientation="vertical"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
<LinearLayout
android:orientation="vertical"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="250dp"
android:layout_height="250dp"
android:maxHeight="20dp"
android:id="@+id/wifi_qr_code"
tools:src="@drawable/swap_qr_example"/>
tools:src="@drawable/swap_qr_example" />
<TextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/swap_scan_or_type_url"
style="@style/SwapTheme.Wizard.MainText"/>
style="@style/SwapTheme.Wizard.MainText" />
<TextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/device_ip_address"
tools:text="http://255.255.255.255:8888"
style="@style/SwapTheme.Wizard.LocalIpAddress"/>
style="@style/SwapTheme.Wizard.LocalIpAddress" />
<Button style="@style/SwapTheme.Wizard.OptionButton"
<Button
style="@style/SwapTheme.Wizard.OptionButton"
android:text="@string/use_bluetooth"
android:layout_gravity="center"
android:id="@+id/btn_use_bluetooth"/>
android:id="@+id/btn_use_bluetooth" />
<TextView
<TextView
android:id="@+id/warning_qr_scanner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/warning_scaning_qr_code"
android:visibility="gone"
style="@style/SwapTheme.Wizard.QRScanWarningText"/>
style="@style/SwapTheme.Wizard.QRScanWarningText" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</org.fdroid.fdroid.nearby.SwapView>

View File

@ -1,157 +1,156 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.nearby.StartSwapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
swap:toolbarTitle="@string/swap_nearby"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".nearby.SwapWorkflowActivity">
<org.fdroid.fdroid.nearby.StartSwapView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
swap:toolbarTitle="@string/swap_nearby"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".nearby.SwapWorkflowActivity">
<!-- Misc header -->
<include layout="@layout/start_swap_header"/>
<include layout="@layout/start_swap_header" />
<!-- Bluetooth swap status + toggle -->
<LinearLayout
android:id="@+id/bluetooth_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/header"
android:padding="10dp"
android:orientation="horizontal">
android:id="@+id/bluetooth_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/header"
android:padding="10dp"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:contentDescription="@string/use_bluetooth"
swap:srcCompat="@drawable/ic_bluetooth_searching"/>
android:layout_width="24dp"
android:layout_height="24dp"
android:contentDescription="@string/use_bluetooth"
swap:srcCompat="@drawable/ic_bluetooth_searching" />
<LinearLayout
android:layout_width="0dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingStart="15dp"
android:layout_weight="1.00"
tools:ignore="RtlSymmetry">
<TextView
android:id="@+id/bluetooth_visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingStart="15dp"
android:layout_weight="1.00"
tools:ignore="RtlSymmetry">
tools:text="@string/swap_not_visible_bluetooth"
android:textSize="18sp" />
<TextView
android:id="@+id/bluetooth_visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/swap_not_visible_bluetooth"
android:textSize="18sp"/>
<TextView
android:id="@+id/device_id_bluetooth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="SP-120"
android:textColor="@color/swap_light_text"/>
android:id="@+id/device_id_bluetooth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="SP-120"
android:textColor="@color/swap_light_text" />
</LinearLayout>
<com.google.android.material.switchmaterial.SwitchMaterial
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:id="@+id/switch_bluetooth"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:id="@+id/switch_bluetooth" />
</LinearLayout>
<!-- WiFi swap status + toggle -->
<LinearLayout
android:id="@+id/wifi_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/bluetooth_info"
android:padding="10dp"
android:orientation="horizontal">
android:id="@+id/wifi_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/bluetooth_info"
android:padding="10dp"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:contentDescription="@string/wifi"
swap:srcCompat="@drawable/ic_wifi"/>
android:layout_width="24dp"
android:layout_height="24dp"
android:contentDescription="@string/wifi"
swap:srcCompat="@drawable/ic_wifi" />
<LinearLayout
android:layout_width="0dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingStart="15dp"
android:layout_weight="1.00"
tools:ignore="RtlSymmetry">
<TextView
android:id="@+id/wifi_visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingStart="15dp"
android:layout_weight="1.00"
tools:ignore="RtlSymmetry">
tools:text="@string/swap_starting"
android:textSize="18sp" />
<TextView
android:id="@+id/wifi_visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/swap_starting"
android:textSize="18sp"/>
android:id="@+id/device_id_wifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/swap_wifi_device_name"
android:textColor="@color/swap_light_text" />
<TextView
android:id="@+id/device_id_wifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/swap_wifi_device_name"
android:textColor="@color/swap_light_text"/>
<TextView
android:id="@+id/wifi_network"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="150dp"
tools:text="wifi network name"
android:textColor="@color/swap_bright_blue"
android:textSize="16sp"/>
android:id="@+id/wifi_network"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="150dp"
tools:text="wifi network name"
android:textColor="@color/swap_bright_blue"
android:textSize="16sp" />
</LinearLayout>
<com.google.android.material.switchmaterial.SwitchMaterial
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/switch_wifi"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/switch_wifi" />
</LinearLayout>
<!-- Feedback for "searching for nearby people..." -->
<LinearLayout
android:id="@+id/feedback_searching"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/wifi_info"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:paddingTop="20dp">
android:id="@+id/feedback_searching"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/wifi_info"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:paddingTop="20dp">
<TextView
android:id="@+id/text_people_nearby"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/swap_people_nearby"
android:textColor="@color/swap_light_text"
android:layout_weight="1.00"/>
android:id="@+id/text_people_nearby"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/swap_people_nearby"
android:textColor="@color/swap_light_text"
android:layout_weight="1.00" />
<ProgressBar
android:id="@+id/searching_people_nearby"
android:layout_width="24dp"
android:layout_height="24dp"
android:indeterminate="true"/>
android:id="@+id/searching_people_nearby"
android:layout_width="24dp"
android:layout_height="24dp"
android:indeterminate="true" />
</LinearLayout>
<!-- Buttons to help the user when they can't find any peers. Shown at bottom of relative layout -->
<LinearLayout
android:id="@+id/cant_find_peers"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
android:id="@+id/cant_find_peers"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_send_fdroid"
@ -187,25 +186,25 @@
<!-- Heading for "can't find peers" -->
<TextView
android:id="@+id/header_cant_find_peers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/cant_find_peers"
android:text="@string/swap_cant_find_peers"
android:paddingLeft="20dp"
android:paddingStart="20dp"
android:paddingRight="20dp"
android:paddingEnd="20dp"
android:paddingTop="20dp"
android:textColor="@color/swap_light_text"/>
android:id="@+id/header_cant_find_peers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/cant_find_peers"
android:text="@string/swap_cant_find_peers"
android:paddingLeft="20dp"
android:paddingStart="20dp"
android:paddingRight="20dp"
android:paddingEnd="20dp"
android:paddingTop="20dp"
android:textColor="@color/swap_light_text" />
<!-- List of all currently known peers (i.e. bluetooth and wifi devices that have been identified -->
<ListView
android:id="@+id/list_people_nearby"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/feedback_searching"
android:layout_above="@id/header_cant_find_peers">
android:id="@+id/list_people_nearby"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/feedback_searching"
android:layout_above="@id/header_cant_find_peers">
</ListView>

View File

@ -1,19 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.nearby.SwapSuccessView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
swap:toolbarTitle="@string/swap_success"
android:id="@+id/swap_success"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.fdroid.fdroid.nearby.SwapSuccessView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
swap:toolbarTitle="@string/swap_success"
android:id="@+id/swap_success"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
swap:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="vertical"/>
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
swap:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="vertical" />
</org.fdroid.fdroid.nearby.SwapSuccessView>

View File

@ -1,60 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.nearby.SwapView
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_scan_qr"
android:background="@color/swap_blue"
android:layout_height="match_parent"
android:layout_width="wrap_content">
<org.fdroid.fdroid.nearby.SwapView xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_scan_qr"
android:background="@color/swap_blue"
android:layout_height="match_parent"
android:layout_width="wrap_content">
<ScrollView android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout android:orientation="vertical"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
<LinearLayout
android:orientation="vertical"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="250dp"
android:layout_height="250dp"
android:maxHeight="20dp"
android:id="@+id/wifi_qr_code"
tools:src="@drawable/swap_qr_example"/>
tools:src="@drawable/swap_qr_example" />
<TextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/swap_scan_or_type_url"
style="@style/SwapTheme.Wizard.MainText"/>
style="@style/SwapTheme.Wizard.MainText" />
<!--
<Button style="@style/SwapTheme.Wizard.OptionButton"
android:id="@+id/btn_not_working"
android:text="@string/swap_wifi_qr_not_working"
android:layout_alignParentBottom="true" />
-->
<!--
<Button style="@style/SwapTheme.Wizard.OptionButton"
android:id="@+id/btn_not_working"
android:text="@string/swap_wifi_qr_not_working"
android:layout_alignParentBottom="true" />
-->
<TextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/device_ip_address"
tools:text="http://255.255.255.255:8888"
style="@style/SwapTheme.Wizard.LocalIpAddress"/>
style="@style/SwapTheme.Wizard.LocalIpAddress" />
<Button style="@style/SwapTheme.Wizard.OptionButton"
<Button
style="@style/SwapTheme.Wizard.OptionButton"
android:text="@string/open_qr_code_scanner"
android:layout_gravity="center"
android:id="@+id/btn_qr_scanner"/>
android:id="@+id/btn_qr_scanner" />
<TextView
<TextView
android:id="@+id/warning_qr_scanner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/warning_scaning_qr_code"
android:visibility="gone"
style="@style/SwapTheme.Wizard.QRScanWarningText"/>
style="@style/SwapTheme.Wizard.QRScanWarningText" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</org.fdroid.fdroid.nearby.SwapView>

View File

@ -1,10 +1,10 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_next"
android:icon="@drawable/ic_arrow_forward"
android:title="@string/next"
android:titleCondensed="@string/next"/>
android:titleCondensed="@string/next" />
<!-- Currently in a style, but that style probably won't work on 8 -> 11 devices -->
<!--android:drawable="@drawable/swap_action_button_skin"-->

View File

@ -1,15 +1,15 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
android:title="@string/menu_search"
android:titleCondensed="@string/menu_search"/>
android:titleCondensed="@string/menu_search" />
<item
android:id="@+id/action_next"
android:icon="@drawable/ic_arrow_forward"
android:title="@string/next"
android:titleCondensed="@string/next"/>
android:titleCondensed="@string/next" />
</menu>

View File

@ -4,7 +4,7 @@
<integer name="unhidePin">1337</integer>
<declare-styleable name="SwapView">
<attr name="toolbarColor" format="color"/>
<attr name="toolbarTitle" format="string"/>
<attr name="toolbarColor" format="color" />
<attr name="toolbarTitle" format="string" />
</declare-styleable>
</resources>

View File

@ -5,19 +5,15 @@
<item name="colorButtonNormal">#04b9e6</item>
</style>
<style name="SwapTheme.StartSwap" parent="Theme.App"/>
<style name="SwapTheme.StartSwap" parent="Theme.App" />
<style name="SwapTheme.StartSwap.Text" parent="@style/SwapTheme.StartSwap">
</style>
<style name="SwapTheme.StartSwap.Text" parent="@style/SwapTheme.StartSwap"></style>
<style name="SwapTheme.BluetoothDeviceList" parent="@style/SwapTheme.Wizard">
</style>
<style name="SwapTheme.BluetoothDeviceList" parent="@style/SwapTheme.Wizard"></style>
<style name="SwapTheme.AppList" parent="Base.Theme.App">
</style>
<style name="SwapTheme.AppList" parent="Base.Theme.App"></style>
<style name="SwapTheme.AppList.ListItem" parent="Theme.App">
</style>
<style name="SwapTheme.AppList.ListItem" parent="Theme.App"></style>
<style name="SwapTheme.AppList.SwapSuccessBase">
<item name="android:gravity">center</item>
@ -26,7 +22,7 @@
<item name="android:paddingBottom">20.1dp</item> <!-- 36px * 96dpi / 160dpi -->
</style>
<style name="SwapTheme.AppList.SwapSuccess" parent="SwapTheme.AppList.SwapSuccessBase"/>
<style name="SwapTheme.AppList.SwapSuccess" parent="SwapTheme.AppList.SwapSuccessBase" />
<style name="SwapTheme.AppList.SwapSuccessDetailsBase">
<item name="android:gravity">center</item>
@ -36,7 +32,7 @@
<item name="android:textStyle">bold</item>
</style>
<style name="SwapTheme.AppList.SwapSuccessDetails" parent="SwapTheme.AppList.SwapSuccessDetailsBase"/>
<style name="SwapTheme.AppList.SwapSuccessDetails" parent="SwapTheme.AppList.SwapSuccessDetailsBase" />
<style name="SwapTheme.StartSwap.MainTextBase">
<item name="android:gravity">center</item>
@ -47,8 +43,7 @@
<item name="android:paddingBottom">16.8dp</item> <!-- 30px * 96dpi / 160dpi -->
</style>
<style name="SwapTheme.StartSwap.MainText" parent="SwapTheme.StartSwap.MainTextBase">
</style>
<style name="SwapTheme.StartSwap.MainText" parent="SwapTheme.StartSwap.MainTextBase"></style>
<style name="SwapTheme.Wizard.TextBase">
<item name="android:gravity">center</item>
@ -57,7 +52,7 @@
<item name="android:textColorSecondary">#fff</item>
</style>
<style name="SwapTheme.Wizard.Text" parent="SwapTheme.Wizard.TextBase"/>
<style name="SwapTheme.Wizard.Text" parent="SwapTheme.Wizard.TextBase" />
<style name="SwapTheme.Wizard.Text.Toolbar" parent="SwapTheme.Wizard.Text">
<item name="android:textSize">22sp</item>
@ -78,7 +73,7 @@
<item name="android:paddingBottom">10dp</item>
</style>
<style name="SwapTheme.Wizard.MainText" parent="SwapTheme.Wizard.MainTextBase"/>
<style name="SwapTheme.Wizard.MainText" parent="SwapTheme.Wizard.MainTextBase" />
<style name="SwapTheme.Wizard.QRScanWarningText" parent="@style/SwapTheme.Wizard.MainTextBase">
<item name="android:paddingLeft">40dp</item>
@ -115,8 +110,7 @@
<item name="android:layout_margin">0dp</item>
</style>
<style name="SwapTheme.Wizard.ReceiveSwap" parent="SwapTheme.Wizard">
</style>
<style name="SwapTheme.Wizard.ReceiveSwap" parent="SwapTheme.Wizard"></style>
<!--
Buttons used to ask the user to confirm they want to receive a swap repo from someone

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
/**
* (C) Copyright 2014 mjahnen <jahnen@in.tum.de>
*

View File

@ -1,43 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<CheckBoxPreference
android:defaultValue="true"
android:key="pref_panic_exit"
android:summary="@string/panic_exit_summary"
android:title="@string/panic_exit_title"/>
android:defaultValue="true"
android:key="pref_panic_exit"
android:summary="@string/panic_exit_summary"
android:title="@string/panic_exit_title" />
<PreferenceCategory
android:key="pref_panic_destructive_actions"
android:title="@string/panic_destructive_actions">
android:key="pref_panic_destructive_actions"
android:title="@string/panic_destructive_actions">
<ListPreference
android:key="pref_panic_app"
android:summary="@string/panic_app_setting_summary"
android:title="@string/panic_app_setting_title"
tools:icon="@drawable/ic_cancel"/>
android:key="pref_panic_app"
android:summary="@string/panic_app_setting_summary"
android:title="@string/panic_app_setting_title"
tools:icon="@drawable/ic_cancel" />
<org.fdroid.fdroid.panic.DestructiveCheckBoxPreference
android:defaultValue="false"
android:enabled="false"
android:key="pref_panic_hide"
android:summary="@string/panic_hide_summary"
android:title="@string/panic_hide_title"/>
android:defaultValue="false"
android:enabled="false"
android:key="pref_panic_hide"
android:summary="@string/panic_hide_summary"
android:title="@string/panic_hide_title" />
<org.fdroid.fdroid.panic.DestructiveCheckBoxPreference
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: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" />
</PreferenceCategory>
<PreferenceCategory
android:key="pref_panic_apps_to_uninstall"
android:title="@string/panic_apps_to_uninstall">
android:key="pref_panic_apps_to_uninstall"
android:title="@string/panic_apps_to_uninstall">
</PreferenceCategory>

View File

@ -60,7 +60,7 @@
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:name=".FDroidApp"
@ -78,8 +78,7 @@
android:configChanges="layoutDirection|locale"
android:excludeFromRecents="true"
android:label="@string/menu_install"
android:parentActivityName=".views.main.MainActivity">
</activity>
android:parentActivityName=".views.main.MainActivity"></activity>
<activity
android:name=".privileged.views.UninstallDialogActivity"
@ -90,8 +89,7 @@
android:configChanges="layoutDirection|locale"
android:label="@string/menu_manage"
android:launchMode="singleTask"
android:parentActivityName=".views.main.MainActivity">
</activity>
android:parentActivityName=".views.main.MainActivity"></activity>
<activity
android:name=".NfcNotEnabledActivity"
@ -103,16 +101,14 @@
android:configChanges="layoutDirection|locale"
android:label="@string/repo_details"
android:parentActivityName=".views.ManageReposActivity"
android:windowSoftInputMode="stateHidden">
</activity>
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".views.AppDetailsActivity"
android:configChanges="layoutDirection|locale"
android:exported="true"
android:label="@string/app_details"
android:parentActivityName=".views.main.MainActivity">
</activity>
android:parentActivityName=".views.main.MainActivity"></activity>
<activity android:name=".views.ScreenShotsActivity" />
@ -404,12 +400,10 @@
<activity android:name=".views.apps.AppListActivity" />
<activity
android:name=".views.installed.InstalledAppsActivity"
android:parentActivityName=".views.main.MainActivity">
</activity>
android:parentActivityName=".views.main.MainActivity"></activity>
<activity
android:name=".views.InstallHistoryActivity"
android:parentActivityName=".views.main.MainActivity">
</activity>
android:parentActivityName=".views.main.MainActivity"></activity>
<activity
android:name=".installer.FileInstallerActivity"
@ -442,8 +436,7 @@
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="remove">
</provider>
tools:node="remove"></provider>
<receiver
android:name=".receiver.StartupReceiver"

View File

@ -8,6 +8,9 @@ import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.fdroid.database.Repository;
import org.fdroid.download.Mirror;
import org.fdroid.fdroid.views.ManageReposActivity;
@ -17,9 +20,6 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Handles requests to add new repos via URLs. This is an {@code IntentService}
* so that requests are queued, which is necessary when either

View File

@ -9,13 +9,17 @@ import android.content.pm.PackageManager;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import androidx.core.app.TaskStackBuilder;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.fdroid.database.DbUpdateChecker;
import org.fdroid.database.Repository;
import org.fdroid.database.UpdatableApp;
import org.fdroid.database.DbUpdateChecker;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.App;
import org.fdroid.fdroid.data.DBHelper;
@ -30,11 +34,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.TaskStackBuilder;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import io.reactivex.rxjava3.disposables.Disposable;
/**
@ -85,9 +84,9 @@ public final class AppUpdateStatusManager {
public static final String REASON_READY_TO_INSTALL = "readytoinstall";
public static final String REASON_UPDATES_AVAILABLE = "updatesavailable";
public static final String REASON_CLEAR_ALL_UPDATES = "clearallupdates";
public static final String REASON_CLEAR_ALL_INSTALLED = "clearallinstalled";
public static final String REASON_REPO_DISABLED = "repodisabled";
private static final String REASON_CLEAR_ALL_UPDATES = "clearallupdates";
private static final String REASON_CLEAR_ALL_INSTALLED = "clearallinstalled";
private static final String REASON_REPO_DISABLED = "repodisabled";
/**
* If this is present and true, then the broadcast has been sent in response to the {@link AppUpdateStatus#status}
@ -115,7 +114,7 @@ public final class AppUpdateStatusManager {
return instance;
}
private static AppUpdateStatusManager instance;
private static volatile AppUpdateStatusManager instance;
private final MutableLiveData<Integer> numUpdatableApps = new MutableLiveData<>();
public static class AppUpdateStatus implements Parcelable {
@ -146,6 +145,7 @@ public final class AppUpdateStatusManager {
/**
* Dumps some information about the status for debugging purposes.
*/
@NonNull
public String toString() {
return app.packageName + " [Status: " + status
+ ", Progress: " + progressCurrent + " / " + progressMax + ']';
@ -290,7 +290,7 @@ public final class AppUpdateStatusManager {
return numUpdatableApps;
}
public void setNumUpdatableApps(int num) {
private void setNumUpdatableApps(int num) {
numUpdatableApps.postValue(num);
}

View File

@ -5,6 +5,8 @@ import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.annotation.Nullable;
import org.fdroid.fdroid.data.Apk;
import java.util.ArrayList;
@ -13,8 +15,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import androidx.annotation.Nullable;
// Call getIncompatibleReasons(apk) on an instance of this class to
// find reasons why an apk may be incompatible with the user's device.
public class CompatibilityChecker {

View File

@ -5,16 +5,16 @@ import android.content.Intent;
import android.os.Process;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.app.JobIntentService;
import androidx.core.content.ContextCompat;
import com.bumptech.glide.Glide;
import org.apache.commons.io.FileUtils;
import java.io.File;
import androidx.annotation.NonNull;
import androidx.core.app.JobIntentService;
import androidx.core.content.ContextCompat;
/**
* An {@link JobIntentService} subclass for deleting the full cache for this app.
*/

View File

@ -45,6 +45,14 @@ import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.content.ContextCompat;
import androidx.core.os.ConfigurationCompat;
import androidx.core.os.LocaleListCompat;
import com.bumptech.glide.Glide;
import org.acra.ACRA;
@ -55,7 +63,6 @@ import org.acra.config.MailSenderConfigurationBuilder;
import org.apache.commons.net.util.SubnetUtils;
import org.fdroid.database.FDroidDatabase;
import org.fdroid.database.Repository;
import org.fdroid.fdroid.Preferences.ChangeListener;
import org.fdroid.fdroid.data.App;
import org.fdroid.fdroid.data.DBHelper;
import org.fdroid.fdroid.installer.ApkFileProvider;
@ -78,14 +85,6 @@ import java.util.List;
import java.util.Random;
import java.util.UUID;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.content.ContextCompat;
import androidx.core.os.ConfigurationCompat;
import androidx.core.os.LocaleListCompat;
import info.guardianproject.netcipher.NetCipher;
import info.guardianproject.netcipher.proxy.OrbotHelper;
import io.reactivex.rxjava3.core.Single;
@ -127,8 +126,8 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
* responding to local broadcasts. It is kept as a reference on the app object here so that
* it doesn't get GC'ed.
*/
@SuppressWarnings("unused")
NotificationHelper notificationHelper;
@SuppressWarnings({"FieldCanBeLocal", "unused", "PMD.SingularField"})
private NotificationHelper notificationHelper;
static {
BOUNCYCASTLE_PROVIDER = new org.bouncycastle.jce.provider.BouncyCastleProvider();
@ -179,9 +178,10 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
* The built-in BouncyCastle was stripped down in {@link Build.VERSION_CODES#S}
* so that {@code SHA1withRSA} and {@code SHA256withRSA} are no longer included.
*
* @see <a href="https://gitlab.com/fdroid/fdroidclient/-/issues/2338">Nearby Swap Crash on Android 12: no such algorithm: SHA1WITHRSA for provider BC</a>
* @see
* <a href="https://gitlab.com/fdroid/fdroidclient/-/issues/2338">Nearby Swap Crash on Android 12: no such algorithm: SHA1WITHRSA for provider BC</a>
*/
public static void enableBouncyCastle() {
private static void enableBouncyCastle() {
if (Build.VERSION.SDK_INT >= 31) {
Security.removeProvider("BC");
}
@ -323,19 +323,12 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
// If the user changes the preference to do with filtering anti-feature apps,
// it is easier to just notify a change in the app provider,
// so that the newly updated list will correctly filter relevant apps.
preferences.registerAppsRequiringAntiFeaturesChangeListener(new Preferences.ChangeListener() {
@Override
public void onPreferenceChange() {
// TODO check if anything else needs updating/reloading
}
preferences.registerAppsRequiringAntiFeaturesChangeListener(() -> {
// TODO check if anything else needs updating/reloading
});
preferences.registerUnstableUpdatesChangeListener(new Preferences.ChangeListener() {
@Override
public void onPreferenceChange() {
AppUpdateStatusManager.getInstance(FDroidApp.this).checkForUpdates();
}
});
preferences.registerUnstableUpdatesChangeListener(() ->
AppUpdateStatusManager.getInstance(FDroidApp.this).checkForUpdates());
CleanCacheWorker.schedule(this);
@ -353,12 +346,8 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
FDroidApp.initWifiSettings();
WifiStateChangeService.start(this, null);
// if the HTTPS pref changes, then update all affected things
preferences.registerLocalRepoHttpsListeners(new ChangeListener() {
@Override
public void onPreferenceChange() {
WifiStateChangeService.start(getApplicationContext(), null);
}
});
preferences.registerLocalRepoHttpsListeners(() -> WifiStateChangeService.start(getApplicationContext(),
null));
if (preferences.isKeepingInstallHistory()) {
InstallHistoryService.register(this);

View File

@ -28,7 +28,7 @@ public final class Languages {
private static Locale locale;
private static Languages singleton;
private static Map<String, String> tmpMap = new TreeMap<>();
private static final Map<String, String> TMP_MAP = new TreeMap<>();
private static Map<String, String> nameMap;
static {
@ -36,30 +36,29 @@ public final class Languages {
}
private Languages(AppCompatActivity activity) {
Set<Locale> localeSet = new LinkedHashSet<>();
localeSet.addAll(Arrays.asList(LOCALES_TO_TEST));
Set<Locale> localeSet = new LinkedHashSet<>(Arrays.asList(LOCALES_TO_TEST));
for (Locale locale : localeSet) {
if (locale.equals(TIBETAN)) {
// include English name for devices without Tibetan font support
tmpMap.put(TIBETAN.getLanguage(), "Tibetan བོད་སྐད།"); // Tibetan
TMP_MAP.put(TIBETAN.getLanguage(), "Tibetan བོད་སྐད།"); // Tibetan
} else if (locale.equals(Locale.SIMPLIFIED_CHINESE)) {
tmpMap.put(Locale.SIMPLIFIED_CHINESE.toString(), "中文 (中国)"); // Chinese (China)
TMP_MAP.put(Locale.SIMPLIFIED_CHINESE.toString(), "中文 (中国)"); // Chinese (China)
} else if (locale.equals(Locale.TRADITIONAL_CHINESE)) {
tmpMap.put(Locale.TRADITIONAL_CHINESE.toString(), "中文 (台灣)"); // Chinese (Taiwan)
TMP_MAP.put(Locale.TRADITIONAL_CHINESE.toString(), "中文 (台灣)"); // Chinese (Taiwan)
} else if (locale.equals(CHINESE_HONG_KONG)) {
tmpMap.put(CHINESE_HONG_KONG.toString(), "中文 (香港)"); // Chinese (Hong Kong)
TMP_MAP.put(CHINESE_HONG_KONG.toString(), "中文 (香港)"); // Chinese (Hong Kong)
} else {
tmpMap.put(locale.getLanguage(), capitalize(locale.getDisplayLanguage(locale)));
TMP_MAP.put(locale.getLanguage(), capitalize(locale.getDisplayLanguage(locale)));
}
}
// remove the current system language from the menu
tmpMap.remove(Locale.getDefault().getLanguage());
TMP_MAP.remove(Locale.getDefault().getLanguage());
/* SYSTEM_DEFAULT is a fake one for displaying in a chooser menu. */
tmpMap.put(USE_SYSTEM_DEFAULT, activity.getString(R.string.pref_language_default));
nameMap = Collections.unmodifiableMap(tmpMap);
TMP_MAP.put(USE_SYSTEM_DEFAULT, activity.getString(R.string.pref_language_default));
nameMap = Collections.unmodifiableMap(TMP_MAP);
}
/**

View File

@ -38,8 +38,8 @@ import java.util.Arrays;
@SuppressWarnings("LineLength")
public class NotificationHelper {
public static final String CHANNEL_SWAPS = "swap-channel";
public static final String CHANNEL_INSTALLS = "install-channel";
public static final String CHANNEL_UPDATES = "update-channel";
private static final String CHANNEL_INSTALLS = "install-channel";
static final String CHANNEL_UPDATES = "update-channel";
static final String BROADCAST_NOTIFICATIONS_ALL_UPDATES_CLEARED = "org.fdroid.fdroid.installer.notifications.allupdates.cleared";
static final String BROADCAST_NOTIFICATIONS_ALL_INSTALLED_CLEARED = "org.fdroid.fdroid.installer.notifications.allinstalled.cleared";
@ -170,16 +170,12 @@ public class NotificationHelper {
private boolean shouldIgnoreEntry(AppUpdateStatusManager.AppUpdateStatus entry) {
// Ignore unknown status
if (entry.status == AppUpdateStatusManager.Status.DownloadInterrupted) {
return true;
} else if ((entry.status == AppUpdateStatusManager.Status.Downloading ||
// Ignore downloading, readyToInstall and installError if we are showing the details screen for this app
if (entry.status == AppUpdateStatusManager.Status.DownloadInterrupted) return true;
return (entry.status == AppUpdateStatusManager.Status.Downloading ||
entry.status == AppUpdateStatusManager.Status.ReadyToInstall ||
entry.status == AppUpdateStatusManager.Status.InstallError) &&
AppDetailsActivity.isAppVisible(entry.app.packageName)) {
// Ignore downloading, readyToInstall and installError if we are showing the details screen for this app
return true;
}
return false;
AppDetailsActivity.isAppVisible(entry.app.packageName);
}
private void createNotification(AppUpdateStatusManager.AppUpdateStatus entry) {
@ -267,13 +263,11 @@ public class NotificationHelper {
return context.getString(R.string.notification_title_single_update_available);
case PendingInstall:
case Downloading:
case Installing:
case Installed:
return app.name;
case ReadyToInstall:
return context.getString(app.isInstalled(context) ? R.string.notification_title_single_ready_to_install_update : R.string.notification_title_single_ready_to_install);
case Installing:
return app.name;
case Installed:
return app.name;
case InstallError:
return context.getString(R.string.notification_title_single_install_error);
}
@ -283,18 +277,16 @@ public class NotificationHelper {
private String getSingleItemContentString(App app, AppUpdateStatusManager.Status status) {
switch (status) {
case UpdateAvailable:
case ReadyToInstall:
case InstallError:
return app.name;
case PendingInstall:
case Downloading:
return context.getString(app.isInstalled(context) ? R.string.notification_content_single_downloading_update : R.string.notification_content_single_downloading, app.name);
case ReadyToInstall:
return app.name;
case Installing:
return context.getString(R.string.notification_content_single_installing, app.name);
case Installed:
return context.getString(R.string.notification_content_single_installed);
case InstallError:
return app.name;
}
return "";
}

View File

@ -96,36 +96,36 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
public static final String PREF_SHOW_INCOMPAT_VERSIONS = "incompatibleVersions";
public static final String PREF_SHOW_ANTI_FEATURES = "showAntiFeatures";
public static final String PREF_FORCE_TOUCH_APPS = "ignoreTouchscreen";
public static final String PREF_PROMPT_TO_SEND_CRASH_REPORTS = "promptToSendCrashReports";
private static final String PREF_PROMPT_TO_SEND_CRASH_REPORTS = "promptToSendCrashReports";
public static final String PREF_KEEP_CACHE_TIME = "keepCacheFor";
public static final String PREF_UNSTABLE_UPDATES = "unstableUpdates";
private static final String PREF_UNSTABLE_UPDATES = "unstableUpdates";
public static final String PREF_KEEP_INSTALL_HISTORY = "keepInstallHistory";
public static final String PREF_SEND_TO_FDROID_METRICS = "sendToFdroidMetrics";
public static final String PREF_USE_IPFS_GATEWAYS = "useIpfsGateways";
private static final String PREF_USE_IPFS_GATEWAYS = "useIpfsGateways";
public static final String PREF_EXPERT = "expert";
public static final String PREF_FORCE_OLD_INDEX = "forceOldIndex";
public static final String PREF_PRIVILEGED_INSTALLER = "privilegedInstaller";
public static final String PREF_LOCAL_REPO_NAME = "localRepoName";
public static final String PREF_LOCAL_REPO_HTTPS = "localRepoHttps";
public static final String PREF_SCAN_REMOVABLE_STORAGE = "scanRemovableStorage";
private static final String PREF_SCAN_REMOVABLE_STORAGE = "scanRemovableStorage";
public static final String PREF_LANGUAGE = "language";
public static final String PREF_USE_TOR = "useTor";
public static final String PREF_ENABLE_PROXY = "enableProxy";
public static final String PREF_PROXY_HOST = "proxyHost";
public static final String PREF_PROXY_PORT = "proxyPort";
public static final String PREF_SHOW_NFC_DURING_SWAP = "showNfcDuringSwap";
private static final String PREF_SHOW_NFC_DURING_SWAP = "showNfcDuringSwap";
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";
public static final String PREF_HIDE_ALL_NOTIFICATIONS = "hideAllNotifications";
public static final String PREF_SEND_VERSION_AND_UUID_TO_SERVERS = "sendVersionAndUUIDToServers";
private static final String PREF_PANIC_WIPE_SET = "panicWipeSet";
private static final String PREF_PANIC_TMP_SELECTED_SET = "panicTmpSelectedSet";
private static final String PREF_HIDE_ON_LONG_PRESS_SEARCH = "hideOnLongPressSearch";
private static final String PREF_HIDE_ALL_NOTIFICATIONS = "hideAllNotifications";
private static final String PREF_SEND_VERSION_AND_UUID_TO_SERVERS = "sendVersionAndUUIDToServers";
public static final int OVER_NETWORK_NEVER = 0;
public static final int OVER_NETWORK_ON_DEMAND = 1;
private static final int OVER_NETWORK_ON_DEMAND = 1;
public static final int OVER_NETWORK_ALWAYS = 2;
// not shown in Settings
@ -160,7 +160,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
lightWithDarkActionBar, // Obsolete
}
public static final long UPDATE_INTERVAL_DISABLED = Long.MAX_VALUE;
static final long UPDATE_INTERVAL_DISABLED = Long.MAX_VALUE;
public static final long[] UPDATE_INTERVAL_VALUES = {
UPDATE_INTERVAL_DISABLED,
DateUtils.WEEK_IN_MILLIS * 2,
@ -192,7 +192,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
initialized.put(key, false);
}
public boolean promptToSendCrashReports() {
boolean promptToSendCrashReports() {
return preferences.getBoolean(PREF_PROMPT_TO_SEND_CRASH_REPORTS, IGNORED_B);
}
@ -217,7 +217,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
/**
* Get the update interval in milliseconds.
*/
public long getUpdateInterval() {
long getUpdateInterval() {
int position = preferences.getInt(PREF_UPDATE_INTERVAL, IGNORED_I);
return UPDATE_INTERVAL_VALUES[position];
}
@ -327,7 +327,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
}
}
long getLastUpdateCheck() {
private long getLastUpdateCheck() {
return preferences.getLong(PREF_LAST_UPDATE_CHECK, DEFAULT_LAST_UPDATE_CHECK);
}
@ -342,7 +342,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
return getLastUpdateCheck() == DEFAULT_LAST_UPDATE_CHECK;
}
public boolean getUnstableUpdates() {
private boolean getUnstableUpdates() {
return preferences.getBoolean(PREF_UNSTABLE_UPDATES, IGNORED_B);
}
@ -364,7 +364,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
preferences.edit().putBoolean(PREF_UNSTABLE_UPDATES, value).apply();
}
public boolean isKeepingInstallHistory() {
boolean isKeepingInstallHistory() {
return preferences.getBoolean(PREF_KEEP_INSTALL_HISTORY, IGNORED_B);
}
@ -392,7 +392,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
preferences.edit().putBoolean(PREF_EXPERT, flag).apply();
}
public boolean forceTouchApps() {
boolean forceTouchApps() {
return preferences.getBoolean(Preferences.PREF_FORCE_TOUCH_APPS, IGNORED_B);
}
@ -400,7 +400,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
return Theme.valueOf(preferences.getString(Preferences.PREF_THEME, null));
}
public boolean isPureBlack() {
boolean isPureBlack() {
return preferences.getBoolean(Preferences.PREF_USE_PURE_BLACK_DARK_THEME, false);
}
@ -417,7 +417,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
return preferences.getString(Preferences.PREF_LANGUAGE, Languages.USE_SYSTEM_DEFAULT);
}
public void clearLanguage() {
void clearLanguage() {
preferences.edit().remove(Preferences.PREF_LANGUAGE).apply();
}
@ -433,7 +433,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
return preferences.getBoolean(PREF_UPDATE_NOTIFICATION_ENABLED, true);
}
public boolean isAutoDownloadEnabled() {
boolean isAutoDownloadEnabled() {
return preferences.getBoolean(PREF_AUTO_DOWNLOAD_INSTALL_UPDATES, IGNORED_B);
}
@ -471,7 +471,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
/**
* Some users never use WiFi, this lets us check for that state on first run.
*/
public void setDefaultForDataOnlyConnection(Context context) {
void setDefaultForDataOnlyConnection(Context context) {
ConnectivityManager cm = ContextCompat.getSystemService(context, ConnectivityManager.class);
if (cm == null) {
return;
@ -498,7 +498,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
return preferences.getBoolean(PREF_USE_TOR, IGNORED_B);
}
public boolean isProxyEnabled() {
boolean isProxyEnabled() {
return preferences.getBoolean(PREF_ENABLE_PROXY, IGNORED_B);
}
@ -545,7 +545,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
}
public Set<String> getPanicTmpSelectedSet() {
return preferences.getStringSet(Preferences.PREF_PANIC_TMP_SELECTED_SET, Collections.<String>emptySet());
return preferences.getStringSet(Preferences.PREF_PANIC_TMP_SELECTED_SET, Collections.emptySet());
}
public void setPanicTmpSelectedSet(Set<String> selectedSet) {
@ -553,7 +553,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
}
public Set<String> getPanicWipeSet() {
return preferences.getStringSet(Preferences.PREF_PANIC_WIPE_SET, Collections.<String>emptySet());
return preferences.getStringSet(Preferences.PREF_PANIC_WIPE_SET, Collections.emptySet());
}
public void setPanicWipeSet(Set<String> selectedSet) {
@ -564,7 +564,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
* Preference for whitelabel builds that are meant to be entirely controlled
* by the server, without user interaction, e.g. "appliances".
*/
public boolean hideAllNotifications() {
boolean hideAllNotifications() {
return preferences.getBoolean(PREF_HIDE_ALL_NOTIFICATIONS, IGNORED_B);
}
@ -572,7 +572,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
* Whether to include the version of this app and a randomly generated ID
* to the server when downloading from it.
*/
public boolean sendVersionAndUUIDToServers() {
boolean sendVersionAndUUIDToServers() {
return preferences.getBoolean(PREF_SEND_VERSION_AND_UUID_TO_SERVERS, IGNORED_B);
}

View File

@ -77,19 +77,19 @@ public class UpdateService extends JobIntentService {
public static final String LOCAL_ACTION_STATUS = "status";
public static final String EXTRA_MESSAGE = "msg";
public static final String EXTRA_REPO_FINGERPRINT = "fingerprint";
public static final String EXTRA_REPO_ERRORS = "repoErrors";
private static final String EXTRA_MESSAGE = "msg";
private static final String EXTRA_REPO_FINGERPRINT = "fingerprint";
private static final String EXTRA_REPO_ERRORS = "repoErrors";
public static final String EXTRA_STATUS_CODE = "status";
public static final String EXTRA_MANUAL_UPDATE = "manualUpdate";
public static final String EXTRA_FORCED_UPDATE = "forcedUpdate";
public static final String EXTRA_PROGRESS = "progress";
private static final String EXTRA_MANUAL_UPDATE = "manualUpdate";
private static final String EXTRA_FORCED_UPDATE = "forcedUpdate";
private static final String EXTRA_PROGRESS = "progress";
public static final int STATUS_COMPLETE_WITH_CHANGES = 0;
public static final int STATUS_COMPLETE_AND_SAME = 1;
public static final int STATUS_ERROR_GLOBAL = 2;
public static final int STATUS_ERROR_LOCAL = 3;
public static final int STATUS_ERROR_LOCAL_SMALL = 4;
private static final int STATUS_COMPLETE_AND_SAME = 1;
private static final int STATUS_ERROR_GLOBAL = 2;
private static final int STATUS_ERROR_LOCAL = 3;
private static final int STATUS_ERROR_LOCAL_SMALL = 4;
public static final int STATUS_INFO = 5;
/**
@ -226,7 +226,7 @@ public class UpdateService extends JobIntentService {
return updateService != null && isForcedUpdate;
}
public static void stopNow() {
static void stopNow() {
if (updateService != null) {
updateService.stopSelf(JOB_ID);
updateService = null;
@ -280,15 +280,15 @@ public class UpdateService extends JobIntentService {
updateService = null;
}
public static void sendStatus(Context context, int statusCode) {
private static void sendStatus(Context context, int statusCode) {
sendStatus(context, statusCode, null, -1);
}
public static void sendStatus(Context context, int statusCode, String message) {
private static void sendStatus(Context context, int statusCode, String message) {
sendStatus(context, statusCode, message, -1);
}
public static void sendStatus(Context context, int statusCode, String message, int progress) {
private static void sendStatus(Context context, int statusCode, String message, int progress) {
Intent intent = new Intent(LOCAL_ACTION_STATUS);
intent.putExtra(EXTRA_STATUS_CODE, statusCode);
if (!TextUtils.isEmpty(message)) {
@ -558,8 +558,8 @@ public class UpdateService extends JobIntentService {
}
}
public static void reportDownloadProgress(Context context, String indexUrl,
long bytesRead, long totalBytes) {
static void reportDownloadProgress(Context context, String indexUrl,
long bytesRead, long totalBytes) {
Utils.debugLog(TAG, "Downloading " + indexUrl + "(" + bytesRead + "/" + totalBytes + ")");
String downloadedSizeFriendly = Utils.getFriendlySize(bytesRead);
int percent = -1;
@ -570,7 +570,6 @@ public class UpdateService extends JobIntentService {
if (totalBytes == -1) {
message = context.getString(R.string.status_download_unknown_size,
indexUrl, downloadedSizeFriendly);
percent = -1;
} else {
String totalSizeFriendly = Utils.getFriendlySize(totalBytes);
message = context.getString(R.string.status_download,
@ -587,7 +586,7 @@ public class UpdateService extends JobIntentService {
* "Saving app details" sent to the user. If you know how many apps you have
* processed, then a message of "Saving app details (x/total)" is displayed.
*/
public static void reportProcessingAppsProgress(Context context, String indexUrl, int appsSaved, int totalApps) {
static void reportProcessingAppsProgress(Context context, String indexUrl, int appsSaved, int totalApps) {
Utils.debugLog(TAG, "Committing " + indexUrl + "(" + appsSaved + "/" + totalApps + ")");
if (totalApps > 0) {
String message = context.getString(R.string.status_inserting_x_apps,

Some files were not shown because too many files have changed in this diff Show More