refactored avatar generation. first step

This commit is contained in:
iNPUTmice 2014-10-20 21:08:33 +02:00
parent 0bb2c3c4d5
commit 21961673cb
25 changed files with 405 additions and 368 deletions

View file

@ -14,14 +14,10 @@ import org.json.JSONObject;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.OtrEngine;
import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.XmppConnection;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.os.SystemClock;
public class Account extends AbstractEntity {
@ -345,20 +341,6 @@ public class Account extends AbstractEntity {
return false;
}
public Bitmap getImage(Context context, int size) {
if (this.avatar != null) {
Bitmap bm = FileBackend.getAvatar(this.avatar, size, context);
if (bm == null) {
return UIHelper.getContactPicture(getJid(), size, context,
false);
} else {
return bm;
}
} else {
return UIHelper.getContactPicture(getJid(), size, context, false);
}
}
public boolean setAvatar(String filename) {
if (this.avatar != null && this.avatar.equals(filename)) {
return false;

View file

@ -2,9 +2,6 @@ package eu.siacs.conversations.entities;
import java.util.Locale;
import android.content.Context;
import android.graphics.Bitmap;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xml.Element;
public class Bookmark extends Element implements ListItem {
@ -120,21 +117,14 @@ public class Bookmark extends Element implements ListItem {
return this.account;
}
@Override
public Bitmap getImage(int dpSize, Context context) {
if (this.mJoinedConversation == null) {
return UIHelper.getContactPicture(getDisplayName(), dpSize,
context, false);
} else {
return UIHelper.getContactPicture(this.mJoinedConversation, dpSize,
context, false);
}
}
public void setConversation(Conversation conversation) {
this.mJoinedConversation = conversation;
}
public Conversation getConversation() {
return this.mJoinedConversation;
}
public String getName() {
return this.getAttribute("name");
}

View file

@ -8,13 +8,9 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xml.Element;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
public class Contact implements ListItem {
public static final String TABLENAME = "contacts";
@ -330,20 +326,6 @@ public class Contact implements ListItem {
}
}
@Override
public Bitmap getImage(int size, Context context) {
if (this.avatar != null) {
Bitmap bm = FileBackend.getAvatar(avatar, size, context);
if (bm == null) {
return UIHelper.getContactPicture(this, size, context, false);
} else {
return bm;
}
} else {
return UIHelper.getContactPicture(this, size, context, false);
}
}
public boolean setAvatar(String filename) {
if (this.avatar != null && this.avatar.equals(filename)) {
return false;
@ -353,6 +335,10 @@ public class Contact implements ListItem {
}
}
public String getAvatar() {
return this.avatar;
}
public boolean deleteOtrFingerprint(String fingerprint) {
boolean success = false;
try {

View file

@ -8,7 +8,6 @@ import org.json.JSONException;
import org.json.JSONObject;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.UIHelper;
import net.java.otr4j.OtrException;
import net.java.otr4j.crypto.OtrCryptoEngineImpl;
@ -17,9 +16,7 @@ import net.java.otr4j.session.SessionID;
import net.java.otr4j.session.SessionImpl;
import net.java.otr4j.session.SessionStatus;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.os.SystemClock;
public class Conversation extends AbstractEntity {
@ -329,9 +326,8 @@ public class Conversation extends AbstractEntity {
public synchronized MucOptions getMucOptions() {
if (this.mucOptions == null) {
this.mucOptions = new MucOptions(this.getAccount());
this.mucOptions = new MucOptions(this);
}
this.mucOptions.setConversation(this);
return this.mucOptions;
}
@ -428,14 +424,6 @@ public class Conversation extends AbstractEntity {
return this.bookmark;
}
public Bitmap getImage(Context context, int size) {
if (mode == MODE_SINGLE) {
return getContact().getImage(size, context);
} else {
return UIHelper.getContactPicture(this, size, context, false);
}
}
public boolean hasDuplicateMessage(Message message) {
for (int i = this.getMessages().size() - 1; i >= 0; --i) {
if (this.messages.get(i).equals(message)) {

View file

@ -1,12 +1,7 @@
package eu.siacs.conversations.entities;
import android.content.Context;
import android.graphics.Bitmap;
public interface ListItem extends Comparable<ListItem> {
public String getDisplayName();
public String getJid();
public Bitmap getImage(int dpSize, Context context);
}

View file

@ -102,6 +102,10 @@ public class MucOptions {
public long getPgpKeyId() {
return this.pgpKeyId;
}
public Contact getContact() {
return account.getRoster().getContactFromRoster(getJid());
}
}
private Account account;
@ -116,8 +120,9 @@ public class MucOptions {
private String joinnick;
private String password = null;
public MucOptions(Account account) {
this.account = account;
public MucOptions(Conversation conversation) {
this.account = conversation.getAccount();
this.conversation = conversation;
}
public void deleteUser(String name) {
@ -253,10 +258,6 @@ public class MucOptions {
this.joinnick = nick;
}
public void setConversation(Conversation conversation) {
this.conversation = conversation;
}
public boolean online() {
return this.isOnline;
}
@ -361,4 +362,8 @@ public class MucOptions {
conversation
.setAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD, password);
}
public Conversation getConversation() {
return this.conversation;
}
}

View file

@ -15,6 +15,9 @@ public class Roster {
}
public Contact getContactFromRoster(String jid) {
if (jid == null) {
return null;
}
String cleanJid = jid.split("/", 2)[0];
Contact contact = contacts.get(cleanJid);
if (contact != null && contact.showInRoster()) {

View file

@ -92,16 +92,19 @@ public class HttpConnection implements Downloadable {
mXmppConnectionService.updateConversationUi();
}
private void setupTrustManager(HttpsURLConnection connection, boolean interactive) {
private void setupTrustManager(HttpsURLConnection connection,
boolean interactive) {
X509TrustManager trustManager;
if (interactive) {
trustManager = mXmppConnectionService.getMemorizingTrustManager();
} else {
trustManager = mXmppConnectionService.getMemorizingTrustManager().getNonInteractive();
trustManager = mXmppConnectionService.getMemorizingTrustManager()
.getNonInteractive();
}
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null,new X509TrustManager[] { trustManager },mXmppConnectionService.getRNG());
sc.init(null, new X509TrustManager[] { trustManager },
mXmppConnectionService.getRNG());
connection.setSSLSocketFactory(sc.getSocketFactory());
} catch (KeyManagementException e) {
return;
@ -139,7 +142,8 @@ public class HttpConnection implements Downloadable {
}
}
private long retrieveFileSize() throws IOException, SSLHandshakeException {
private long retrieveFileSize() throws IOException,
SSLHandshakeException {
HttpURLConnection connection = (HttpURLConnection) mUrl
.openConnection();
connection.setRequestMethod("HEAD");

View file

@ -152,13 +152,12 @@ public class DatabaseBackend extends SQLiteOpenHelper {
return list;
}
public ArrayList<Message> getMessages(
Conversation conversations, int limit) {
public ArrayList<Message> getMessages(Conversation conversations, int limit) {
return getMessages(conversations, limit, -1);
}
public ArrayList<Message> getMessages(Conversation conversation,
int limit, long timestamp) {
public ArrayList<Message> getMessages(Conversation conversation, int limit,
long timestamp) {
ArrayList<Message> list = new ArrayList<Message>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor;

View file

@ -35,7 +35,6 @@ import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.DownloadableFile;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.pep.Avatar;
public class FileBackend {
@ -69,8 +68,7 @@ public class FileBackend {
return getFile(message, true);
}
public DownloadableFile getFile(Message message,
boolean decrypted) {
public DownloadableFile getFile(Message message, boolean decrypted) {
StringBuilder filename = new StringBuilder();
filename.append(getConversationsDirectory());
filename.append(message.getUuid());
@ -88,7 +86,8 @@ public class FileBackend {
public static String getConversationsDirectory() {
return Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).getAbsolutePath()+"/Conversations/";
Environment.DIRECTORY_PICTURES).getAbsolutePath()
+ "/Conversations/";
}
public Bitmap resize(Bitmap originalBitmap, int size) {
@ -219,8 +218,7 @@ public class FileBackend {
}
public Bitmap getImageFromMessage(Message message) {
return BitmapFactory.decodeFile(getFile(message)
.getAbsolutePath());
return BitmapFactory.decodeFile(getFile(message).getAbsolutePath());
}
public Bitmap getThumbnail(Message message, int size, boolean cacheOnly)
@ -306,7 +304,7 @@ public class FileBackend {
}
public boolean isAvatarCached(Avatar avatar) {
File file = new File(getAvatarPath(context, avatar.getFilename()));
File file = new File(getAvatarPath(avatar.getFilename()));
return file.exists();
}
@ -314,7 +312,7 @@ public class FileBackend {
if (isAvatarCached(avatar)) {
return true;
}
String filename = getAvatarPath(context, avatar.getFilename());
String filename = getAvatarPath(avatar.getFilename());
File file = new File(filename + ".tmp");
file.getParentFile().mkdirs();
try {
@ -346,10 +344,14 @@ public class FileBackend {
}
}
public static String getAvatarPath(Context context, String avatar) {
public String getAvatarPath(String avatar) {
return context.getFilesDir().getAbsolutePath() + "/avatars/" + avatar;
}
public Uri getAvatarUri(String avatar) {
return Uri.parse("file:" + getAvatarPath(avatar));
}
public Bitmap cropCenterSquare(Uri image, int size) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
@ -371,7 +373,40 @@ public class FileBackend {
}
}
public static Bitmap cropCenterSquare(Bitmap input, int size) {
public Bitmap cropCenter(Uri image, int newHeight, int newWidth) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = calcSampleSize(image,
Math.max(newHeight, newWidth));
InputStream is = context.getContentResolver()
.openInputStream(image);
Bitmap source = BitmapFactory.decodeStream(is, null, options);
int sourceWidth = source.getWidth();
int sourceHeight = source.getHeight();
float xScale = (float) newWidth / sourceWidth;
float yScale = (float) newHeight / sourceHeight;
float scale = Math.max(xScale, yScale);
float scaledWidth = scale * sourceWidth;
float scaledHeight = scale * sourceHeight;
float left = (newWidth - scaledWidth) / 2;
float top = (newHeight - scaledHeight) / 2;
RectF targetRect = new RectF(left, top, left + scaledWidth, top
+ scaledHeight);
Bitmap dest = Bitmap.createBitmap(newWidth, newHeight,
source.getConfig());
Canvas canvas = new Canvas(dest);
canvas.drawBitmap(source, null, targetRect, null);
return dest;
} catch (FileNotFoundException e) {
return null;
}
}
public Bitmap cropCenterSquare(Bitmap input, int size) {
int w = input.getWidth();
int h = input.getHeight();
@ -440,13 +475,15 @@ public class FileBackend {
}
}
public static Bitmap getAvatar(String avatar, int size, Context context) {
Bitmap bm = BitmapFactory.decodeFile(FileBackend.getAvatarPath(context,
avatar));
public Bitmap getAvatar(String avatar, int size) {
if (avatar == null) {
return null;
}
Bitmap bm = cropCenter(getAvatarUri(avatar), size, size);
if (bm == null) {
return null;
}
return cropCenterSquare(bm, UIHelper.getRealPx(size, context));
return bm;
}
public boolean isFileAvailable(Message message) {

View file

@ -0,0 +1,194 @@
package eu.siacs.conversations.services;
import java.util.List;
import java.util.Locale;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Bookmark;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.ListItem;
import eu.siacs.conversations.entities.MucOptions;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.net.Uri;
public class AvatarService {
private static final int FG_COLOR = 0xFFFAFAFA;
private static final int TRANSPARENT = 0x00000000;
protected XmppConnectionService mXmppConnectionService = null;
public AvatarService(XmppConnectionService service) {
this.mXmppConnectionService = service;
}
public Bitmap getAvatar(Contact contact, int size) {
Bitmap avatar = mXmppConnectionService.getFileBackend().getAvatar(
contact.getAvatar(), size);
if (avatar == null) {
if (contact.getProfilePhoto() != null) {
avatar = mXmppConnectionService.getFileBackend()
.cropCenterSquare(Uri.parse(contact.getProfilePhoto()),
size);
if (avatar == null) {
avatar = getAvatar(contact.getDisplayName(), size);
}
} else {
avatar = getAvatar(contact.getDisplayName(), size);
}
}
return avatar;
}
public Bitmap getAvatar(ListItem item, int size) {
if (item instanceof Contact) {
return getAvatar((Contact) item, size);
} else if (item instanceof Bookmark) {
Bookmark bookmark = (Bookmark) item;
if (bookmark.getConversation() != null) {
return getAvatar(bookmark.getConversation(), size);
} else {
return getAvatar(bookmark.getDisplayName(), size);
}
} else {
return getAvatar(item.getDisplayName(), size);
}
}
public Bitmap getAvatar(Conversation conversation, int size) {
if (conversation.getMode() == Conversation.MODE_SINGLE) {
return getAvatar(conversation.getContact(), size);
} else {
return getAvatar(conversation.getMucOptions(), size);
}
}
public Bitmap getAvatar(MucOptions mucOptions, int size) {
List<MucOptions.User> users = mucOptions.getUsers();
int count = users.size();
Bitmap bitmap = Bitmap
.createBitmap(size, size, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
bitmap.eraseColor(TRANSPARENT);
if (count == 0) {
String name = mucOptions.getConversation().getName();
String letter = name.substring(0, 1);
int color = this.getColorForName(name);
drawTile(canvas, letter, color, 0, 0, size, size);
} else if (count == 1) {
drawTile(canvas, users.get(0), 0, 0, size, size);
} else if (count == 2) {
drawTile(canvas, users.get(0), 0, 0, size / 2 - 1, size);
drawTile(canvas, users.get(1), size / 2 + 1, 0, size, size);
} else if (count == 3) {
drawTile(canvas, users.get(0), 0, 0, size / 2 - 1, size);
drawTile(canvas, users.get(1), size / 2 + 1, 0, size, size / 2 - 1);
drawTile(canvas, users.get(2), size / 2 + 1, size / 2 + 1, size,
size);
} else if (count == 4) {
drawTile(canvas, users.get(0), 0, 0, size / 2 - 1, size / 2 - 1);
drawTile(canvas, users.get(1), 0, size / 2 + 1, size / 2 - 1, size);
drawTile(canvas, users.get(2), size / 2 + 1, 0, size, size / 2 - 1);
drawTile(canvas, users.get(3), size / 2 + 1, size / 2 + 1, size,
size);
} else {
drawTile(canvas, users.get(0), 0, 0, size / 2 - 1, size / 2 - 1);
drawTile(canvas, users.get(1), 0, size / 2 + 1, size / 2 - 1, size);
drawTile(canvas, users.get(2), size / 2 + 1, 0, size, size / 2 - 1);
drawTile(canvas, "\u2026", 0xFF202020, size / 2 + 1, size / 2 + 1,
size, size);
}
return bitmap;
}
public Bitmap getAvatar(Account account, int size) {
Bitmap avatar = mXmppConnectionService.getFileBackend().getAvatar(
account.getAvatar(), size);
if (avatar == null) {
avatar = getAvatar(account.getJid(), size);
}
return avatar;
}
public Bitmap getAvatar(String name, int size) {
Bitmap bitmap = Bitmap
.createBitmap(size, size, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
String letter = name.substring(0, 1);
int color = this.getColorForName(name);
drawTile(canvas, letter, color, 0, 0, size, size);
return bitmap;
}
private void drawTile(Canvas canvas, String letter, int tileColor,
int left, int top, int right, int bottom) {
letter = letter.toUpperCase(Locale.getDefault());
Paint tilePaint = new Paint(), textPaint = new Paint();
tilePaint.setColor(tileColor);
textPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(FG_COLOR);
textPaint.setTypeface(Typeface.create("sans-serif-light",
Typeface.NORMAL));
textPaint.setTextSize((float) ((right - left) * 0.8));
Rect rect = new Rect();
canvas.drawRect(new Rect(left, top, right, bottom), tilePaint);
textPaint.getTextBounds(letter, 0, 1, rect);
float width = textPaint.measureText(letter);
canvas.drawText(letter, (right + left) / 2 - width / 2, (top + bottom)
/ 2 + rect.height() / 2, textPaint);
}
private void drawTile(Canvas canvas, MucOptions.User user, int left,
int top, int right, int bottom) {
Contact contact = user.getContact();
if (contact != null) {
Uri uri = null;
if (contact.getAvatar() != null) {
uri = mXmppConnectionService.getFileBackend().getAvatarUri(
contact.getAvatar());
} else if (contact.getProfilePhoto() != null) {
uri = Uri.parse(contact.getProfilePhoto());
}
if (uri != null) {
Bitmap bitmap = mXmppConnectionService.getFileBackend()
.cropCenter(uri, bottom - top, right - left);
if (bitmap != null) {
drawTile(canvas, bitmap, left, top, right, bottom);
} else {
String letter = user.getName().substring(0, 1);
int color = this.getColorForName(user.getName());
drawTile(canvas, letter, color, left, top, right, bottom);
}
} else {
String letter = user.getName().substring(0, 1);
int color = this.getColorForName(user.getName());
drawTile(canvas, letter, color, left, top, right, bottom);
}
} else {
String letter = user.getName().substring(0, 1);
int color = this.getColorForName(user.getName());
drawTile(canvas, letter, color, left, top, right, bottom);
}
}
private void drawTile(Canvas canvas, Bitmap bm, int dstleft, int dsttop,
int dstright, int dstbottom) {
Rect dst = new Rect(dstleft, dsttop, dstright, dstbottom);
canvas.drawBitmap(bm, null, dst, null);
}
private int getColorForName(String name) {
int holoColors[] = { 0xFFe91e63, 0xFF9c27b0, 0xFF673ab7, 0xFF3f51b5,
0xFF5677fc, 0xFF03a9f4, 0xFF00bcd4, 0xFF009688, 0xFFff5722,
0xFF795548, 0xFF607d8b };
return holoColors[(int) ((name.hashCode() & 0xffffffffl) % holoColors.length)];
}
}

View file

@ -97,8 +97,8 @@ public class NotificationService {
if (messages.size() >= 1) {
Conversation conversation = messages.get(0)
.getConversation();
mBuilder.setLargeIcon(conversation.getImage(
mXmppConnectionService, 64));
// mBuilder.setLargeIcon(conversation.getImage(mXmppConnectionService,
// 64));
mBuilder.setContentTitle(conversation.getName());
StringBuilder text = new StringBuilder();
for (int i = 0; i < messages.size(); ++i) {

View file

@ -111,6 +111,7 @@ public class XmppConnectionService extends Service {
this);
private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager(
this);
private AvatarService mAvatarService = new AvatarService(this);
private OnConversationUpdate mOnConversationUpdate = null;
private Integer convChangedListenerCount = 0;
@ -145,7 +146,8 @@ public class XmppConnectionService extends Service {
}
};
private FileObserver fileObserver = new FileObserver(FileBackend.getConversationsDirectory()) {
private FileObserver fileObserver = new FileObserver(
FileBackend.getConversationsDirectory()) {
@Override
public void onEvent(int event, String path) {
@ -286,6 +288,10 @@ public class XmppConnectionService extends Service {
return this.fileBackend;
}
public AvatarService getAvatarService() {
return this.mAvatarService;
}
public Message attachImageToConversation(final Conversation conversation,
final Uri uri, final UiCallback<Message> callback) {
final Message message;
@ -820,8 +826,9 @@ public class XmppConnectionService extends Service {
}
private void checkDeletedFiles(Conversation conversation) {
for(Message message : conversation.getMessages()) {
if (message.getType() == Message.TYPE_IMAGE && message.getEncryption() != Message.ENCRYPTION_PGP) {
for (Message message : conversation.getMessages()) {
if (message.getType() == Message.TYPE_IMAGE
&& message.getEncryption() != Message.ENCRYPTION_PGP) {
if (!getFileBackend().isFileAvailable(message)) {
message.setDownloadable(new DeletedDownloadable());
}
@ -830,9 +837,11 @@ public class XmppConnectionService extends Service {
}
private void markFileDeleted(String uuid) {
for(Conversation conversation : getConversations()) {
for(Message message : conversation.getMessages()) {
if (message.getType() == Message.TYPE_IMAGE && message.getEncryption() != Message.ENCRYPTION_PGP && message.getUuid().equals(uuid)) {
for (Conversation conversation : getConversations()) {
for (Message message : conversation.getMessages()) {
if (message.getType() == Message.TYPE_IMAGE
&& message.getEncryption() != Message.ENCRYPTION_PGP
&& message.getUuid().equals(uuid)) {
if (!getFileBackend().isFileAvailable(message)) {
message.setDownloadable(new DeletedDownloadable());
updateConversationUi();
@ -1113,7 +1122,7 @@ public class XmppConnectionService extends Service {
}
}
}
Log.d(Config.LOGTAG,"app switched into foreground");
Log.d(Config.LOGTAG, "app switched into foreground");
}
private void switchToBackground() {
@ -1126,7 +1135,7 @@ public class XmppConnectionService extends Service {
}
}
this.mNotificationService.setIsInForeground(false);
Log.d(Config.LOGTAG,"app switched into background");
Log.d(Config.LOGTAG, "app switched into background");
}
private boolean isScreenOn() {
@ -1288,7 +1297,9 @@ public class XmppConnectionService extends Service {
leaveMuc(conversation);
} else {
if (conversation.endOtrIfNeeded()) {
Log.d(Config.LOGTAG,account.getJid()+": ended otr session with "+conversation.getContactJid());
Log.d(Config.LOGTAG, account.getJid()
+ ": ended otr session with "
+ conversation.getContactJid());
}
}
}

View file

@ -201,7 +201,8 @@ public class ConferenceDetailsActivity extends XmppActivity {
private void populateView() {
mAccountJid.setText(getString(R.string.using_account, conversation
.getAccount().getJid()));
mYourPhoto.setImageBitmap(conversation.getAccount().getImage(this, 48));
mYourPhoto.setImageBitmap(xmppConnectionService.getAvatarService()
.getAvatar(conversation.getAccount(), getPixel(48)));
setTitle(conversation.getName());
mFullJid.setText(conversation.getContactJid().split("/", 2)[0]);
mYourNick.setText(conversation.getMucOptions().getActualNick());
@ -248,21 +249,23 @@ public class ConferenceDetailsActivity extends XmppActivity {
}
Bitmap bm;
if (user.getJid() != null) {
Contact contact = account.getRoster().getContact(user.getJid());
if (contact.showInRoster()) {
bm = contact.getImage(48, this);
Contact contact = account.getRoster().getContactFromRoster(
user.getJid());
if (contact != null) {
bm = xmppConnectionService.getAvatarService().getAvatar(
contact, getPixel(48));
name.setText(contact.getDisplayName());
role.setText(user.getName() + " \u2022 "
+ getReadableRole(user.getRole()));
} else {
bm = UIHelper.getContactPicture(user.getName(), 48, this,
false);
bm = xmppConnectionService.getAvatarService().getAvatar(
user.getName(), getPixel(48));
name.setText(user.getName());
role.setText(getReadableRole(user.getRole()));
}
} else {
bm = UIHelper
.getContactPicture(user.getName(), 48, this, false);
bm = xmppConnectionService.getAvatarService().getAvatar(
user.getName(), getPixel(48));
name.setText(user.getName());
role.setText(getReadableRole(user.getRole()));
}

View file

@ -313,10 +313,7 @@ public class ContactDetailsActivity extends XmppActivity {
}
accountJidTv.setText(getString(R.string.using_account, contact
.getAccount().getJid()));
UIHelper.prepareContactBadge(this, badge, contact,
getApplicationContext());
prepareContactBadge(badge, contact);
if (contact.getSystemAccount() == null) {
badge.setOnClickListener(onBadgeClick);
}
@ -383,6 +380,16 @@ public class ContactDetailsActivity extends XmppActivity {
}
}
private void prepareContactBadge(QuickContactBadge badge, Contact contact) {
if (contact.getSystemAccount() != null) {
String[] systemAccount = contact.getSystemAccount().split("#");
long id = Long.parseLong(systemAccount[0]);
badge.assignContactUri(Contacts.getLookupUri(id, systemAccount[1]));
}
badge.setImageBitmap(xmppConnectionService.getAvatarService()
.getAvatar(contact, getPixel(72)));
}
protected void confirmToDeleteFingerprint(final String fingerprint) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.delete_fingerprint);

View file

@ -158,8 +158,8 @@ public class PublishProfilePictureActivity extends XmppActivity {
if (this.avatarUri == null) {
if (this.account.getAvatar() != null
|| this.defaultUri == null) {
this.avatar.setImageBitmap(this.account.getImage(
getApplicationContext(), 384));
// this.avatar.setImageBitmap(this.account.getImage(getApplicationContext(),
// 384));
if (this.defaultUri != null) {
this.avatar
.setOnLongClickListener(this.backToDefaultListener);

View file

@ -526,6 +526,11 @@ public abstract class XmppActivity extends Activity {
return this.mSecondaryBackgroundColor;
}
public int getPixel(int dp) {
DisplayMetrics metrics = getResources().getDisplayMetrics();
return ((int) (dp * metrics.density));
}
class BitmapWorkerTask extends AsyncTask<Message, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private Message message = null;

View file

@ -34,7 +34,8 @@ public class AccountAdapter extends ArrayAdapter<Account> {
jid.setText(account.getJid());
TextView statusView = (TextView) view.findViewById(R.id.account_status);
ImageView imageView = (ImageView) view.findViewById(R.id.account_image);
imageView.setImageBitmap(account.getImage(activity, 48));
imageView.setImageBitmap(activity.xmppConnectionService
.getAvatarService().getAvatar(account, activity.getPixel(48)));
switch (account.getStatus()) {
case Account.STATUS_DISABLED:
statusView.setText(getContext().getString(

View file

@ -127,7 +127,9 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
ImageView profilePicture = (ImageView) view
.findViewById(R.id.conversation_image);
profilePicture.setImageBitmap(conversation.getImage(activity, 56));
profilePicture.setImageBitmap(activity.xmppConnectionService
.getAvatarService().getAvatar(conversation,
activity.getPixel(56)));
return view;
}

View file

@ -4,6 +4,7 @@ import java.util.List;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.ListItem;
import eu.siacs.conversations.ui.XmppActivity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
@ -14,8 +15,11 @@ import android.widget.TextView;
public class ListItemAdapter extends ArrayAdapter<ListItem> {
public ListItemAdapter(Context context, List<ListItem> objects) {
super(context, 0, objects);
protected XmppActivity activity;
public ListItemAdapter(XmppActivity activity, List<ListItem> objects) {
super(activity, 0, objects);
this.activity = activity;
}
@Override
@ -32,7 +36,8 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
jid.setText(item.getJid());
name.setText(item.getDisplayName());
picture.setImageBitmap(item.getImage(48, getContext()));
picture.setImageBitmap(activity.xmppConnectionService
.getAvatarService().getAvatar(item, activity.getPixel(48)));
return view;
}

View file

@ -59,8 +59,10 @@ public class MessageAdapter extends ArrayAdapter<Message> {
if (this.accountBitmap == null) {
if (getCount() > 0) {
this.accountBitmap = getItem(0).getConversation().getAccount()
.getImage(getContext(), 48);
this.accountBitmap = activity.xmppConnectionService
.getAvatarService().getAvatar(
getItem(0).getConversation().getAccount(),
activity.getPixel(48));
}
}
return this.accountBitmap;
@ -494,9 +496,12 @@ public class MessageAdapter extends ArrayAdapter<Message> {
&& d.getStatus() == Downloadable.STATUS_DELETED) {
displayInfoMessage(viewHolder, R.string.image_file_deleted);
} else if (d != null && d.getStatus() == Downloadable.STATUS_OFFER) {
displayDownloadableMessage(viewHolder, item,R.string.download_image);
} else if (d != null && d.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) {
displayDownloadableMessage(viewHolder, item,R.string.check_image_filesize);
displayDownloadableMessage(viewHolder, item,
R.string.download_image);
} else if (d != null
&& d.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) {
displayDownloadableMessage(viewHolder, item,
R.string.check_image_filesize);
} else if ((item.getEncryption() == Message.ENCRYPTION_DECRYPTED)
|| (item.getEncryption() == Message.ENCRYPTION_NONE)
|| (item.getEncryption() == Message.ENCRYPTION_OTR)) {
@ -564,7 +569,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
public Bitmap get(Contact contact, Context context) {
if (!contactBitmaps.containsKey(contact.getJid())) {
contactBitmaps.put(contact.getJid(),
contact.getImage(48, context));
activity.xmppConnectionService.getAvatarService()
.getAvatar(contact, activity.getPixel(48)));
}
return contactBitmaps.get(contact.getJid());
}
@ -573,8 +579,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
if (unknownBitmaps.containsKey(name)) {
return unknownBitmaps.get(name);
} else {
Bitmap bm = UIHelper
.getContactPicture(name, 48, context, false);
Bitmap bm = activity.xmppConnectionService.getAvatarService()
.getAvatar(name, activity.getPixel(48));
unknownBitmaps.put(name, bm);
return bm;
}

View file

@ -22,7 +22,7 @@ public class PhoneHelper {
final String[] PROJECTION = new String[] { ContactsContract.Data._ID,
ContactsContract.Data.DISPLAY_NAME,
ContactsContract.Data.PHOTO_THUMBNAIL_URI,
ContactsContract.Data.PHOTO_URI,
ContactsContract.Data.LOOKUP_KEY,
ContactsContract.CommonDataKinds.Im.DATA };
@ -50,10 +50,8 @@ public class PhoneHelper {
"displayname",
cursor.getString(cursor
.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)));
contact.putString(
"photouri",
cursor.getString(cursor
.getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI)));
contact.putString("photouri", cursor.getString(cursor
.getColumnIndex(ContactsContract.Data.PHOTO_URI)));
contact.putString("lookup", cursor.getString(cursor
.getColumnIndex(ContactsContract.Data.LOOKUP_KEY)));

View file

@ -123,167 +123,6 @@ public class UIHelper {
}
}
public static int getRealPx(int dp, Context context) {
final DisplayMetrics metrics = context.getResources()
.getDisplayMetrics();
return ((int) (dp * metrics.density));
}
private static int getNameColor(String name) {
/*
* int holoColors[] = { 0xFF1da9da, 0xFFb368d9, 0xFF83b600, 0xFFffa713,
* 0xFFe92727 };
*/
int holoColors[] = { 0xFFe91e63, 0xFF9c27b0, 0xFF673ab7, 0xFF3f51b5,
0xFF5677fc, 0xFF03a9f4, 0xFF00bcd4, 0xFF009688, 0xFFff5722,
0xFF795548, 0xFF607d8b };
return holoColors[(int) ((name.hashCode() & 0xffffffffl) % holoColors.length)];
}
private static void drawTile(Canvas canvas, String letter, int tileColor,
int textColor, int left, int top, int right, int bottom) {
Paint tilePaint = new Paint(), textPaint = new Paint();
tilePaint.setColor(tileColor);
textPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(textColor);
textPaint.setTypeface(Typeface.create("sans-serif-light",
Typeface.NORMAL));
textPaint.setTextSize((float) ((right - left) * 0.8));
Rect rect = new Rect();
canvas.drawRect(new Rect(left, top, right, bottom), tilePaint);
textPaint.getTextBounds(letter, 0, 1, rect);
float width = textPaint.measureText(letter);
canvas.drawText(letter, (right + left) / 2 - width / 2, (top + bottom)
/ 2 + rect.height() / 2, textPaint);
}
private static Bitmap getUnknownContactPicture(String[] names, int size,
int bgColor, int fgColor) {
int tiles = (names.length > 4) ? 4 : (names.length < 1) ? 1
: names.length;
Bitmap bitmap = Bitmap
.createBitmap(size, size, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
String[] letters = new String[tiles];
int[] colors = new int[tiles];
if (names.length < 1) {
letters[0] = "?";
colors[0] = 0xFFe92727;
} else {
for (int i = 0; i < tiles; ++i) {
letters[i] = (names[i].length() > 0) ? names[i].substring(0, 1)
.toUpperCase(Locale.US) : " ";
colors[i] = getNameColor(names[i]);
}
if (names.length > 4) {
letters[3] = "\u2026"; // Unicode ellipsis
colors[3] = 0xFF202020;
}
}
bitmap.eraseColor(bgColor);
switch (tiles) {
case 1:
drawTile(canvas, letters[0], colors[0], fgColor, 0, 0, size, size);
break;
case 2:
drawTile(canvas, letters[0], colors[0], fgColor, 0, 0,
size / 2 - 1, size);
drawTile(canvas, letters[1], colors[1], fgColor, size / 2 + 1, 0,
size, size);
break;
case 3:
drawTile(canvas, letters[0], colors[0], fgColor, 0, 0,
size / 2 - 1, size);
drawTile(canvas, letters[1], colors[1], fgColor, size / 2 + 1, 0,
size, size / 2 - 1);
drawTile(canvas, letters[2], colors[2], fgColor, size / 2 + 1,
size / 2 + 1, size, size);
break;
case 4:
drawTile(canvas, letters[0], colors[0], fgColor, 0, 0,
size / 2 - 1, size / 2 - 1);
drawTile(canvas, letters[1], colors[1], fgColor, 0, size / 2 + 1,
size / 2 - 1, size);
drawTile(canvas, letters[2], colors[2], fgColor, size / 2 + 1, 0,
size, size / 2 - 1);
drawTile(canvas, letters[3], colors[3], fgColor, size / 2 + 1,
size / 2 + 1, size, size);
break;
}
return bitmap;
}
private static Bitmap getMucContactPicture(Conversation conversation,
int size, int bgColor, int fgColor) {
List<User> members = conversation.getMucOptions().getUsers();
if (members.size() == 0) {
return getUnknownContactPicture(
new String[] { conversation.getName() }, size, bgColor,
fgColor);
}
ArrayList<String> names = new ArrayList<String>();
names.add(conversation.getMucOptions().getActualNick());
for (User user : members) {
names.add(user.getName());
if (names.size() > 4) {
break;
}
}
String[] mArrayNames = new String[names.size()];
names.toArray(mArrayNames);
return getUnknownContactPicture(mArrayNames, size, bgColor, fgColor);
}
public static Bitmap getContactPicture(Conversation conversation,
int dpSize, Context context, boolean notification) {
if (conversation.getMode() == Conversation.MODE_SINGLE) {
return getContactPicture(conversation.getContact(), dpSize,
context, notification);
} else {
int fgColor = UIHelper.FG_COLOR, bgColor = (notification) ? UIHelper.BG_COLOR
: UIHelper.TRANSPARENT;
return getMucContactPicture(conversation,
getRealPx(dpSize, context), bgColor, fgColor);
}
}
public static Bitmap getContactPicture(Contact contact, int dpSize,
Context context, boolean notification) {
String uri = contact.getProfilePhoto();
if (uri == null) {
return getContactPicture(contact.getDisplayName(), dpSize, context,
notification);
}
try {
Bitmap bm = BitmapFactory.decodeStream(context.getContentResolver()
.openInputStream(Uri.parse(uri)));
return Bitmap.createScaledBitmap(bm, getRealPx(dpSize, context),
getRealPx(dpSize, context), false);
} catch (FileNotFoundException e) {
return getContactPicture(contact.getDisplayName(), dpSize, context,
notification);
}
}
public static Bitmap getContactPicture(String name, int dpSize,
Context context, boolean notification) {
int fgColor = UIHelper.FG_COLOR, bgColor = (notification) ? UIHelper.BG_COLOR
: UIHelper.TRANSPARENT;
return getUnknownContactPicture(new String[] { name },
getRealPx(dpSize, context), bgColor, fgColor);
}
public static void showErrorNotification(Context context,
List<Account> accounts) {
NotificationManager mNotificationManager = (NotificationManager) context
@ -326,16 +165,6 @@ public class UIHelper {
mNotificationManager.notify(1111, notification);
}
public static void prepareContactBadge(final Activity activity,
QuickContactBadge badge, final Contact contact, Context context) {
if (contact.getSystemAccount() != null) {
String[] systemAccount = contact.getSystemAccount().split("#");
long id = Long.parseLong(systemAccount[0]);
badge.assignContactUri(Contacts.getLookupUri(id, systemAccount[1]));
}
badge.setImageBitmap(contact.getImage(72, context));
}
@SuppressLint("InflateParams")
public static AlertDialog getVerifyFingerprintDialog(
final ConversationActivity activity,
@ -370,25 +199,6 @@ public class UIHelper {
return builder.create();
}
public static Bitmap getSelfContactPicture(Account account, int size,
boolean showPhoneSelfContactPicture, Context context) {
if (showPhoneSelfContactPicture) {
Uri selfiUri = PhoneHelper.getSefliUri(context);
if (selfiUri != null) {
try {
return BitmapFactory.decodeStream(context
.getContentResolver().openInputStream(selfiUri));
} catch (FileNotFoundException e) {
return getContactPicture(account.getJid(), size, context,
false);
}
}
return getContactPicture(account.getJid(), size, context, false);
} else {
return getContactPicture(account.getJid(), size, context, false);
}
}
private final static class EmoticonPattern {
Pattern pattern;
String replacement;

View file

@ -110,7 +110,7 @@ public class XmppConnection implements Runnable {
private OnBindListener bindListener = null;
private OnMessageAcknowledged acknowledgedListener = null;
private MemorizingTrustManager mMemorizingTrustManager;
private final Context applicationContext;
private final Context applicationContext;
public XmppConnection(Account account, XmppConnectionService service) {
this.mRandom = service.getRNG();
@ -119,7 +119,7 @@ public class XmppConnection implements Runnable {
this.wakeLock = service.getPowerManager().newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, account.getJid());
tagWriter = new TagWriter();
applicationContext = service.getApplicationContext();
applicationContext = service.getApplicationContext();
}
protected void changeStatus(int nextStatus) {
@ -172,13 +172,15 @@ public class XmppConnection implements Runnable {
} else {
boolean socketError = true;
int srvIndex = 0;
while (socketError && namePort.containsKey("name" + srvIndex)){
while (socketError
&& namePort.containsKey("name" + srvIndex)) {
try {
srvRecordServer = namePort.getString("name" + srvIndex);
srvRecordServer = namePort.getString("name"
+ srvIndex);
srvRecordPort = namePort.getInt("port" + srvIndex);
Log.d(Config.LOGTAG, account.getJid()
+ ": using values from dns " + srvRecordServer
+ ":" + srvRecordPort);
+ ": using values from dns "
+ srvRecordServer + ":" + srvRecordPort);
socket = new Socket(srvRecordServer, srvRecordPort);
socketError = false;
} catch (UnknownHostException e) {
@ -384,13 +386,13 @@ public class XmppConnection implements Runnable {
iq.addChild("ping", "urn:xmpp:ping");
this.sendIqPacket(iq, new OnIqPacketReceived() {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
Log.d(Config.LOGTAG, account.getJid()
+ ": online with resource " + account.getResource());
changeStatus(Account.STATUS_ONLINE);
}
});
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
Log.d(Config.LOGTAG, account.getJid()
+ ": online with resource " + account.getResource());
changeStatus(Account.STATUS_ONLINE);
}
});
}
private Element processPacket(Tag currentTag, int packetType)
@ -527,7 +529,8 @@ public class XmppConnection implements Runnable {
}
private SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(applicationContext);
return PreferenceManager
.getDefaultSharedPreferences(applicationContext);
}
private boolean enableLegacySSL() {
@ -551,14 +554,15 @@ public class XmppConnection implements Runnable {
true);
// Support all protocols except legacy SSL.
// The min SDK version prevents us having to worry about SSLv2. In future, this may be
// The min SDK version prevents us having to worry about SSLv2. In
// future, this may be
// true of SSLv3 as well.
final String[] supportProtocols;
if (enableLegacySSL()) {
supportProtocols = sslSocket.getSupportedProtocols();
} else {
final List<String> supportedProtocols = new LinkedList<String>(Arrays.asList(
sslSocket.getSupportedProtocols()));
final List<String> supportedProtocols = new LinkedList<String>(
Arrays.asList(sslSocket.getSupportedProtocols()));
supportedProtocols.remove("SSLv3");
supportProtocols = new String[supportedProtocols.size()];
supportedProtocols.toArray(supportProtocols);
@ -613,7 +617,8 @@ public class XmppConnection implements Runnable {
} else if (compressionAvailable()) {
sendCompressionZlib();
} else if (this.streamFeatures.hasChild("register")
&& account.isOptionSet(Account.OPTION_REGISTER) && usingEncryption) {
&& account.isOptionSet(Account.OPTION_REGISTER)
&& usingEncryption) {
sendRegistryRequest();
} else if (!this.streamFeatures.hasChild("register")
&& account.isOptionSet(Account.OPTION_REGISTER)) {
@ -637,7 +642,8 @@ public class XmppConnection implements Runnable {
} else if (this.streamFeatures.hasChild("bind") && shouldBind) {
sendBindRequest();
} else {
Log.d(Config.LOGTAG,account.getJid()+": incompatible server. disconnecting");
Log.d(Config.LOGTAG, account.getJid()
+ ": incompatible server. disconnecting");
disconnect(true);
}
}

View file

@ -358,8 +358,8 @@ public class JingleConnection implements Downloadable {
Content content = new Content(this.contentCreator, this.contentName);
if (message.getType() == Message.TYPE_IMAGE) {
content.setTransportId(this.transportId);
this.file = this.mXmppConnectionService.getFileBackend()
.getFile(message, false);
this.file = this.mXmppConnectionService.getFileBackend().getFile(
message, false);
if (message.getEncryption() == Message.ENCRYPTION_OTR) {
Conversation conversation = this.message.getConversation();
this.mXmppConnectionService.renewSymmetricKey(conversation);
@ -634,7 +634,7 @@ public class JingleConnection implements Downloadable {
}
private void sendFallbackToIbb() {
Log.d(Config.LOGTAG,"sending fallback to ibb");
Log.d(Config.LOGTAG, "sending fallback to ibb");
JinglePacket packet = this.bootstrapPacket("transport-replace");
Content content = new Content(this.contentCreator, this.contentName);
this.transportId = this.mJingleConnectionManager.nextRandomId();
@ -646,7 +646,7 @@ public class JingleConnection implements Downloadable {
}
private boolean receiveFallbackToIbb(JinglePacket packet) {
Log.d(Config.LOGTAG,"receiving fallack to ibb");
Log.d(Config.LOGTAG, "receiving fallack to ibb");
String receivedBlockSize = packet.getJingleContent().ibbTransport()
.getAttribute("block-size");
if (receivedBlockSize != null) {