package com.stripe.android;

import android.app.Activity;
import android.content.Intent;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.stripe.android.model.PaymentIntent;
import com.stripe.android.utils.ObjectUtils;
import com.stripe.android.view.ActivityStarter;
import com.stripe.android.view.PaymentAuthRelayActivity;
import com.stripe.android.view.PaymentAuthenticationExtras;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

class Stripe3ds2CompletionStarter
        implements ActivityStarter<Stripe3ds2CompletionStarter.StartData> {
    @NonNull private final Activity mActivity;
    private final int mRequestCode;

    Stripe3ds2CompletionStarter(@NonNull Activity activity, int requestCode) {
        mActivity = activity;
        mRequestCode = requestCode;
    }

    @Override
    public void start(@NonNull StartData data) {
        final Intent intent = new Intent(mActivity, PaymentAuthRelayActivity.class)
                .putExtra(PaymentAuthenticationExtras.CLIENT_SECRET,
                        data.mPaymentIntent.getClientSecret());
        mActivity.startActivityForResult(intent, mRequestCode);
    }

    @IntDef({Status.COMPLETE, Status.CANCEL, Status.TIMEOUT, Status.PROTOCOL_ERROR,
            Status.RUNTIME_ERROR})
    @Retention(RetentionPolicy.SOURCE)
    @interface Status {
        int COMPLETE = 0;
        int CANCEL = 1;
        int TIMEOUT = 2;
        int PROTOCOL_ERROR = 3;
        int RUNTIME_ERROR = 4;
    }

    static class StartData {
        @NonNull private final PaymentIntent mPaymentIntent;
        @Status private final int mStatus;
        @Nullable private final String mCompletionTransactionStatus;

        @NonNull
        static StartData createForComplete(@NonNull PaymentIntent paymentIntent,
                                           @NonNull String completionTransactionStatus) {
            return new StartData(paymentIntent, Status.COMPLETE, completionTransactionStatus);
        }

        StartData(@NonNull PaymentIntent paymentIntent,
                  @Status int status) {
            this(paymentIntent, status, null);
        }

        private StartData(@NonNull PaymentIntent paymentIntent, @Status int status,
                          @Nullable String completionTransactionStatus) {
            mPaymentIntent = paymentIntent;
            mStatus = status;
            mCompletionTransactionStatus = completionTransactionStatus;
        }

        @Override
        public int hashCode() {
            return ObjectUtils.hash(mPaymentIntent, mStatus, mCompletionTransactionStatus);
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            return super.equals(obj) || (obj instanceof StartData && typedEquals((StartData) obj));
        }

        private boolean typedEquals(@NonNull StartData startData) {
            return ObjectUtils.equals(mPaymentIntent, startData.mPaymentIntent) &&
                    ObjectUtils.equals(mStatus, startData.mStatus) &&
                    ObjectUtils.equals(mCompletionTransactionStatus,
                            startData.mCompletionTransactionStatus);
        }
    }
}

@@ -553,16 +553,52 @@
 nPolicy;
+%0Aimport java.lang.ref.WeakReference;
 %0A%0Aclass 
@@ -728,24 +728,38 @@
 e final 
+WeakReference%3C
 Activity
  mActivi
@@ -750,16 +750,17 @@
 Activity
+%3E
  mActivi
@@ -757,24 +757,27 @@
 y%3E mActivity
+Ref
 ;%0A    privat
@@ -903,19 +903,42 @@
 vity
- = 
+Ref = new WeakReference%3C%3E(
 activity
 ;%0A  
@@ -933,16 +933,17 @@
 activity
+)
 ;%0A      
@@ -1038,24 +1038,141 @@
 ata data) %7B%0A
+        final Activity activity = mActivityRef.get();%0A        if (activity == null) %7B%0A            return;%0A        %7D%0A%0A
         fina
@@ -1200,18 +1200,17 @@
  Intent(
-mA
+a
 ctivity,
@@ -1379,26 +1379,25 @@
 ));%0A        
-mA
+a
 ctivity.star

Use weak reference for Activity in Stripe3ds2CompletionStarter (#1051)