Skip to content

Commit

Permalink
Apollo: Release source code for 52.1
Browse files Browse the repository at this point in the history
  • Loading branch information
acrespo committed Aug 2, 2024
1 parent 7bbe9b2 commit 7111460
Show file tree
Hide file tree
Showing 67 changed files with 1,117 additions and 873 deletions.
21 changes: 21 additions & 0 deletions android/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ follow [https://changelog.md/](https://changelog.md/) guidelines.

## [Unreleased]

## [52.1] - 2024-08-02

### ADDED

- Background notification processing reliability improvements
- Wallet delete checks client-side (e.g prevent it wallet not fully empty)

### FIXED

- Handling of missing or deprecated currencies
- Tiny text copy when updating emergency kit

### CHANGED

- Upgraded compiledSdkVersion and targetSdkVersion to 34
- Upgraded go version to 1.21.11
- Enhanced password input for change password flow (consistency with rest of the app)
- Enhanced error metadata for strange secure storage errors
- Removed never used "max fee" button and calculations
- Revamped to UI test suite. Enhancing reliability and coverage.

## [52] - 2024-06-14

### ADDED
Expand Down
2 changes: 1 addition & 1 deletion android/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM --platform=linux/amd64 openjdk:17-jdk-buster@sha256:9217da81dcff19e60861791
ENV NDK_VERSION 22.0.7026061
ENV ANDROID_PLATFORM_VERSION 28
ENV ANDROID_BUILD_TOOLS_VERSION 28.0.3
ENV GO_VERSION 1.18.1
ENV GO_VERSION 1.21.11

RUN apt-get update \
&& apt-get install --yes --no-install-recommends \
Expand Down
15 changes: 6 additions & 9 deletions android/apollo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,17 @@ apply from: "${project.rootDir}/linters/pmd/check-android.gradle"
//apply from: "${project.rootDir}/linters/findbugs/check-android.gradle"

android {
compileSdkVersion 31
compileSdk 34

defaultConfig {
minSdkVersion 19
targetSdkVersion 31
versionCode 1
versionName "1.0"
minSdk 19
targetSdk 34

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
minified {
debuggable true
minifyEnabled true
}
}
Expand All @@ -48,12 +45,12 @@ android {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}

lintOptions {
lint {
abortOnError true
htmlReport true
textReport true
lintConfig file("${project.rootDir}/linters/android-lint/config.xml")
baseline file("lint-baseline.xml")
lintConfig file("$rootDir/linters/android-lint/config.xml")
baseline file('lint-baseline.xml')
}

testOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class AnalyticsProvider @Inject constructor(context: Context) {

// Avoid recursion (Timber.i reports a breadcrumb). TODO proper design and fix this
if (event !is AnalyticsEvent.E_BREADCRUMB) {
Timber.i("AnalyticsProvider", event.toString())
Timber.i("AnalyticsProvider: $event")
}

} catch (t: Throwable) {
Expand Down
17 changes: 0 additions & 17 deletions android/apollo/src/main/java/io/muun/apollo/data/external/Gen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -292,23 +292,6 @@ object Gen {
private fun muunAddress() =
MuunAddress(1, "m/1/2/3", address())

/**
* Get a PaymentRequest
*/
fun payReq(
amount: MonetaryAmount = Money.of(0, "USD"),
feeRate: Double = 10.0,
takeFeeFromAmount: Boolean = false,

) = PaymentRequest(
type = PaymentRequest.Type.TO_ADDRESS,
amount = amount,
description = "foo",
address = address(),
feeInSatoshisPerByte = feeRate,
takeFeeFromAmount = takeFeeFromAmount
)

fun submarineSwap(
outputAmountInSatoshis: Long,
sweepFeeInSatoshis: Long = 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import io.muun.apollo.data.net.ConnectivityInfoProvider
import io.muun.apollo.data.net.NetworkInfoProvider
import kotlinx.serialization.Serializable
import java.util.Locale
import java.util.TimeZone
import javax.inject.Inject

private const val UNSUPPORTED = -1
Expand All @@ -27,6 +26,7 @@ class BackgroundExecutionMetricsProvider @Inject constructor(
private val activityManagerInfoProvider: ActivityManagerInfoProvider,
private val resourcesInfoProvider: ResourcesInfoProvider,
private val systemCapabilitiesProvider: SystemCapabilitiesProvider,
private val dateTimeZoneProvider: DateTimeZoneProvider,
) {

private val powerManager: PowerManager by lazy {
Expand Down Expand Up @@ -54,7 +54,7 @@ class BackgroundExecutionMetricsProvider @Inject constructor(
SystemClock.elapsedRealtime(),
hardwareCapabilitiesProvider.bootCount,
Locale.getDefault().toString(),
TimeZone.getDefault().rawOffset / 1000L,
dateTimeZoneProvider.timeZoneOffsetSeconds,
telephonyInfoProvider.region.orElse(""),
telephonyInfoProvider.simRegion,
appInfoProvider.appDatadir,
Expand All @@ -68,7 +68,10 @@ class BackgroundExecutionMetricsProvider @Inject constructor(
systemCapabilitiesProvider.developerEnabled,
connectivityInfoProvider.proxyHttp,
connectivityInfoProvider.proxyHttps,
connectivityInfoProvider.proxySocks
connectivityInfoProvider.proxySocks,
dateTimeZoneProvider.autoDateTime,
dateTimeZoneProvider.autoTimeZone,
dateTimeZoneProvider.timeZoneId
)

@Suppress("ArrayInDataClass")
Expand Down Expand Up @@ -108,6 +111,9 @@ class BackgroundExecutionMetricsProvider @Inject constructor(
private val proxyHttp: String,
private val proxyHttps: String,
private val proxySocks: String,
private val autoDateTime: Int,
private val autoTimeZone: Int,
private val timeZoneId: String,
)

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.muun.apollo.data.os

import android.content.Context
import android.provider.Settings
import java.util.TimeZone
import javax.inject.Inject

class DateTimeZoneProvider @Inject constructor(private val context: Context) {

val autoTimeZone: Int
get() {
return Settings.Global.getInt(
context.contentResolver,
Settings.Global.AUTO_TIME_ZONE,
-1
)
}

val autoDateTime: Int
get() {
return Settings.Global.getInt(
context.contentResolver,
Settings.Global.AUTO_TIME,
-1
)
}

val timeZoneId: String
get() {
return TimeZone.getDefault().id.take(100)
}

val timeZoneOffsetSeconds: Long
get() {
return TimeZone.getDefault().rawOffset / 1000L
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public byte[] getAesIv(String key) {
*/
public synchronized byte[] getPersistentSecureRandomBytes(String key, int size) {
if (sharedPreferences.contains(key)) {
Timber.i("getPersistentSecureRandomBytes for " + key + ". Cached.");
final byte[] iv = getBytes(key);

// We've had a few InvalidKeyExceptions that might come from invalid IVs
Expand All @@ -90,6 +91,7 @@ public synchronized byte[] getPersistentSecureRandomBytes(String key, int size)
return iv;

} else {
Timber.i("getPersistentSecureRandomBytes for " + key + ". Generate new");
final byte[] bytes = RandomGenerator.getBytes(size);
saveBytes(bytes, key);
return bytes;
Expand All @@ -102,7 +104,14 @@ public synchronized byte[] getPersistentSecureRandomBytes(String key, int size)
public void saveBytes(byte[] bytes, String key) {
initSecureStorage();

sharedPreferences.edit().putString(key, SerializationUtils.serializeBytes(bytes)).commit();
final boolean writeSuccess = sharedPreferences.edit()
.putString(key, SerializationUtils.serializeBytes(bytes))
.commit();

Timber.i("SaveBytes for " + key + " success:" + writeSuccess );
if (!writeSuccess) {
Timber.e("Error while committing write to secure storage preferences");
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ public boolean has(String key) {
// our error report infra offers more metadata/insights on this issue
if (hasKeyInPreferences != hasKeyInKeystore) {
final SecureStorageError error = new SecureStorageError(debugSnapshot());
error.addMetadata("key", key);
error.addMetadata("hasKeyInPreferences", hasKeyInPreferences);
error.addMetadata("hasKeyInKeystore", hasKeyInKeystore);
Timber.e(error);
throw error;
}
Expand Down Expand Up @@ -196,6 +199,7 @@ private void storeEncrypted(String key, byte[] input) {
preferences.saveBytes(keyStore.encryptData(input, key, preferences.getAesIv(key)), key);
} catch (Throwable e) {
Timber.i("SecureStorageError on WRITE for key: " + key);
Timber.e(e);
final SecureStorageError ssError = new SecureStorageError(e, debugSnapshot());
enhanceError(ssError, key);
throw ssError;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import io.muun.apollo.domain.model.user.UserPhoneNumber;
import io.muun.apollo.domain.model.user.UserProfile;
import io.muun.common.Optional;
import io.muun.common.model.Currency;
import io.muun.common.model.PhoneNumber;
import io.muun.common.utils.Preconditions;

Expand All @@ -32,6 +33,7 @@
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.money.CurrencyUnit;

@Singleton
public class UserRepository extends BaseRepository {
Expand Down Expand Up @@ -487,26 +489,37 @@ public static class StoredUserJson {
// and migrate the preference to a non-minified JSON this class is APPEND-ONLY.

public long hid;

public String email;

public String createdAt;

public String phoneNumber;

public boolean isPhoneNumberVerified;

public String firstName;

public String lastName;

public String profilePictureUrl;

public boolean isEmailVerified;

public boolean hasRecoveryCode;

public boolean hasPassword;

public boolean hasP2PEnabled;

public boolean hasExportedKeys;

public String currency;

public String emergencyKitLastExportedAt;

public Integer emergencyKitVersion;

public String emergencyKitExportMethod;

@NonNull // Not backed by Houston, cached locally
Expand Down Expand Up @@ -551,25 +564,27 @@ public StoredUserJson() {
/**
* Manual constructor.
*/
public StoredUserJson(long hid,
String email,
String createdAt,
String phoneNumber,
boolean isPhoneNumberVerified,
String firstName,
String lastName,
String profilePictureUrl,
boolean isEmailVerified,
boolean hasRecoveryCode,
boolean hasPassword,
boolean hasP2PEnabled,
boolean hasExportedKeys,
String currency,
String emergencyKitLastExportedAt,
Integer emergencyKitVersion,
EmergencyKitExport.Method emergencyKitExportMethod,
@NonNull StoredEkVerificationCodes ekVerificationCodes,
@NonNull List<Integer> ekVersions) {
public StoredUserJson(
long hid,
String email,
String createdAt,
String phoneNumber,
boolean isPhoneNumberVerified,
String firstName,
String lastName,
String profilePictureUrl,
boolean isEmailVerified,
boolean hasRecoveryCode,
boolean hasPassword,
boolean hasP2PEnabled,
boolean hasExportedKeys,
String currency,
String emergencyKitLastExportedAt,
Integer emergencyKitVersion,
EmergencyKitExport.Method emergencyKitExportMethod,
@NonNull StoredEkVerificationCodes ekVerificationCodes,
@NonNull List<Integer> ekVersions
) {

this.hid = hid;
this.email = email;
Expand Down Expand Up @@ -608,7 +623,7 @@ User toUser() {
? Optional.of(new UserProfile(firstName, lastName, profilePictureUrl))
: Optional.empty(),

SerializationUtils.deserializeCurrencyUnit(currency != null ? currency : "USD"),
loadCurrencyFromStorage(),

hasRecoveryCode,
hasPassword,
Expand All @@ -626,6 +641,18 @@ User toUser() {
);
}

private CurrencyUnit loadCurrencyFromStorage() {
try {
final String currencyCode = currency != null ? currency : "USD";
return SerializationUtils.deserializeCurrencyUnit(currencyCode);

} catch (Exception e) {
// This can happen for example if user primary currency is no longer supported
// after an app or OS update.
return Currency.getUnit(Currency.DEFAULT.getCode()).get();
}
}

void initEmergencyKitVersion() {
if (emergencyKitLastExportedAt != null) {
emergencyKitVersion = (int) Libwallet.EKVersionDescriptors;
Expand Down Expand Up @@ -683,9 +710,11 @@ public StoredUserJson get(@NonNull String key, @NonNull SharedPreferences prefer
}

@Override
public void set(@NonNull String key,
@NonNull StoredUserJson value,
@NonNull SharedPreferences.Editor editor) {
public void set(
@NonNull String key,
@NonNull StoredUserJson value,
@NonNull SharedPreferences.Editor editor
) {
super.set(key, value, editor);
}
}
Expand Down
Loading

0 comments on commit 7111460

Please sign in to comment.