Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f393c3a0 authored by cketti's avatar cketti
Browse files

Move Android permission handling out of K9Activity

parent 4cb7e464
Loading
Loading
Loading
Loading
+1 −55
Original line number Diff line number Diff line
package com.fsck.k9.activity;


import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;

import androidx.annotation.LayoutRes;
import androidx.annotation.StringRes;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.view.View;
import com.fsck.k9.ui.R;
import com.fsck.k9.ui.ThemeManager;
import com.fsck.k9.ui.permissions.PermissionRationaleDialogFragment;
import timber.log.Timber;


public abstract class K9Activity extends AppCompatActivity {
    public static final int PERMISSIONS_REQUEST_READ_CONTACTS  = 1;
    private static final String FRAGMENT_TAG_RATIONALE = "rationale";


    private final K9ActivityCommon base = new K9ActivityCommon(this, ThemeType.DEFAULT);

    public ThemeManager getThemeManager() {
@@ -49,47 +38,4 @@ public abstract class K9Activity extends AppCompatActivity {
        }
        setSupportActionBar(toolbar);
    }

    public boolean hasPermission(Permission permission) {
        return ContextCompat.checkSelfPermission(this, permission.permission) == PackageManager.PERMISSION_GRANTED;
    }

    public void requestPermissionOrShowRationale(Permission permission) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission.permission)) {
            PermissionRationaleDialogFragment dialogFragment =
                    PermissionRationaleDialogFragment.newInstance(permission);

            dialogFragment.show(getSupportFragmentManager(), FRAGMENT_TAG_RATIONALE);
        } else {
            requestPermission(permission);
        }
    }

    public void requestPermission(Permission permission) {
        Timber.i("Requesting permission: " + permission.permission);
        ActivityCompat.requestPermissions(this, new String[] { permission.permission }, permission.requestCode);
    }


    public enum Permission {
        READ_CONTACTS(
                Manifest.permission.READ_CONTACTS,
                PERMISSIONS_REQUEST_READ_CONTACTS,
                R.string.permission_contacts_rationale_title,
                R.string.permission_contacts_rationale_message
        );


        public final String permission;
        public final int requestCode;
        public final int rationaleTitle;
        public final int rationaleMessage;

        Permission(String permission, int requestCode, @StringRes int rationaleTitle, @StringRes int rationaleMessage) {
            this.permission = permission;
            this.requestCode = requestCode;
            this.rationaleTitle = rationaleTitle;
            this.rationaleMessage = rationaleMessage;
        }
    }
}
+23 −1
Original line number Diff line number Diff line
@@ -110,7 +110,11 @@ import com.fsck.k9.ui.compose.QuotedMessageMvpView;
import com.fsck.k9.ui.compose.QuotedMessagePresenter;
import com.fsck.k9.ui.helper.SizeFormatter;
import com.fsck.k9.ui.messagelist.DefaultFolderProvider;
import com.fsck.k9.ui.permissions.K9PermissionUiHelper;
import com.fsck.k9.ui.permissions.Permission;
import com.fsck.k9.ui.permissions.PermissionUiHelper;

import org.jetbrains.annotations.NotNull;
import org.openintents.openpgp.OpenPgpApiManager;
import org.openintents.openpgp.util.OpenPgpApi;
import timber.log.Timber;
@@ -120,7 +124,7 @@ import timber.log.Timber;
public class MessageCompose extends K9Activity implements OnClickListener,
        CancelListener, AttachmentDownloadCancelListener, OnFocusChangeListener,
        OnOpenPgpInlineChangeListener, OnOpenPgpSignOnlyChangeListener, MessageBuilder.Callback,
        AttachmentPresenter.AttachmentsChangedListener, OnOpenPgpDisableListener {
        AttachmentPresenter.AttachmentsChangedListener, OnOpenPgpDisableListener, PermissionUiHelper {

    private static final int DIALOG_SAVE_OR_DISCARD_DRAFT_MESSAGE = 1;
    private static final int DIALOG_CONFIRM_DISCARD_ON_BACK = 2;
@@ -177,6 +181,8 @@ public class MessageCompose extends K9Activity implements OnClickListener,
    private final MessageLoaderHelperFactory messageLoaderHelperFactory = DI.get(MessageLoaderHelperFactory.class);
    private final DefaultFolderProvider defaultFolderProvider = DI.get(DefaultFolderProvider.class);

    private final PermissionUiHelper permissionUiHelper = new K9PermissionUiHelper(this);

    private QuotedMessagePresenter quotedMessagePresenter;
    private MessageLoaderHelper messageLoaderHelper;
    private AttachmentPresenter attachmentPresenter;
@@ -1883,4 +1889,20 @@ public class MessageCompose extends K9Activity implements OnClickListener,
            return titleResource;
        }
    }

    @Override
    public boolean hasPermission(@NotNull Permission permission) {
        return permissionUiHelper.hasPermission(permission);
    }

    @Override
    public void requestPermissionOrShowRationale(@NotNull Permission permission) {
        permissionUiHelper.requestPermissionOrShowRationale(permission);
    }

    @Override
    public void requestPermission(@NotNull Permission permission) {
        permissionUiHelper.requestPermission(permission);
    }

}
+24 −1
Original line number Diff line number Diff line
@@ -60,9 +60,15 @@ import com.fsck.k9.ui.messageview.MessageViewFragment;
import com.fsck.k9.ui.messageview.MessageViewFragment.MessageViewFragmentListener;
import com.fsck.k9.ui.messageview.PlaceholderFragment;
import com.fsck.k9.ui.onboarding.OnboardingActivity;
import com.fsck.k9.ui.permissions.K9PermissionUiHelper;
import com.fsck.k9.ui.permissions.Permission;
import com.fsck.k9.ui.permissions.PermissionUiHelper;
import com.fsck.k9.view.ViewSwitcher;
import com.fsck.k9.view.ViewSwitcher.OnSwitchCompleteListener;
import com.mikepenz.materialdrawer.Drawer.OnDrawerListener;

