slight cleanups to direct share implementation

This commit is contained in:
Vincent Breitmoser 2018-02-28 13:44:02 +01:00 committed by cketti
parent 2df5d679c3
commit 9273d253fa
4 changed files with 104 additions and 76 deletions

View file

@ -113,14 +113,14 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
private List<Recipient> cachedRecipients;
private ForceLoadContentObserver observerContact, observerKey;
private RecipientLoader(Context context, String cryptoProvider) {
private RecipientLoader(Context context) {
super(context);
this.query = null;
this.lookupKeyUri = null;
this.addresses = null;
this.contactUri = null;
this.cryptoProvider = cryptoProvider;
this.cryptoProvider = null;
this.contentResolver = context.getContentResolver();
}
@ -157,14 +157,11 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
contentResolver = context.getContentResolver();
}
public static RecipientLoader getMostContactedRecipientLoader(Context context, String cryptoProvider,
final int maxRecipients) {
return new RecipientLoader(context, cryptoProvider) {
public static RecipientLoader getMostContactedRecipientLoader(Context context, final int maxRecipients) {
return new RecipientLoader(context) {
@Override
public List<Recipient> loadInBackground() {
Map<String, Recipient> recipientMap = new HashMap<>();
List<Recipient> recipients = super.fillContactDataBySortOrder(recipientMap, maxRecipients);
return super.fillCryptoStatusData(recipients, recipientMap);
return super.fillContactDataBySortOrder(maxRecipients);
}
};
}
@ -357,7 +354,7 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
return hasContact;
}
private List<Recipient> fillContactDataBySortOrder(Map<String, Recipient> recipientMap, Integer maxRecipients) {
private List<Recipient> fillContactDataBySortOrder(int maxRecipients) {
List<Recipient> recipients = new ArrayList<>();
Uri queryUri = Email.CONTENT_URI;
@ -367,7 +364,7 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
return recipients;
}
fillContactDataFromCursor(cursor, recipients, recipientMap, null, maxRecipients);
fillContactDataFromCursor(cursor, recipients, new HashMap<String, Recipient>(), null, maxRecipients);
return recipients;
}

View file

@ -3,21 +3,21 @@ package com.fsck.k9.activity.misc;
import java.io.IOException;
import java.util.Locale;
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.widget.ImageView;
@ -34,8 +34,8 @@ import com.bumptech.glide.load.resource.bitmap.BitmapResource;
import com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.load.resource.file.FileToStreamDecoder;
import com.bumptech.glide.load.resource.transcode.BitmapBytesTranscoder;
import com.bumptech.glide.load.resource.transcode.BitmapToGlideDrawableTranscoder;
import com.bumptech.glide.request.FutureTarget;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.fsck.k9.helper.Contacts;
@ -60,7 +60,7 @@ public class ContactPictureLoader {
private static final String FALLBACK_CONTACT_LETTER = "?";
private Resources mResources;
private final Context context;
private Contacts mContactsHelper;
private int mPictureSizeInPx;
@ -106,11 +106,11 @@ public class ContactPictureLoader {
* use a dynamically calculated background color.
*/
public ContactPictureLoader(Context context, int defaultBackgroundColor) {
Context appContext = context.getApplicationContext();
mResources = appContext.getResources();
mContactsHelper = Contacts.getInstance(appContext);
this.context = context.getApplicationContext();
mContactsHelper = Contacts.getInstance(this.context);
float scale = mResources.getDisplayMetrics().density;
Resources resources = context.getResources();
float scale = resources.getDisplayMetrics().density;
mPictureSizeInPx = (int) (PICTURE_SIZE * scale);
mDefaultBackgroundColor = defaultBackgroundColor;
@ -176,39 +176,35 @@ public class ContactPictureLoader {
}
}
public Bitmap loadContactPictureIcon(Context context, Recipient recipient) {
return loadContactPicture(context, recipient.photoThumbnailUri, recipient.address);
public Bitmap loadContactPictureIcon(Recipient recipient) {
return loadContactPicture(recipient.photoThumbnailUri, recipient.address);
}
private Bitmap loadContactPicture(final Context context, Uri photoUri, final Address address) {
@WorkerThread
private Bitmap loadContactPicture(Uri photoUri, Address address) {
FutureTarget<Bitmap> bitmapTarget;
if (photoUri != null) {
try {
return Glide.with(context)
.load(photoUri)
.asBitmap()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.dontAnimate()
.into(mPictureSizeInPx, mPictureSizeInPx)
.get();
} catch (Exception e) {
}
}
try {
return Glide.with(context)
bitmapTarget = Glide.with(context)
.load(photoUri)
.asBitmap()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.dontAnimate()
.into(mPictureSizeInPx, mPictureSizeInPx);
} else {
bitmapTarget = Glide.with(context)
.using(new FallbackGlideModelLoader(), FallbackGlideParams.class)
.from(FallbackGlideParams.class)
.as(Bitmap.class)
.decoder(new FallbackGlideBitmapDecoder(context))
.encoder(new BitmapEncoder(Bitmap.CompressFormat.PNG, 0))
.encoder(new BitmapEncoder(CompressFormat.PNG, 0))
.cacheDecoder(new FileToStreamDecoder<>(new StreamBitmapDecoder(context)))
.diskCacheStrategy(DiskCacheStrategy.NONE)
.load(new FallbackGlideParams(address))
.dontAnimate()
.into(mPictureSizeInPx, mPictureSizeInPx).get();
} catch (Exception e) {
.into(mPictureSizeInPx, mPictureSizeInPx);
}
return null;
return loadIgnoringErors(bitmapTarget);
}
private int calcUnknownContactColor(Address address) {
@ -310,4 +306,14 @@ public class ContactPictureLoader {
}
}
@WorkerThread
@Nullable
private <T> T loadIgnoringErors(FutureTarget<T> target) {
try {
return target.get();
} catch (Exception e) {
return null;
}
}
}

View file

@ -1,8 +1,12 @@
package com.fsck.k9.service;
import java.util.ArrayList;
import java.util.List;
import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
@ -11,55 +15,78 @@ import android.os.Build;
import android.os.Bundle;
import android.service.chooser.ChooserTarget;
import android.service.chooser.ChooserTargetService;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.fsck.k9.activity.MessageCompose;
import com.fsck.k9.activity.compose.RecipientLoader;
import com.fsck.k9.activity.misc.ContactPictureLoader;
import com.fsck.k9.helper.ContactPicture;
import com.fsck.k9.view.RecipientSelectView;
import java.util.ArrayList;
import java.util.List;
import com.fsck.k9.view.RecipientSelectView.Recipient;
@TargetApi(Build.VERSION_CODES.M)
public class K9ChooserTargetService extends ChooserTargetService {
private static final int MAX_TARGETS = 5;
private final int MAX_TARGETS = 5;
private RecipientLoader recipientLoader;
private ContactPictureLoader contactPictureLoader;
@Override
public void onCreate() {
super.onCreate();
Context applicationContext = getApplicationContext();
recipientLoader = RecipientLoader.getMostContactedRecipientLoader(applicationContext, MAX_TARGETS);
contactPictureLoader = ContactPicture.getContactPictureLoader(applicationContext);
}
@Override
public List<ChooserTarget> onGetChooserTargets(ComponentName targetActivityName, IntentFilter matchedFilter) {
final List<ChooserTarget> targets = new ArrayList<>();
final ComponentName componentName = new ComponentName(this, MessageCompose.class);
List<Recipient> recipients = recipientLoader.loadInBackground();
String cryptoProvider = null;//TODO please check, cryptoProvider necessary?
RecipientLoader recipientLoader = RecipientLoader
.getMostContactedRecipientLoader(this.getApplicationContext(), cryptoProvider, MAX_TARGETS);
List<RecipientSelectView.Recipient> recipients = recipientLoader.loadInBackground();
return createChooserTargets(recipients);
}
// Ranking score for target between 0.0f and 1.0f
@NonNull
private List<ChooserTarget> createChooserTargets(List<Recipient> recipients) {
float score = 1.0f;
for (RecipientSelectView.Recipient recipient : recipients) {
List<ChooserTarget> targets = new ArrayList<>();
ComponentName componentName = new ComponentName(this, MessageCompose.class);
for (Recipient recipient : recipients) {
Bundle intentExtras = prepareIntentExtras(recipient);
Icon icon = loadRecipientIcon(recipient);
ChooserTarget chooserTarget =
new ChooserTarget(recipient.getDisplayNameOrAddress(), icon, score, componentName, intentExtras);
targets.add(chooserTarget);
final Bundle extras = new Bundle();
extras.putString("uuid", recipient.getDisplayNameOrAddress());
String address = recipient.address.getAddress();
extras.putStringArray(Intent.EXTRA_EMAIL,
new String[] { recipient.getDisplayNameOrAddress() + "<" + address + ">" });
Icon icon = null;
Bitmap bitmap = ContactPicture.getContactPictureLoader(getApplicationContext())
.loadContactPictureIcon(getApplicationContext(), recipient);
if (bitmap != null) {
icon = Icon.createWithBitmap(bitmap);
}
targets.add(new ChooserTarget(recipient.getDisplayNameOrAddress(), icon, score, componentName, extras));
score -= 0.1;
}
return targets;
}
@NonNull
private Bundle prepareIntentExtras(Recipient recipient) {
String address = recipient.address.getAddress();
String displayNameOrAddress = recipient.getDisplayNameOrAddress();
Bundle extras = new Bundle();
extras.putString("uuid", displayNameOrAddress);
extras.putStringArray(Intent.EXTRA_EMAIL, new String[] { displayNameOrAddress + "<" + address + ">" });
return extras;
}
@Nullable
private Icon loadRecipientIcon(Recipient recipient) {
Bitmap bitmap = contactPictureLoader.loadContactPictureIcon(recipient);
if (bitmap == null) {
return null;
}
return Icon.createWithBitmap(bitmap);
}
}

View file

@ -256,38 +256,36 @@ public class RecipientLoaderTest {
int maxTargets = 1;
setupContactProvider(CONTACT_1, CONTACT_2);
RecipientLoader recipientLoader = RecipientLoader.getMostContactedRecipientLoader(context, CRYPTO_PROVIDER,
maxTargets);
RecipientLoader recipientLoader = RecipientLoader.getMostContactedRecipientLoader(context, maxTargets);
List<Recipient> recipients = recipientLoader.loadInBackground();
assertEquals(maxTargets, recipients.size());
assertEquals("bob@host.com", recipients.get(0).address.getAddress());
assertEquals(RecipientCryptoStatus.UNAVAILABLE, recipients.get(0).getCryptoStatus());
assertEquals(RecipientCryptoStatus.UNDEFINED, recipients.get(0).getCryptoStatus());
}
@Test
public void getMostContactedFoundLess() throws Exception {
int maxTargets = 5;
setupContactProvider(CONTACT_1, CONTACT_2);
RecipientLoader recipientLoader = RecipientLoader.getMostContactedRecipientLoader(context, CRYPTO_PROVIDER,
maxTargets);
RecipientLoader recipientLoader = RecipientLoader.getMostContactedRecipientLoader(context, maxTargets);
List<Recipient> recipients = recipientLoader.loadInBackground();
assertEquals(2, recipients.size());
assertEquals("bob@host.com", recipients.get(0).address.getAddress());
assertEquals(RecipientCryptoStatus.UNAVAILABLE, recipients.get(0).getCryptoStatus());
assertEquals(RecipientCryptoStatus.UNDEFINED, recipients.get(0).getCryptoStatus());
assertEquals("bob2@host.com", recipients.get(1).address.getAddress());
assertEquals(RecipientCryptoStatus.UNAVAILABLE, recipients.get(1).getCryptoStatus());
assertEquals(RecipientCryptoStatus.UNDEFINED, recipients.get(1).getCryptoStatus());
}
@Test
public void getMostContactedFoundNothing() throws Exception {
int maxTargets = 5;
setupContactProvider();
RecipientLoader recipientLoader = RecipientLoader.getMostContactedRecipientLoader(context, CRYPTO_PROVIDER,
maxTargets);
RecipientLoader recipientLoader = RecipientLoader.getMostContactedRecipientLoader(context, maxTargets);
List<Recipient> recipients = recipientLoader.loadInBackground();
assertEquals(0, recipients.size());