Skip to content

Commit

Permalink
Apollo: Release source code for 51.5
Browse files Browse the repository at this point in the history
  • Loading branch information
acrespo committed Dec 22, 2023
1 parent e801e0d commit 8294607
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 67 deletions.
7 changes: 7 additions & 0 deletions android/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ follow [https://changelog.md/](https://changelog.md/) guidelines.

## [Unreleased]

## [51.5] - 2023-12-22

### FIXED

- A crash regarding activity and fragment recreation, introduced in 51.4.
- Stopped adding email information to crashlytics reports.

## [51.4] - 2023-12-14

### ADDED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,8 @@ object Crashlytics {
* Set up Crashlytics metadata.
*/
@JvmStatic
fun configure(email: String?, userId: String) {
fun configure(userId: String) {
crashlytics?.setUserId(userId)
crashlytics?.setCustomKey("email", email ?: "unknown")

// TODO: use setUserEmail, and grab Houston session UUID to attach it
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ class LoggingContextManager @Inject constructor(
return // If no LOGGED-IN user do nothing (we handle sign-in flow on its own)
}

val user = maybeUser.get()
Crashlytics.configure(user.email.orElse(null), user.hid.toString())
Crashlytics.configure(maybeUser.get().hid.toString())

LoggingContext.locale = context.locale().toString()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class StartEmailSetupAction @Inject constructor(
user.email = Optional.of(email)
user.isEmailVerified = false

Crashlytics.configure(email, user.hid.toString())
Crashlytics.configure(user.hid.toString())

userRepository.store(user)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class CreateFirstSessionAction @Inject constructor(
keysRepo.storeBaseMuunPublicKey(it.cosigningPublicKey)
keysRepo.storeSwapServerPublicKey(it.swapServerPublicKey)

Crashlytics.configure(null, it.user.hid.toString())
Crashlytics.configure(it.user.hid.toString())

playIntegrityNonceRepo.store(it.playIntegrityNonce)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class CreateLoginSessionAction @Inject constructor(
)
}
.doOnNext {
Crashlytics.configure(email, "NotLoggedYet")
Crashlytics.configure("NotLoggedYet")
playIntegrityNonceRepo.store(it.playIntegrityNonce)
}
}
Expand Down
4 changes: 2 additions & 2 deletions android/apolloui/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ android {
applicationId "io.muun.apollo"
minSdkVersion 19
targetSdkVersion 33
versionCode 1104
versionName "51.4"
versionCode 1105
versionName "51.5"

// Needed to make sure these classes are available in the main DEX file for API 19
// See: https://spin.atomicobject.com/2018/07/16/support-kitkat-multidex/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,7 @@ public void dismissSnackBar() {

@NotNull // not true, but compatible with Kotlin lateinit var
public PresenterT getPresenter() {
Timber.d("Lifecycle: " + this + "#getPresenter:" + presenter);
return presenter; // make available to fragment presenters
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
import androidx.annotation.StringRes;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.viewbinding.ViewBinding;
import butterknife.ButterKnife;
import butterknife.Unbinder;
Expand All @@ -47,7 +45,7 @@
import javax.validation.constraints.NotNull;

public abstract class BaseFragment<PresenterT extends Presenter> extends Fragment
implements BaseView, Caller, PermissionRequester, DefaultLifecycleObserver {
implements BaseView, Caller, PermissionRequester {

private FragmentComponent component;

Expand Down Expand Up @@ -97,47 +95,6 @@ protected int getMenuResource() {
return 0;
}

@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);

Timber.d("Lifecycle: " + getClass().getSimpleName() + "#onAttach");

safeGetParentActivity()
.map(BaseActivity::getLifecycle)
.ifPresent(lifecycle -> lifecycle.addObserver(this));
}

/**
* Notifies that {@code ON_CREATE} event occurred for parent activity. Note this is the
* new, recommended way of handling deprecated Fragment#onActivityCreated callback.
*
* <p>Why are we removing the lifecycle observer in the onCreate method? Shouldn't we detach the
* lifecycle in the onDestroy?</p>
*
* <p><a href="https://developer.android.com/jetpack/androidx/releases/fragment#1.3.0-alpha02">
* As per the changelog:</a></p>
*
* <p>The onActivityCreated() method is now deprecated. Code touching the fragment's view should
* be done in onViewCreated() (which is called immediately before onActivityCreated()) and other
* initialization code should be in onCreate(). To receive a callback specifically when the
* activity's onCreate() is complete, a LifeCycleObserver should be registered on the activity's
* Lifecycle in onAttach(), and removed once the onCreate() callback is received.</p>
*
* @param owner the component, whose state was changed
*/
@Override
public void onCreate(@NonNull LifecycleOwner owner) {
safeGetParentActivity()
.map(BaseActivity::getLifecycle)
.ifPresent(lifecycle -> lifecycle.removeObserver(this));

Timber.d("Lifecycle: " + owner.getClass().getSimpleName() + "#onCreate");
Timber.d("Lifecycle: " + getClass().getSimpleName() + "#onActivityCreated");

onActivityCreated();
}

/**
* See {@link Fragment#onCreate(Bundle)}.
*
Expand Down Expand Up @@ -256,14 +213,6 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
protected void initializeUi(View view) {
}

/**
* Our own custom impl of deprecated Fragment#onActivityCreated. This will always be called
* AFTER the Activity's onCreate method has successfully finished.
*/
protected void onActivityCreated() {

}

/**
* Override this method to add any clean up logic.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ public void destroy() {

@Override
public void setView(@NotNull ViewT view) {
Timber.d("Lifecycle: " + this + "#setView");
this.view = view;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,54 @@
import io.muun.apollo.presentation.ui.listener.OnBackPressedListener;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import timber.log.Timber;

import javax.validation.constraints.NotNull;

public abstract class SingleFragment<PresenterT extends SingleFragmentPresenter>
extends BaseFragment<PresenterT> implements SingleFragmentView, OnBackPressedListener {

// TODO we're currently abusing how this lifecycle method works and when its called, in
// particular for activity recreation. Since its deprecated by Android, we should consider
// removing this and when doing so we should pay special attention to setParentPresenter and
// activity and fragment's presenter injection (via dagger).
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
Timber.d("Lifecycle: " + this + "#onActivityCreated");
super.onActivityCreated(savedInstanceState);
presenter.setParentPresenter(getParentActivity().getPresenter());
onActivityCreated();
}

@Override
/**
* Custom designed method for stuff we need to have AFTER activity's onCreate but BEFORE
* fragment's onCreateView (e.g particularly getParentActivity().attachHeader()).
*/
protected void onActivityCreated() {
getParentActivity().attachHeader();
setUpHeader();
}

@Override
public View onCreateView(
@NonNull LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState
) {
if (savedInstanceState != null) {
// Fragment is being re-created, activity is being recreated too and Android does not
// call fragment's onActivityCreated(Bundle) on its own (at least not "on time").
onActivityCreated();
}
return super.onCreateView(inflater, container, savedInstanceState);
}

/**
* Implement this method to perform initial visual setup of our MuunHeader (toolbar) component.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ class NewOperationErrorFragment : SingleFragment<NewOperationErrorPresenter>(),
override fun getLayoutResource(): Int =
R.layout.new_operation_error_fragment

override fun onActivityCreated() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
UiUtils.lastResortHideKeyboard(parentActivity)
}

Expand Down

0 comments on commit 8294607

Please sign in to comment.