import org.jetbrains.annotations.NotNull;

import timber.log.Timber;


@@ -72,7 +78,7 @@ import timber.log.Timber;
 * From this Activity the user can perform all standard message operations.
 */
public class MessageList extends K9Activity implements MessageListFragmentListener,
        MessageViewFragmentListener, OnBackStackChangedListener, OnSwitchCompleteListener {
        MessageViewFragmentListener, OnBackStackChangedListener, OnSwitchCompleteListener, PermissionUiHelper {

    private static final String EXTRA_SEARCH = "search_bytes";
    private static final String EXTRA_NO_THREADING = "no_threading";
@@ -178,6 +184,8 @@ public class MessageList extends K9Activity implements MessageListFragmentListen
    private final NotificationChannelManager channelUtils = DI.get(NotificationChannelManager.class);
    private final DefaultFolderProvider defaultFolderProvider = DI.get(DefaultFolderProvider.class);

    private final PermissionUiHelper permissionUiHelper = new K9PermissionUiHelper(this);

    private ActionBar actionBar;
    private ActionBarDrawerToggle drawerToggle;
    private K9Drawer drawer;
@@ -1622,4 +1630,19 @@ public class MessageList extends K9Activity implements MessageListFragmentListen
            drawer.deselect();
        }
    }

    @Override
    public boolean hasPermission(@NotNull Permission permission) {
        return permissionUiHelper.hasPermission(permission);
    }

    @Override
    public void requestPermissionOrShowRationale(@NotNull Permission permission) {
        permissionUiHelper.requestPermissionOrShowRationale(permission);
    }

    @Override
    public void requestPermission(@NotNull Permission permission) {
        permissionUiHelper.requestPermission(permission);
    }
}
+21 −0
Original line number Diff line number Diff line
package com.fsck.k9.ui.permissions

import android.Manifest
import androidx.annotation.StringRes
import com.fsck.k9.ui.R

private const val PERMISSIONS_REQUEST_READ_CONTACTS = 1

enum class Permission(
    val permission: String,
    val requestCode: Int,
    @param:StringRes val rationaleTitle: Int,
    @param:StringRes val rationaleMessage: Int
) {
    READ_CONTACTS(
        Manifest.permission.READ_CONTACTS,
        PERMISSIONS_REQUEST_READ_CONTACTS,
        R.string.permission_contacts_rationale_title,
        R.string.permission_contacts_rationale_message
    );
}
+11 −14
Original line number Diff line number Diff line
@@ -5,15 +5,13 @@ import android.app.Dialog
import android.os.Bundle
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import com.fsck.k9.activity.K9Activity
import com.fsck.k9.activity.K9Activity.Permission
import com.fsck.k9.ui.R

/**
 * A dialog displaying a message to explain why the app requests a certain permission.
 *
 * Closing the dialog triggers a permission request. For this to work the Activity needs to be a subclass of
 * [K9Activity].
 * Closing the dialog triggers a permission request. For this to work the Activity needs to implement
 * [PermissionUiHelper].
 */
class PermissionRationaleDialogFragment : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
@@ -22,22 +20,21 @@ class PermissionRationaleDialogFragment : DialogFragment() {

        val permission = Permission.valueOf(permissionName)

        return AlertDialog.Builder(requireContext()).apply {
            setTitle(permission.rationaleTitle)
            setMessage(permission.rationaleMessage)
            setPositiveButton(R.string.okay_action) { _, _ ->
                val activity = requireActivity() as? K9Activity
                        ?: throw AssertionError("PermissionRationaleDialogFragment can only be used with K9Activity")
        return AlertDialog.Builder(requireContext())
            .setTitle(permission.rationaleTitle)
            .setMessage(permission.rationaleMessage)
            .setPositiveButton(R.string.okay_action) { _, _ ->
                val permissionUiHelper = requireActivity() as? PermissionUiHelper
                        ?: throw AssertionError("Activities using PermissionRationaleDialogFragment need to " +
                            "implement PermissionUiHelper")

                activity.requestPermission(permission)
            }
                permissionUiHelper.requestPermission(permission)
            }.create()
    }

    companion object {
        private const val ARG_PERMISSION = "permission"

        @JvmStatic
        fun newInstance(permission: Permission): PermissionRationaleDialogFragment {
            return PermissionRationaleDialogFragment().apply {
                arguments = bundleOf(ARG_PERMISSION to permission.name)
Loading