callbacks/maoni-email/src/main/java/org/rm3l/maoni/email/MaoniEmailListener.java

Summary

Maintainability
C
1 day
Test Coverage
/*
 * Copyright (c) 2016-2022 Armel Soro
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package org.rm3l.maoni.email;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;

import org.rm3l.maoni.common.contract.Listener;
import org.rm3l.maoni.common.model.Feedback;

import java.util.ArrayList;
import java.util.Map;

/**
 * Simple callback for Maoni that takes care of sending the Feedback via an email provider
 */
public class MaoniEmailListener implements Listener {

    public static final String DEFAULT_EMAIL_SUBJECT = "Feedback";

    private final Context mContext;
    private final String mMimeType;
    private final String mSubject;
    private final String[] mToAddresses;
    private final String mBodyHeader;
    private final String mBodyFooter;
    private final String[] mCcAddresses;
    private final String[] mBccAddresses;

    public MaoniEmailListener(final Context context, final String... toAddresses) {
        this(context, DEFAULT_EMAIL_SUBJECT, toAddresses);
    }

    public MaoniEmailListener(final Context context, final String subject,
        final String[] toAddresses) {
        this(context, subject, toAddresses, null, null);
    }

    public MaoniEmailListener(final Context context, final String subject,
        final String[] toAddresses, final String[] ccAddresses, final String[] bccAddresses) {
        this(context, "text/html", subject, null, null, toAddresses, ccAddresses, bccAddresses);
    }

    public MaoniEmailListener(
            final Context context,
            final String mimeType,
            final String subject,
            final String bodyHeader,
            final String bodyFooter,
            final String[] toAddresses,
            final String[] ccAddresses,
            final String[] bccAddresses) {
        this.mContext = context;
        this.mMimeType = mimeType;
        this.mSubject = subject;
        this.mToAddresses = toAddresses;
        this.mBodyHeader = bodyHeader;
        this.mBodyFooter = bodyFooter;
        this.mCcAddresses = ccAddresses;
        this.mBccAddresses = bccAddresses;
    }

    @Override
    public void onDismiss() {
        //Nothing to do
    }

    @Override
    public boolean onSendButtonClicked(final Feedback feedback) {

        final Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
        intent.setData(Uri.parse("mailto:")); // only email apps should handle this
        intent.putExtra(Intent.EXTRA_SUBJECT,
                mSubject != null ? mSubject : DEFAULT_EMAIL_SUBJECT);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
            if (mToAddresses != null) {
                intent.putExtra(Intent.EXTRA_EMAIL, mToAddresses);
            }
            if (mCcAddresses != null) {
                intent.putExtra(Intent.EXTRA_CC, mCcAddresses);
            }
            if (mBccAddresses != null) {
                intent.putExtra(Intent.EXTRA_BCC, mBccAddresses);
            }
        }
        if (mMimeType != null) {
            intent.setType(mMimeType);
        }

        final StringBuilder body = new StringBuilder();
        if (mBodyHeader != null) {
            body.append(mBodyHeader).append("\n\n");
        }

        body.append(feedback.userComment).append("\n\n");

        body.append("\n------------\n");
        body.append("- Feedback ID: ").append(feedback.id).append("\n");

        final Map<CharSequence, Object> additionalData = feedback.getAdditionalData();
        if (additionalData != null) {
            body.append("\n------ Extra-fields ------\n");
            for (final Map.Entry<CharSequence, Object> entry : additionalData.entrySet()) {
                body.append("- ")
                        .append(entry.getKey()).append(": ").
                        append(entry.getValue()).append("\n");
            }
        }

        body.append("\n------ Application ------\n");
        if (feedback.appInfo != null) {
            if (feedback.appInfo.applicationId != null) {
                body.append("- Application ID: ").append(feedback.appInfo.applicationId).append("\n");
            }
            if (feedback.appInfo.caller != null) {
                body.append("- Activity: ").append(feedback.appInfo.caller).append("\n");
            }
            if (feedback.appInfo.buildType != null) {
                body.append("- Build Type: ").append(feedback.appInfo.buildType).append("\n");
            }
            if (feedback.appInfo.flavor != null) {
                body.append("- Flavor: ").append(feedback.appInfo.flavor).append("\n");
            }
            if (feedback.appInfo.versionCode != null) {
                body.append("- Version Code: ").append(feedback.appInfo.versionCode).append("\n");
            }
            if (feedback.appInfo.versionName != null) {
                body.append("- Version Name: ").append(feedback.appInfo.versionName).append("\n");
            }
        }

        body.append("\n------ Device ------\n");
        if (feedback.deviceInfo != null) {
            body.append(feedback.deviceInfo.toString());
        }
        body.append("\n\n");

        if (mBodyFooter != null) {
            body.append("\n--").append(mBodyFooter);
        }

        intent.putExtra(Intent.EXTRA_TEXT, body.toString());

        final ComponentName componentName = intent.resolveActivity(mContext.getPackageManager());
        if (componentName != null) {
            //Add screenshot as attachment
            final ArrayList<Uri> attachmentsUris = new ArrayList<>();
            if (feedback.screenshotFileUri != null) {
                //Grant READ permission to the intent
                mContext.grantUriPermission(componentName.getPackageName(),
                        feedback.screenshotFileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
                attachmentsUris.add(feedback.screenshotFileUri);
            }
            //Add logs file as attachment
            if (feedback.logsFileUri != null) {
                //Grant READ permission to the intent
                mContext.grantUriPermission(componentName.getPackageName(),
                        feedback.logsFileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
                attachmentsUris.add(feedback.logsFileUri);
            }
            if (!attachmentsUris.isEmpty()) {
                intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachmentsUris);
            }
            mContext.startActivity(intent);
        }

        return true;
    }
}