...
 
Commits (28)
......@@ -39,7 +39,7 @@ buildscript {
'acra' : '4.6.1',
'appIntro' : '4.1.0',
'swipeLayout' : '1.2.0',
'dexter' : '5.0.0',
'dexter' : '6.0.1',
'workRuntime' : '2.0.1',
'androidJob' : '1.3.0-rc1',
'jcipAnnotations' : '1.0',
......
......@@ -28,6 +28,8 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!-- Needed for Android 28+ compatibility -->
......@@ -65,8 +67,6 @@
android:label="@string/delete_messages_label"
android:permissionGroup="android.permission-group.MESSAGES"
android:protectionLevel="dangerous" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="${applicationId}.permission.DELETE_MESSAGES" />
<application
......@@ -534,7 +534,7 @@
<activity
android:name=".pEp.ui.keys.PepExtraKeys"
android:label="Extra keys" />
<activity android:name=".pEp.ui.activities.PermissionsActivity" />
<activity android:name="security.pEp.ui.permissions.PermissionsActivity" />
<activity
android:name=".pEp.filepicker.FilePickerActivity"
android:label="@string/app_name"
......
This diff is collapsed.
package com.fsck.k9.activity;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.fsck.k9.Account;
import com.fsck.k9.AccountStats;
import com.fsck.k9.BaseAccount;
import com.fsck.k9.FontSizes;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.R;
import com.fsck.k9.activity.compose.MessageActions;
import com.fsck.k9.activity.misc.ExtendedAsyncTask;
import com.fsck.k9.activity.misc.NonConfigurationInstance;
import com.fsck.k9.activity.setup.AccountSetupBasics;
import com.fsck.k9.activity.setup.WelcomeMessage;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.helper.SizeFormatter;
import com.fsck.k9.mailstore.LocalFolder;
import com.fsck.k9.mailstore.StorageManager;
import com.fsck.k9.pEp.PEpImporterActivity;
import com.fsck.k9.pEp.ui.AboutActivity;
import com.fsck.k9.pEp.ui.listeners.OnBaseAccountClickListener;
import com.fsck.k9.pEp.ui.listeners.OnFolderClickListener;
import com.fsck.k9.pEp.ui.tools.FeedbackTools;
import com.fsck.k9.pEp.ui.tools.NestedListView;
import com.fsck.k9.preferences.SettingsExporter;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchAccount;
import com.fsck.k9.search.SearchSpecification.Attribute;
import com.fsck.k9.search.SearchSpecification.SearchField;
import com.fsck.k9.ui.settings.K9SettingsActivity;
import com.fsck.k9.ui.settings.account.AccountSettingsActivity;
import com.karumi.dexter.listener.single.CompositePermissionListener;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import foundation.pEp.jniadapter.Rating;
import timber.log.Timber;
public class AccountsLegacy extends PEpImporterActivity {
public class AccountsLegacy
//extends PEpImporterActivity
{
/*
/**
*/
/**
* URL used to open Android Market application
*/
*//*
private static final String ANDROID_MARKET_URL = "https://play.google.com/store/apps/details?id=org.openintents.filemanager";
/**
*/
/**
* Number of special accounts ('Unified Inbox' and 'All Messages')
*/
*//*
private static final int SPECIAL_ACCOUNTS_COUNT = 2;
private static final int DIALOG_REMOVE_ACCOUNT = 1;
......@@ -94,9 +32,11 @@ public class AccountsLegacy extends PEpImporterActivity {
private MessagingController controller;
/*
*/
/*
* Must be serializable hence implementation class used for declaration.
*/
*//*
private ConcurrentHashMap<String, AccountStats> accountStats = new ConcurrentHashMap<String, AccountStats>();
private ConcurrentMap<BaseAccount, String> pendingWork = new ConcurrentHashMap<BaseAccount, String>();
......@@ -116,11 +56,13 @@ public class AccountsLegacy extends PEpImporterActivity {
private boolean exportGlobalSettings;
private ArrayList<String> exportAccountUuids;
/**
*/
/**
* Contains information about objects that need to be retained on configuration changes.
*
* @see #onRetainNonConfigurationInstance()
*/
*//*
private NonConfigurationInstance nonConfigurationInstance;
......@@ -229,7 +171,8 @@ public class AccountsLegacy extends PEpImporterActivity {
@Override
public void folderStatusChanged(Account account, String folderServerId, int unreadMessageCount) {
/*try {
*/
/*try {
//TODO: FIX;
AccountStats stats = controller.getAccountStats(account);
if (stats == null) {
......@@ -239,7 +182,8 @@ public class AccountsLegacy extends PEpImporterActivity {
}
} catch (Exception e) {
Timber.e(e, "Unable to get account stats");
}*/
}*//*
}
@Override
public void accountStatusChanged(BaseAccount account, AccountStats stats) {
......@@ -449,14 +393,16 @@ public class AccountsLegacy extends PEpImporterActivity {
}
private void setupSettingsButton() {
/*View settingsButton = findViewById(R.id.settings_container);
*/
/*View settingsButton = findViewById(R.id.settings_container);
settingsButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onEditSettings();
}
});
*/}
*//*
}
private void setupAddAccountButton() {
addAccountButton = findViewById(R.id.add_account_container);
......@@ -474,9 +420,11 @@ public class AccountsLegacy extends PEpImporterActivity {
setStatusBarPepColor(Rating.pEpRatingFullyAnonymous);
}
/**
*/
/**
* Creates and initializes the special accounts ('Unified Inbox' and 'All Messages')
*/
*//*
private void createSpecialAccounts() {
unifiedInboxAccount = SearchAccount.createUnifiedInboxAccount(this);
allMessagesAccount = SearchAccount.createAllMessagesAccount(this);
......@@ -551,9 +499,11 @@ public class AccountsLegacy extends PEpImporterActivity {
mListener.onPause(this);
}
/**
*/
/**
* Save the reference to a currently displayed dialog or a running AsyncTask (if available).
*/
*//*
// TODO: 28/9/16 Fix this
// @Override
// public Object onRetainNonConfigurationInstance() {
......@@ -686,11 +636,13 @@ public class AccountsLegacy extends PEpImporterActivity {
}
/*
*/
/*
* This method is called with 'null' for the argument 'account' if
* all accounts are to be checked. This is handled accordingly in
* MessagingController.checkMail().
*/
*//*
private void onCheckMail(Account account) {
MessagingController.getInstance(getApplication()).checkMail(this, account, true, true, null);
if (account == null) {
......@@ -719,12 +671,14 @@ public class AccountsLegacy extends PEpImporterActivity {
}
}
/**
*/
/**
* Show that account's inbox or folder-list
* or return false if the account is not available.
* @param account the account to open ({@link SearchAccount} or {@link Account})
* @return false if unsuccessful
*/
*//*
private boolean onOpenAccount(BaseAccount account) {
if (account instanceof SearchAccount) {
SearchAccount searchAccount = (SearchAccount)account;
......@@ -757,14 +711,16 @@ public class AccountsLegacy extends PEpImporterActivity {
promptForServerPasswords(disabledAccounts);
}
/**
*/
/**
* Ask the user to enter the server passwords for disabled accounts.
*
* @param disabledAccounts
* A non-empty list of {@link Account}s to ask the user for passwords. Never
* {@code null}.
* <p><strong>Note:</strong> Calling this method will modify the supplied list.</p>
*/
*//*
private void promptForServerPasswords(final List<Account> disabledAccounts) {
Account account = disabledAccounts.remove(0);
PasswordPromptDialog dialog = new PasswordPromptDialog(account, disabledAccounts);
......@@ -1019,11 +975,13 @@ public class AccountsLegacy extends PEpImporterActivity {
}
/**
*/
/**
* Get current version number.
*
* @return String version
*/
*//*
private String getVersionNumber() {
String version = "?";
try {
......@@ -1120,14 +1078,16 @@ public class AccountsLegacy extends PEpImporterActivity {
}
/**
*/
/**
* Set the {@code NonConfigurationInstance} this activity should retain on configuration
* changes.
*
* @param inst
* The {@link NonConfigurationInstance} that should be retained when
* {@link AccountsLegacy#onRetainNonConfigurationInstance()} is called.
*/
*//*
public void setNonConfigurationInstance(NonConfigurationInstance inst) {
nonConfigurationInstance = inst;
}
......@@ -1389,4 +1349,4 @@ public class AccountsLegacy extends PEpImporterActivity {
public TextView descriptionUnreadMessages;
}
}
}
*/}
......@@ -20,8 +20,6 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.TypedValue;
......@@ -38,6 +36,9 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import com.fsck.k9.Account;
import com.fsck.k9.Account.MessageFormat;
import com.fsck.k9.Identity;
......@@ -89,14 +90,18 @@ import com.fsck.k9.message.SimpleMessageBuilder;
import com.fsck.k9.message.SimpleMessageFormat;
import com.fsck.k9.pEp.PEpProvider;
import com.fsck.k9.pEp.PePUIArtefactCache;
import com.fsck.k9.pEp.PepPermissionActivity;
import com.fsck.k9.pEp.PepActivity;
import com.fsck.k9.pEp.ui.tools.FeedbackTools;
import com.fsck.k9.ui.EolConvertingEditText;
import com.fsck.k9.ui.compose.QuotedMessageMvpView;
import com.fsck.k9.ui.compose.QuotedMessagePresenter;
import com.karumi.dexter.listener.single.CompositePermissionListener;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;
import foundation.pEp.jniadapter.Rating;
import org.openintents.openpgp.OpenPgpApiManager;
import java.util.Collections;
import java.util.Date;
......@@ -106,13 +111,15 @@ import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
import org.openintents.openpgp.OpenPgpApiManager;
import javax.inject.Inject;
import foundation.pEp.jniadapter.Rating;
import security.pEp.permissions.PermissionRequester;
import timber.log.Timber;
@SuppressWarnings("deprecation") // TODO get rid of activity dialogs and indeterminate progress bars
public class MessageCompose extends PepPermissionActivity implements OnClickListener,
public class MessageCompose extends PepActivity implements OnClickListener,
CancelListener, OnFocusChangeListener, OnCryptoModeChangedListener,
OnOpenPgpInlineChangeListener, PgpSignOnlyDialog.OnOpenPgpSignOnlyChangeListener, MessageBuilder.Callback,
AttachmentPresenter.AttachmentsChangedListener, RecipientPresenter.RecipientsChangedListener {
......@@ -175,7 +182,6 @@ public class MessageCompose extends PepPermissionActivity implements OnClickList
private MessageLoaderHelper messageLoaderHelper;
private AttachmentPresenter attachmentPresenter;
private boolean encrypted = true;
private CompositePermissionListener contactPermissionListener;
private LinearLayout rootView;
private MenuItem alwaysSecureMenuItem;
private PePUIArtefactCache uiCache;
......@@ -247,6 +253,14 @@ public class MessageCompose extends PepPermissionActivity implements OnClickList
private boolean isInSubActivity = false;
@Inject
PermissionRequester permissionRequester;
@Override
public void inject() {
getpEpComponent().inject(this);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......@@ -1931,22 +1945,25 @@ public class MessageCompose extends PepPermissionActivity implements OnClickList
public void askForPermissions() {
if(!permissionAsked) {
permissionAsked = true;
createContactsPermissionListeners();
}
}
public void showPermissionGranted(String permissionName) {
}
permissionRequester.requestContactsPermission(getRootView(), new PermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse response) {
}
public void showPermissionDenied(String permissionName, boolean permanentlyDenied) {
String permissionDenied = getResources().getString(R.string.read_snackbar_permission_permanently_denied);
FeedbackTools.showLongFeedback(getRootView(), permissionDenied);
}
@Override
public void onPermissionDenied(PermissionDeniedResponse response) {
String permissionDenied = getResources().getString(R.string.read_snackbar_permission_permanently_denied);
FeedbackTools.showLongFeedback(getRootView(), permissionDenied);
}
@Override
public void inject() {
@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
}
});
}
}
public void lockSendButton() {
isSendButtonLocked = true;
}
......
......@@ -12,17 +12,6 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.google.android.material.navigation.NavigationView;
import androidx.core.view.GravityCompat;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentManager.OnBackStackChangedListener;
import androidx.fragment.app.FragmentTransaction;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
......@@ -37,6 +26,16 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentManager.OnBackStackChangedListener;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.fsck.k9.Account;
import com.fsck.k9.Account.SortType;
import com.fsck.k9.AccountStats;
......@@ -84,6 +83,7 @@ import com.fsck.k9.view.MessageHeader;
import com.fsck.k9.view.MessageTitleView;
import com.fsck.k9.view.ViewSwitcher;
import com.fsck.k9.view.ViewSwitcher.OnSwitchCompleteListener;
import com.google.android.material.navigation.NavigationView;
import com.pedrogomez.renderers.ListAdapteeCollection;
import com.pedrogomez.renderers.RVRendererAdapter;
import com.pedrogomez.renderers.RendererBuilder;
......@@ -96,6 +96,7 @@ import java.util.List;
import javax.inject.Inject;
import foundation.pEp.jniadapter.Rating;
import security.pEp.permissions.PermissionRequester;
import timber.log.Timber;
......@@ -111,6 +112,8 @@ public class MessageList extends PepActivity implements MessageListFragmentListe
@Inject AccountUtils accountUtils;
@Inject
NotificationChannelManager channelUtils;
@Inject
PermissionRequester permissionRequester;
@Deprecated
//TODO: Remove after 2017-09-11
......@@ -368,6 +371,8 @@ public class MessageList extends PepActivity implements MessageListFragmentListe
return;
}
permissionRequester.requestBatteryOptimizationPermission();
findFragments();
initializeDisplayMode(savedInstanceState);
initializeLayout();
......
package com.fsck.k9.activity
import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
......@@ -44,12 +42,19 @@ import com.fsck.k9.ui.fragmentTransaction
import com.fsck.k9.ui.settings.account.AccountSettingsActivity
import com.fsck.k9.ui.settings.general.GeneralSettingsActivity
import com.fsck.k9.ui.settings.general.GeneralSettingsFragment
import com.karumi.dexter.listener.single.CompositePermissionListener
import com.karumi.dexter.PermissionToken
import com.karumi.dexter.listener.PermissionDeniedResponse
import com.karumi.dexter.listener.PermissionGrantedResponse
import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.single.PermissionListener
import kotlinx.android.synthetic.main.accounts.*
import kotlinx.coroutines.*
import security.pEp.permissions.PermissionChecker
import security.pEp.permissions.PermissionRequester
import timber.log.Timber
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
class SettingsActivity : PEpImporterActivity(), PreferenceFragmentCompat.OnPreferenceStartScreenCallback {
......@@ -84,8 +89,11 @@ class SettingsActivity : PEpImporterActivity(), PreferenceFragmentCompat.OnPrefe
private var nonConfigurationInstance: NonConfigurationInstance? = null
private var accountsList: NestedListView? = null
private var addAccountButton: View? = null
private val storagePermissionListener: CompositePermissionListener? = null
@Inject
lateinit var permissionRequester: PermissionRequester
@Inject
lateinit var permissionChecker: PermissionChecker
private val storageListener = object : StorageManager.StorageListener {
......@@ -205,6 +213,7 @@ class SettingsActivity : PEpImporterActivity(), PreferenceFragmentCompat.OnPrefe
return
}
val startup = intent.getBooleanExtra(EXTRA_STARTUP, true)
if (startup && K9.startIntegratedInbox() && !K9.isHideSpecialAccounts()) {
onOpenAccount(unifiedInboxAccount)
......@@ -242,24 +251,14 @@ class SettingsActivity : PEpImporterActivity(), PreferenceFragmentCompat.OnPrefe
}
setupAddAccountButton()
askForBatteryOptimizationWhiteListing()
}
override fun search(query: String) {
triggerSearch(query, null)
}
override fun showPermissionGranted(permissionName: String) {
}
override fun showPermissionDenied(permissionName: String, permanentlyDenied: Boolean) {
val permissionDenied = resources.getString(R.string.download_snackbar_permission_permanently_denied)
FeedbackTools.showLongFeedback(rootView, permissionDenied)
}
override fun inject() {
getpEpComponent().inject(this)
}
private fun setupAddAccountButton() {
......@@ -783,8 +782,26 @@ class SettingsActivity : PEpImporterActivity(), PreferenceFragmentCompat.OnPrefe
fun onExport(includeGlobals: Boolean, account: Account?) {
createStoragePermissionListeners()
if (hasWriteExternalPermission()) { // TODO, prompt to allow a user to choose which accounts to export
permissionRequester.requestStoragePermission(
rootView,
object : PermissionListener {
override fun onPermissionGranted(response: PermissionGrantedResponse?) {
}
override fun onPermissionRationaleShouldBeShown(permission: PermissionRequest?, token: PermissionToken?) {
}
override fun onPermissionDenied(response: PermissionDeniedResponse?) {
val permissionDenied = resources.getString(R.string.download_snackbar_permission_permanently_denied)
FeedbackTools.showLongFeedback(rootView, permissionDenied)
}
}
)
if (permissionChecker.hasWriteExternalPermission()) {
// TODO, prompt to allow a user to choose which accounts to export
var accountUuids: ArrayList<String>? = null
if (account != null) {
accountUuids = ArrayList()
......@@ -821,10 +838,6 @@ class SettingsActivity : PEpImporterActivity(), PreferenceFragmentCompat.OnPrefe
asyncTask.execute()
}
private fun hasWriteExternalPermission(): Boolean {
val res = applicationContext.checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
return res == PackageManager.PERMISSION_GRANTED
}
internal inner class AccountListAdapter(accounts: List<BaseAccount>, private val onFolderClickListener: OnFolderClickListener, private val onBaseAccountClickListener: OnBaseAccountClickListener) : ArrayAdapter<BaseAccount>(this@SettingsActivity, 0, accounts) {
......
......@@ -3,7 +3,6 @@ package com.fsck.k9.activity.compose;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
......@@ -12,7 +11,6 @@ import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Contacts.Data;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.loader.content.AsyncTaskLoader;
import com.fsck.k9.R;
......@@ -25,9 +23,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static android.Manifest.permission.READ_CONTACTS;
import static android.Manifest.permission.WRITE_CONTACTS;
import security.pEp.permissions.PermissionChecker;
import security.pEp.ui.permissions.PEpPermissionChecker;
public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
/*
......@@ -84,7 +81,7 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
private List<Recipient> cachedRecipients;
private ForceLoadContentObserver observerContact, observerKey;
private PermissionChecker permissionChecker;
public RecipientLoader(Context context, String cryptoProvider, String query) {
super(context);
......@@ -93,6 +90,7 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
this.addresses = null;
this.contactUri = null;
this.cryptoProvider = cryptoProvider;
this.permissionChecker = new PEpPermissionChecker(context);
}
public RecipientLoader(Context context, String cryptoProvider, Address... addresses) {
......@@ -102,6 +100,7 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
this.contactUri = null;
this.cryptoProvider = cryptoProvider;
this.lookupKeyUri = null;
this.permissionChecker = new PEpPermissionChecker(context);
}
public RecipientLoader(Context context, String cryptoProvider, Uri contactUri, boolean isLookupKey) {
......@@ -111,6 +110,7 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
this.contactUri = isLookupKey ? null : contactUri;
this.lookupKeyUri = isLookupKey ? contactUri : null;
this.cryptoProvider = cryptoProvider;
this.permissionChecker = new PEpPermissionChecker(context);
}
@Override
......@@ -118,10 +118,7 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
List<Recipient> recipients = new ArrayList<>();
int writeContactsPermission = ContextCompat.checkSelfPermission(getContext(), WRITE_CONTACTS);
int readContactsPermission = ContextCompat.checkSelfPermission(getContext(), READ_CONTACTS);
if (writeContactsPermission == PackageManager.PERMISSION_GRANTED &&
readContactsPermission == PackageManager.PERMISSION_GRANTED) {
if (permissionChecker.hasContactsPermission()) {
Map<String, Recipient> recipientMap = new HashMap<>();
if (addresses != null) {
......
......@@ -15,14 +15,14 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import androidx.annotation.VisibleForTesting;
import androidx.collection.LruCache;
import android.text.TextUtils;
import android.widget.ImageView;
import androidx.annotation.VisibleForTesting;
import androidx.collection.LruCache;
import com.fsck.k9.helper.Contacts;
import com.fsck.k9.mail.Address;
import com.fsck.k9.pEp.PEpPermissionChecker;
import java.io.FileNotFoundException;
import java.io.IOException;
......@@ -33,6 +33,9 @@ import java.util.concurrent.RejectedExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import security.pEp.permissions.PermissionChecker;
import security.pEp.ui.permissions.PEpPermissionChecker;
public class ContactPictureLoader {
/**
* Resize the pictures to the following value (device-independent pixels).
......@@ -56,6 +59,7 @@ public class ContactPictureLoader {
private int mPictureSizeInPx;
private int mDefaultBackgroundColor;
private PermissionChecker permissionChecker;
/**
* LRU cache of contact pictures.
......@@ -65,17 +69,17 @@ public class ContactPictureLoader {
/**
* @see <a href="http://developer.android.com/design/style/color.html">Color palette used</a>
*/
private final static int CONTACT_DUMMY_COLORS_ARGB[] = {
0xff33B5E5,
0xffAA66CC,
0xff99CC00,
0xffFFBB33,
0xffFF4444,
0xff0099CC,
0xff9933CC,
0xff669900,
0xffFF8800,
0xffCC0000
private final static int[] CONTACT_DUMMY_COLORS_ARGB = {
0xff33B5E5,
0xffAA66CC,
0xff99CC00,
0xffFFBB33,
0xffFF4444,
0xff0099CC,
0xff9933CC,
0xff669900,
0xffFF8800,
0xffCC0000
};
@VisibleForTesting
......@@ -96,16 +100,15 @@ public class ContactPictureLoader {
/**
* Constructor.
*
* @param context
* A {@link Context} instance.
* @param defaultBackgroundColor
* The ARGB value to be used as background color for the fallback picture. {@code 0} to
* use a dynamically calculated background color.
* @param context A {@link Context} instance.
* @param defaultBackgroundColor The ARGB value to be used as background color for the fallback picture. {@code 0} to
* use a dynamically calculated background color.
*/
public ContactPictureLoader(Context context, int defaultBackgroundColor) {
Context appContext = context.getApplicationContext();
permissionChecker = new PEpPermissionChecker(context);
mDefaultBackgroundColor = defaultBackgroundColor;
if (PEpPermissionChecker.hasContactsPermission(context)) {
if (permissionChecker.hasContactsPermission()) {
mContentResolver = appContext.getContentResolver();
mContactsHelper = Contacts.getInstance(appContext);
}
......@@ -138,12 +141,9 @@ public class ContactPictureLoader {
* fallback picture is then stored in the bitmap cache.
* </p>
*
* @param address
* The {@link Address} instance holding the email address that is used to search the
* contacts database.
* @param imageView
* The {@code QuickContactBadge} instance to receive the picture.
*
* @param address The {@link Address} instance holding the email address that is used to search the
* contacts database.
* @param imageView The {@code QuickContactBadge} instance to receive the picture.
* @see #mBitmapCache
* @see #calculateFallbackBitmap(Address)
*/
......@@ -244,15 +244,12 @@ public class ContactPictureLoader {
* Checks if a {@code ContactPictureRetrievalTask} was already created to load the contact
* picture for the supplied {@code Address}.
*
* @param address
* The {@link Address} instance holding the email address that is used to search the
* contacts database.
* @param imageView
* The {@link ImageView} instance that will receive the picture.
*
* @param address The {@link Address} instance holding the email address that is used to search the
* contacts database.
* @param imageView The {@link ImageView} instance that will receive the picture.
* @return {@code true}, if the contact picture should be loaded in a background thread.
* {@code false}, if another {@link ContactPictureRetrievalTask} was already scheduled
* to load that contact picture.
* {@code false}, if another {@link ContactPictureRetrievalTask} was already scheduled
* to load that contact picture.
*/
private boolean cancelPotentialWork(Address address, ImageView imageView) {
final ContactPictureRetrievalTask task = getContactPictureRetrievalTask(imageView);
......@@ -273,11 +270,11 @@ public class ContactPictureLoader {
private ContactPictureRetrievalTask getContactPictureRetrievalTask(ImageView imageView) {
if (imageView != null) {
Drawable drawable = imageView.getDrawable();
if (drawable instanceof AsyncDrawable) {
AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
return asyncDrawable.getContactPictureRetrievalTask();
}
Drawable drawable = imageView.getDrawable();
if (drawable instanceof AsyncDrawable) {
AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
return asyncDrawable.getContactPictureRetrievalTask();
}
}
return null;
......@@ -322,7 +319,9 @@ public class ContactPictureLoader {
}
}
} finally {
try { stream.close(); } catch (IOException e) { /* ignore */ }
try {
stream.close();
} catch (IOException e) { /* ignore */ }
}
}
} catch (FileNotFoundException e) {
......
package com.fsck.k9.activity.setup;
......@@ -7,10 +6,11 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.fragment.app.FragmentTransaction;
import android.view.Menu;
import android.view.MenuItem;
import androidx.fragment.app.FragmentTransaction;
import com.fsck.k9.Account;
import com.fsck.k9.Preferences;
import com.fsck.k9.R;
......@@ -24,6 +24,8 @@ import com.fsck.k9.pEp.ui.tools.AccountSetupNavigator;
import javax.inject.Inject;
import security.pEp.permissions.PermissionRequester;
/**
* Prompts the user for the email address and password.
* Attempts to lookup default settings for the domain the user specified. If the
......@@ -45,9 +47,13 @@ public class AccountSetupBasics extends PEpImporterActivity {
public boolean isEditingOutgoingSettings;
public boolean isBackOutgoingSettings;
private NonConfigurationInstance nonConfigurationInstance;
@Inject AccountSetupNavigator accountSetupNavigator;
@Inject
AccountSetupNavigator accountSetupNavigator;
private boolean isGoingBack = false;
@Inject
PermissionRequester permissionRequester;
public static void actionNewAccount(Context context) {
Intent i = new Intent(context, AccountSetupBasics.class);
context.startActivity(i);
......@@ -110,14 +116,13 @@ public class AccountSetupBasics extends PEpImporterActivity {
ft.addToBackStack("AccountSetupIncomingFragment");
String accountUuid = getIntent().getStringExtra(EXTRA_ACCOUNT);
ft.add(R.id.account_setup_container, AccountSetupOutgoingFragment.intentBackToOutgoingSettings(accountUuid)).commit();
}
else if (savedInstanceState == null) {
} else if (savedInstanceState == null) {
accountSetupBasicsFragment = new AccountSetupBasicsFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.addToBackStack("AccountSetupBasicsFragment");
ft.add(R.id.account_setup_container, accountSetupBasicsFragment).commit();
}
askForBatteryOptimizationWhiteListing();
permissionRequester.requestBatteryOptimizationPermission();
// Handle activity restarts because of a configuration change (e.g. rotating the screen)
nonConfigurationInstance = (NonConfigurationInstance) getLastNonConfigurationInstance();
......@@ -126,13 +131,6 @@ public class AccountSetupBasics extends PEpImporterActivity {
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.account_setup_basic_option, menu);
return true;
}
@Override
protected void refresh() {
}
......@@ -160,16 +158,6 @@ public class AccountSetupBasics extends PEpImporterActivity {
}
@Override
public void showPermissionGranted(String permissionName) {
accountSetupBasicsFragment.contactsPermissionGranted();
}
@Override
public void showPermissionDenied(String permissionName, boolean permanentlyDenied) {
accountSetupBasicsFragment.contactsPermissionDenied();
}
@Override
public void inject() {
getpEpComponent().inject(this);
......@@ -178,7 +166,7 @@ public class AccountSetupBasics extends PEpImporterActivity {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
AccountSetupIncomingFragment accountSetupIncomingFragment = (AccountSetupIncomingFragment)getSupportFragmentManager().findFragmentByTag("accountSetupIncomingFragment");
AccountSetupIncomingFragment accountSetupIncomingFragment = (AccountSetupIncomingFragment) getSupportFragmentManager().findFragmentByTag("accountSetupIncomingFragment");
if (accountSetupIncomingFragment != null && accountSetupIncomingFragment.isVisible()) {
accountSetupIncomingFragment.onActivityResult(requestCode, resultCode, data);
} else {
......
......@@ -3,16 +3,17 @@ package com.fsck.k9.activity.setup;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.fsck.k9.pEp.PEpPermissionChecker;
import com.fsck.k9.pEp.ui.activities.PermissionsActivity;
import com.fsck.k9.K9;
import com.fsck.k9.pEp.ui.fragments.intro.IntroFirstFragment;
import com.fsck.k9.pEp.ui.fragments.intro.IntroSecondFragment;
import com.fsck.k9.pEp.ui.fragments.intro.IntroThirdFragment;
import com.github.paolorotolo.appintro.AppIntro;
import security.pEp.ui.permissions.PermissionsActivity;
import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;
public class WelcomeMessage extends AppIntro {
......@@ -37,25 +38,25 @@ public class WelcomeMessage extends AppIntro {
@Override
public void onSkipPressed(Fragment currentFragment) {
super.onSkipPressed(currentFragment);
if (PEpPermissionChecker.hasBasicPermission(this)) {
AccountSetupBasics.actionNewAccount(this);
} else {
PermissionsActivity.actionAskPermissions(this);
}
finish();
nextAction();
}
@Override
public void onDonePressed(Fragment currentFragment) {
super.onDonePressed(currentFragment);
if (PEpPermissionChecker.hasBasicPermission(this)) {
AccountSetupBasics.actionNewAccount(this);
} else {
nextAction();
}
private void nextAction() {
if (K9.isShallRequestPermissions()) {
PermissionsActivity.actionAskPermissions(this);
} else {
AccountSetupBasics.actionNewAccount(this);
}
finish();
}
@Override
public void onSlideChanged(@Nullable Fragment oldFragment, @Nullable Fragment newFragment) {
super.onSlideChanged(oldFragment, newFragment);
......
......@@ -4427,8 +4427,9 @@ public class MessagingController implements Sync.MessageToSendCallback, KeyImpor
}
// Do not notify if the user does not have notifications enabled or if the message has
// been read.
if (!account.isNotifyNewMail() || message.isSet(Flag.SEEN)) {
// been read or it is an pep-autoconsume-message.
if (!account.isNotifyNewMail() || message.isSet(Flag.SEEN)
|| PEpUtils.isAutoConsumeMessage(message)) {
return false;
}
......
......@@ -14,7 +14,6 @@ import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
......@@ -28,6 +27,8 @@ import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
......@@ -47,8 +48,6 @@ import com.fsck.k9.preferences.SettingsImportExportException;
import com.fsck.k9.preferences.SettingsImporter;
import org.apache.commons.io.IOUtils;
import foundation.pEp.jniadapter.Identity;
import foundation.pEp.jniadapter.pEpException;
import java.io.FileNotFoundException;
import java.io.IOException;
......@@ -58,9 +57,11 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import foundation.pEp.jniadapter.Identity;
import foundation.pEp.jniadapter.pEpException;
import timber.log.Timber;
public abstract class PEpImporterActivity extends PepPermissionActivity {
public abstract class PEpImporterActivity extends PepActivity {
protected static final int ACTIVITY_REQUEST_PICK_SETTINGS_FILE = 1;
private static final int DIALOG_NO_FILE_MANAGER = 4;
......
......@@ -80,7 +80,7 @@ class PEpMessageBuilder {
String charset = MimeUtility.getHeaderParameter(mm.getContentType(), "charset");
if (!Charset.isSupported(charset)) {
if (charset == null || !Charset.isSupported(charset)) {
// failback when the header doesn't have charset parameter or it is invalid, defaults to UTF-8
// FIXME: charset, trate non text bod4y types like application/pgp-keys
charset = Charset.defaultCharset().name();
......
package com.fsck.k9.pEp;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
public class PEpPermissionChecker {
public static Boolean hasBasicPermission(Context context) {
return hasContactsPermission(context) && hasWriteExternalPermission(context);
}
public static Boolean hasWriteExternalPermission(Context context) {
int res = context.getApplicationContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
return (res == PackageManager.PERMISSION_GRANTED);
}
public static Boolean hasContactsPermission(Context context) {
int res = context.getApplicationContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_CONTACTS);
return (res == PackageManager.PERMISSION_GRANTED);
}
}
package com.fsck.k9.pEp;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.provider.Settings;
import com.google.android.material.snackbar.Snackbar;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.activity.K9Activity;
import com.fsck.k9.pEp.infrastructure.components.ApplicationComponent;
import com.fsck.k9.pEp.infrastructure.components.DaggerPEpComponent;
import com.fsck.k9.pEp.infrastructure.components.PEpComponent;
import com.fsck.k9.pEp.infrastructure.modules.ActivityModule;
import com.fsck.k9.pEp.infrastructure.modules.PEpModule;
import com.fsck.k9.pEp.ui.PermissionErrorListener;
import com.fsck.k9.pEp.ui.listeners.ActivityPermissionListener;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
import com.karumi.dexter.listener.single.CompositePermissionListener;
import com.karumi.dexter.listener.single.PermissionListener;
import com.karumi.dexter.listener.single.SnackbarOnDeniedPermissionListener;
import java.util.List;
public abstract class PepPermissionActivity extends K9Activity {
private CompositePermissionListener storagePermissionListener;
private CompositePermissionListener contactPermissionListener;
private PEpComponent pEpComponent;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeInjector(getApplicationComponent());
inject();
}
@Override
public void search(String query) {
/* no-op */
}
private ApplicationComponent getApplicationComponent() {
return getK9().getComponent();
}
public K9 getK9() {
return (K9) getApplication();
}
private void initializeInjector(ApplicationComponent applicationComponent) {
applicationComponent.inject(this);
pEpComponent = DaggerPEpComponent.builder()
.applicationComponent(applicationComponent)
.activityModule(new ActivityModule(this))
.pEpModule(new PEpModule(this, getSupportLoaderManager(), getSupportFragmentManager()))
.build();
}
public abstract void showPermissionGranted(String permissionName);
public abstract void showPermissionDenied(String permissionName, boolean permanentlyDenied);
public void createStoragePermissionListeners() {
ActivityPermissionListener feedbackViewPermissionListener = new ActivityPermissionListener(PepPermissionActivity.this);
String explanation = getResources().getString(R.string.download_permission_first_explanation);
storagePermissionListener = new CompositePermissionListener(feedbackViewPermissionListener,
SnackbarOnDeniedPermissionListener.Builder.with(getRootView(), explanation)
.withOpenSettingsButton(R.string.button_settings)
.build());
Dexter.withActivity(PepPermissionActivity.this)
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(storagePermissionListener)
.withErrorListener(new PermissionErrorListener())
.onSameThread()
.check();
}
public void createContactsPermissionListeners() {
PermissionListener feedbackViewPermissionListener = new ActivityPermissionListener(this);
String explanation = getResources().getString(R.string.read_permission_first_explanation);
contactPermissionListener = new CompositePermissionListener(feedbackViewPermissionListener,
SnackbarOnDeniedPermissionListener.Builder.with(getRootView(),
explanation)
.withOpenSettingsButton(R.string.button_settings)
.withCallback(new Snackbar.Callback() {
@Override public void onShown(Snackbar snackbar) {
super.onShown(snackbar);
}
@Override public void onDismissed(Snackbar snackbar, int event) {
super.onDismissed(snackbar, event);
}
})
.build());
Dexter.withActivity(PepPermissionActivity.this)
.withPermission(Manifest.permission.WRITE_CONTACTS)
.withListener(contactPermissionListener)
.withErrorListener(new PermissionErrorListener())
.onSameThread()
.check();
}
public void createBasicPermissionsActivity(PEpProvider.CompletedCallback completedCallback) {
Dexter.withActivity(this)
.withPermissions(
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS,
Manifest.permission.WRITE_EXTERNAL_STORAGE
).withListener(new MultiplePermissionsListener() {
@Override public void onPermissionsChecked(MultiplePermissionsReport report) {
completedCallback.onComplete();
}
@Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
completedCallback.onError(new Throwable(token.toString()));
}
}).check();
}
public abstract void inject();
public PEpComponent getpEpComponent() {
return pEpComponent;
}
public void askForBatteryOptimizationWhiteListing() {
K9 k9 = getK9();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& !k9.isBatteryOptimizationAsked()) {
Intent intent = new Intent();
String packageName = getPackageName();
PowerManager pm = (PowerManager) k9.getSystemService(Context.POWER_SERVICE);
if (pm != null && pm.isIgnoringBatteryOptimizations(packageName)) {
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
} else {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
}
startActivity(intent);
k9.batteryOptimizationAsked();
}
}
}
package com.fsck.k9.pEp.infrastructure.components;
import com.fsck.k9.activity.MessageCompose;
import com.fsck.k9.activity.MessageList;
import com.fsck.k9.activity.SettingsActivity;
import com.fsck.k9.activity.setup.AccountSetupBasics;
import com.fsck.k9.pEp.filepicker.SelectPathFragment;
import com.fsck.k9.pEp.infrastructure.PerActivity;
import com.fsck.k9.pEp.infrastructure.modules.ActivityModule;
import com.fsck.k9.pEp.infrastructure.modules.ApplicationModule;
import com.fsck.k9.pEp.infrastructure.modules.PEpModule;
import com.fsck.k9.pEp.manualsync.ImportWizardFrompEp;
import com.fsck.k9.pEp.ui.AboutActivity;
import com.fsck.k9.pEp.ui.activities.PermissionsActivity;
import com.fsck.k9.pEp.ui.blacklist.PepBlacklist;
import com.fsck.k9.pEp.ui.fragments.AccountSetupBasicsFragment;
import com.fsck.k9.pEp.ui.fragments.AccountSetupIncomingFragment;
import com.fsck.k9.pEp.ui.fragments.AccountSetupIncomingFragmentLegacy;
import com.fsck.k9.pEp.ui.fragments.AccountSetupOptionsFragment;
import com.fsck.k9.pEp.ui.fragments.AccountSetupOutgoingFragment;
import com.fsck.k9.pEp.ui.keys.keyimport.KeyImportActivity;
import com.fsck.k9.pEp.ui.keys.PepExtraKeys;
import com.fsck.k9.pEp.ui.keys.keyimport.KeyImportActivity;
import com.fsck.k9.pEp.ui.keysync.KeysyncManagement;
import com.fsck.k9.pEp.ui.keysync.PEpAddDevice;
import com.fsck.k9.pEp.ui.privacy.status.PEpStatus;
import com.fsck.k9.pEp.ui.privacy.status.PEpTrustwords;
import com.fsck.k9.ui.messageview.MessageViewFragment;
import dagger.Component;
import security.pEp.ui.permissions.PermissionsActivity;
@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = {
ActivityModule.class, PEpModule.class
}) public interface PEpComponent extends ActivityComponent {
})
public interface PEpComponent extends ActivityComponent {
void inject(PEpStatus activity);
......@@ -50,6 +53,8 @@ import dagger.Component;
void inject(AccountSetupIncomingFragment accountSetupIncomingFragment);
void inject(MessageViewFragment fragment);
void inject(AccountSetupIncomingFragmentLegacy accountSetupIncomingFragment);
void inject(AccountSetupOutgoingFragment accountSetupOutgoingFragment);
......@@ -65,4 +70,8 @@ import dagger.Component;
void inject(KeyImportActivity activity);
void inject(ImportWizardFrompEp activity);
void inject(MessageCompose messageCompose);
void inject(SettingsActivity activity);
}
\ No newline at end of file
......@@ -9,6 +9,8 @@ import javax.inject.Named;
import dagger.Module;
import dagger.Provides;
import security.pEp.permissions.PermissionRequester;
import security.pEp.ui.permissions.PepPermissionRequester;
@Module
public class ActivityModule {
......@@ -30,4 +32,9 @@ public class ActivityModule {
Context provideActivityContext() {
return this.activity;
}
@Provides
public PermissionRequester providepEpPermissionRequestProvider() {
return new PepPermissionRequester(activity);
}
}
......@@ -2,6 +2,7 @@ package com.fsck.k9.pEp.infrastructure.modules;
import android.content.Context;
import androidx.fragment.app.FragmentManager;
import androidx.loader.app.LoaderManager;
......@@ -19,6 +20,8 @@ import javax.inject.Named;
import dagger.Module;
import dagger.Provides;
import security.pEp.permissions.PermissionChecker;
import security.pEp.ui.permissions.PEpPermissionChecker;
@Module
public class PEpModule {
......@@ -38,13 +41,18 @@ public class PEpModule {
}
@Provides
public PEpSettingsChecker providePEpSettingsCheck() {
public PEpSettingsChecker providepEpSettingsCheck() {
return new PEpSettingsCheck(context.getApplicationContext());
}
@Provides
public PermissionChecker providepEpPermissionChecker() {
return new PEpPermissionChecker(context.getApplicationContext());
}
@Provides
@Named("MainUI")
public PEpProvider providepEpProvide() {
public PEpProvider providepEpProvider() {
return ((K9) context.getApplicationContext()).getpEpProvider();
}
......@@ -60,7 +68,7 @@ public class PEpModule {
}
@Provides
public ImportKeyController provideImportkeyController(@Named("Background") PEpProvider pEp) {
public ImportKeyController provideImportkeyController(@Named("Background") PEpProvider pEp) {
return ImportKeyControllerFactory.getInstance().getImportKeyController(context, pEp);
}
......
package com.fsck.k9.pEp.ui.fragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
......@@ -9,6 +10,7 @@ import com.fsck.k9.K9;
import com.fsck.k9.pEp.infrastructure.components.ApplicationComponent;
import com.fsck.k9.pEp.infrastructure.components.DaggerPEpComponent;
import com.fsck.k9.pEp.infrastructure.components.PEpComponent;
import com.fsck.k9.pEp.infrastructure.modules.ActivityModule;
import com.fsck.k9.pEp.infrastructure.modules.PEpModule;
public abstract class PEpFragment extends Fragment {
......@@ -37,6 +39,7 @@ public abstract class PEpFragment extends Fragment {
pEpComponent = DaggerPEpComponent.builder()
.applicationComponent(applicationComponent)
.pEpModule(new PEpModule(getActivity(), getLoaderManager(), getFragmentManager()))
.activityModule(new ActivityModule(getActivity()))
.build();
}
......
package com.fsck.k9.pEp.ui.listeners;
import com.fsck.k9.pEp.PepPermissionActivity;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;
public class ActivityPermissionListener implements PermissionListener {
private final PepPermissionActivity activity;
public ActivityPermissionListener(PepPermissionActivity activity) {
this.activity = activity;
}
@Override public void onPermissionGranted(PermissionGrantedResponse response) {
activity.showPermissionGranted(response.getPermissionName());
}
@Override public void onPermissionDenied(PermissionDeniedResponse response) {
activity.showPermissionDenied(response.getPermissionName(), response.isPermanentlyDenied());
}
@Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission,
PermissionToken token) {
}
}
package com.fsck.k9.pEp.ui.listeners;
import com.fsck.k9.ui.messageview.MessageViewFragment;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;
public class FragmentPermissionListener implements PermissionListener {
private final MessageViewFragment fragment;
public FragmentPermissionListener(MessageViewFragment fragment) {
this.fragment = fragment;
}
@Override public void onPermissionGranted(PermissionGrantedResponse response) {
fragment.showPermissionGranted(response.getPermissionName());
}
@Override public void onPermissionDenied(PermissionDeniedResponse response) {
fragment.showPermissionDenied(response.getPermissionName(), response.isPermanentlyDenied());
}
@Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission,
PermissionToken token) {
fragment.showPermissionRationale(token);
}
}
package com.fsck.k9.ui.messageview;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DownloadManager;
......@@ -12,10 +11,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
......@@ -24,6 +19,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
......@@ -52,15 +51,13 @@ import com.fsck.k9.mailstore.LocalFolder;
import com.fsck.k9.mailstore.LocalMessage;
import com.fsck.k9.mailstore.MessageViewInfo;
import com.fsck.k9.message.extractors.EncryptionVerifier;
import com.fsck.k9.pEp.PEpPermissionChecker;
import com.fsck.k9.pEp.PEpProvider;
import com.fsck.k9.pEp.PEpProviderFactory;
import com.fsck.k9.pEp.PEpUtils;
import com.fsck.k9.pEp.PePUIArtefactCache;
import com.fsck.k9.pEp.ui.PermissionErrorListener;
import com.fsck.k9.pEp.ui.fragments.PEpFragment;
import com.fsck.k9.pEp.ui.infrastructure.DrawerLocker;
import com.fsck.k9.pEp.ui.infrastructure.MessageAction;