Merge beem-account and Beem-avatar
author"Vincent Veronis"
Sat, 19 Mar 2011 19:31:31 +0100
changeset 871 be08c9157636
parent 863 85977e23817a (current diff)
parent 870 2236fe5b2db1 (diff)
child 872 11a7b9c1c500
Merge beem-account and Beem-avatar
AndroidManifest.xml
--- a/AndroidManifest.xml	Fri Feb 25 15:11:29 2011 +0100
+++ b/AndroidManifest.xml	Sat Mar 19 19:31:31 2011 +0100
@@ -76,6 +76,10 @@
 			android:name="android.intent.action.BOOT_COMPLETED" />
 			</intent-filter> </receiver>
 		-->
+	<provider android:name=".providers.AvatarProvider"
+		    android:authorities="com.beem.project.beem.providers.avatarprovider"
+		    android:exported="false" />
+
 		<service android:name=".account.AuthenticatorService"
 			android:exported="true" android:process=":auth">
 			<intent-filter>
@@ -106,4 +110,4 @@
 	<supports-screens android:largeScreens="true"
 		android:normalScreens="true" android:smallScreens="true"
 		android:anyDensity="true" />
-</manifest>
\ No newline at end of file
+</manifest>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/providers/AvatarProvider.java	Sat Mar 19 19:31:31 2011 +0100
@@ -0,0 +1,204 @@
+/*
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009 by Frederic-Charles Barthelery,
+                          Jean-Manuel Da Silva,
+                          Nikita Kozlov,
+                          Philippe Lago,
+                          Jean Baptiste Vergely,
+                          Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://dev.beem-project.com/
+
+    Epitech, hereby disclaims all copyright interest in the program "Beem"
+    written by Frederic-Charles Barthelery,
+               Jean-Manuel Da Silva,
+               Nikita Kozlov,
+               Philippe Lago,
+               Jean Baptiste Vergely,
+               Vincent Veronis.
+
+    Nicolas Sadirac, November 26, 2009
+    President of Epitech.
+
+    Flavien Astraud, November 26, 2009
+    Head of the EIP Laboratory.
+
+*/
+package com.beem.project.beem.providers;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/**
+ * A simple content provider we expose the differents avatar downloaded.
+ *
+ */
+public class AvatarProvider extends ContentProvider {
+
+    /** The content uri of this provider. */
+    public static final Uri CONTENT_URI =
+	Uri.parse("content://com.beem.project.beem.providers.avatarprovider");
+
+    private static final String TAG = AvatarProvider.class.getSimpleName();
+    private static final String AUTHORITY = "com.beem.project.beem.providers.avatarprovider";
+
+    /**
+     * The differents columns available in the AvatarProvider.
+     */
+    public static interface Columns {
+
+	/** The id of the avatar. */
+	String ID = "_id";
+    }
+
+    private static String[] columnNames = new String[] {Columns.ID };
+
+    private static final int AVATAR = 1;
+    private static final int AVATAR_ID = 2;
+    private static final UriMatcher URIMATCHER = new UriMatcher(AVATAR);
+
+    static
+    {
+        URIMATCHER.addURI(AUTHORITY, "*", AVATAR_ID);
+	// should not be needed if we pass AVATAR on the constructor but it does not work
+        URIMATCHER.addURI(AUTHORITY, null, AVATAR);
+    }
+
+    private String mDataPath;
+
+    /**
+     * Create an AvatarProvider.
+     */
+    public AvatarProvider() {
+    }
+
+    /**
+     * Translate the mode passed to {@link #openFile} into mode passed to {@link ParcelFileDescriptor#open}.
+     *
+     * @param uri the uri to open
+     * @param mode the mode
+     * @return the mode
+     * @throws FileNotFoundException if the mode passed is illegal
+     */
+    public static int modeToMode(Uri uri, String mode) throws FileNotFoundException {
+	int modeBits;
+	if ("r".equals(mode)) {
+	    modeBits = ParcelFileDescriptor.MODE_READ_ONLY;
+	} else if ("w".equals(mode) || "wt".equals(mode)) {
+	    modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY
+		| ParcelFileDescriptor.MODE_CREATE
+		| ParcelFileDescriptor.MODE_TRUNCATE;
+	} else if ("wa".equals(mode)) {
+	    modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY
+		| ParcelFileDescriptor.MODE_CREATE
+		| ParcelFileDescriptor.MODE_APPEND;
+	} else if ("rw".equals(mode)) {
+	    modeBits = ParcelFileDescriptor.MODE_READ_WRITE
+		| ParcelFileDescriptor.MODE_CREATE;
+	} else if ("rwt".equals(mode)) {
+	    modeBits = ParcelFileDescriptor.MODE_READ_WRITE
+		| ParcelFileDescriptor.MODE_CREATE
+		| ParcelFileDescriptor.MODE_TRUNCATE;
+	} else {
+	    throw new FileNotFoundException("Bad mode for " + uri + ": "
+		    + mode);
+	}
+	return modeBits;
+    }
+
+    @Override
+    public boolean onCreate() {
+	File cacheDir = Environment.getExternalStorageDirectory();
+	File dataPath = new File(cacheDir, "/Android/data/com.beem.project.beem/cache/avatar");
+	dataPath.mkdirs();
+	mDataPath = dataPath.getAbsolutePath();
+	return true;
+    }
+
+    @Override
+    public ParcelFileDescriptor openFile(Uri uri, String mode)
+	throws FileNotFoundException {
+	String id = uri.getPath();
+	File data = new File(mDataPath, id);
+	int modeBits = AvatarProvider.modeToMode(uri, mode);
+	return ParcelFileDescriptor.open(data, modeBits);
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
+	MatrixCursor c = new MatrixCursor(columnNames);
+	int match = URIMATCHER.match(uri);
+	switch (match) {
+	    case AVATAR:
+		File[] files = new File(mDataPath).listFiles();
+		if (files != null) {
+		    for (File f : files) {
+			c.newRow().add(f.getName());
+		    }
+		}
+		break;
+	    case AVATAR_ID:
+		String id = uri.getPathSegments().get(0);
+		File f = new File(mDataPath, id);
+		if (f.exists())
+			c.newRow().add(f.getName());
+		break;
+	    default:
+		Log.w(TAG, "Unsupported uri for query match = " + match);
+	}
+	return c;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+	return 0;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+	int res = 0;
+	String id = uri.getPath();
+	File data = new File(mDataPath, id);
+	if (data.exists() && data.delete()) {
+	    res++;
+	}
+	return res;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+	return null;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+	return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/providers/package-info.java	Sat Mar 19 19:31:31 2011 +0100
@@ -0,0 +1,49 @@
+/*
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009 by Frederic-Charles Barthelery,
+                          Jean-Manuel Da Silva,
+                          Nikita Kozlov,
+                          Philippe Lago,
+                          Jean Baptiste Vergely,
+                          Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://dev.beem-project.com/
+
+    Epitech, hereby disclaims all copyright interest in the program "Beem"
+    written by Frederic-Charles Barthelery,
+               Jean-Manuel Da Silva,
+               Nikita Kozlov,
+               Philippe Lago,
+               Jean Baptiste Vergely,
+               Vincent Veronis.
+
+    Nicolas Sadirac, November 26, 2009
+    President of Epitech.
+
+    Flavien Astraud, November 26, 2009
+    Head of the EIP Laboratory.
+
+*/
+
+
+/**
+ * ContentProviders for Beem.
+ */
+package com.beem.project.beem.providers;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/service/BeemAvatarCache.java	Sat Mar 19 19:31:31 2011 +0100
@@ -0,0 +1,134 @@
+/*
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009 by Frederic-Charles Barthelery,
+                          Jean-Manuel Da Silva,
+                          Nikita Kozlov,
+                          Philippe Lago,
+                          Jean Baptiste Vergely,
+                          Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://dev.beem-project.com/
+
+    Epitech, hereby disclaims all copyright interest in the program "Beem"
+    written by Frederic-Charles Barthelery,
+               Jean-Manuel Da Silva,
+               Nikita Kozlov,
+               Philippe Lago,
+               Jean Baptiste Vergely,
+               Vincent Veronis.
+
+    Nicolas Sadirac, November 26, 2009
+    President of Epitech.
+
+    Flavien Astraud, November 26, 2009
+    Head of the EIP Laboratory.
+
+*/
+package com.beem.project.beem.service;
+
+import android.content.ContentResolver;
+import android.content.Context;
+
+import android.database.Cursor;
+
+import android.net.Uri;
+
+import com.beem.project.beem.providers.AvatarProvider;
+import com.beem.project.beem.smack.avatar.AvatarCache;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * An implementation of an AvatarCache which store the data of the filesystem.
+ */
+public class BeemAvatarCache implements AvatarCache {
+
+    private static final String TAG = BeemAvatarCache.class.getSimpleName();
+
+    private Context mContext;
+    private ContentResolver mContentResolver;
+
+    /**
+     * Create a BeemAvatarCache.
+     *
+     * @param ctx The android context of the cache.
+     */
+    public BeemAvatarCache(final Context ctx) {
+	mContext = ctx;
+	mContentResolver = mContext.getContentResolver();
+    }
+
+
+    @Override
+    public void put(String key, byte[] data) throws IOException {
+	Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(key).build();
+	OutputStream os = new BufferedOutputStream(mContentResolver.openOutputStream(uri));
+	try {
+	    os.write(data);
+	} finally {
+	    os.close();
+	}
+    }
+
+    @Override
+    public void put(String key, InputStream in) throws IOException {
+	Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(key).build();
+	OutputStream os = new BufferedOutputStream(mContentResolver.openOutputStream(uri));
+	try {
+	    byte[] data = new byte[1024];
+	    int nbread;
+	    while ((nbread = in.read(data)) != -1)
+		    os.write(data, 0, nbread);
+	} finally {
+	    in.close();
+	    os.close();
+	}
+    }
+
+    @Override
+    public byte[] get(String key) throws IOException {
+	Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(key).build();
+	InputStream is = new BufferedInputStream(mContentResolver.openInputStream(uri));
+	ByteArrayOutputStream bos = new ByteArrayOutputStream();
+	try {
+	    byte[] data = new byte[1024];
+	    is.read(data);
+	    bos.write(data);
+	} finally {
+	    is.close();
+	}
+	return bos.toByteArray();
+    }
+
+    @Override
+    public boolean contains(String key) {
+	Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(key).build();
+	uri = Uri.parse("content://com.beem.project.beem.providers.avatarprovider");
+	Cursor c = mContentResolver.query(uri, null, null, null, null);
+	boolean res = c.getCount() > 0;
+	c.close();
+	return res;
+    }
+}
--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Fri Feb 25 15:11:29 2011 +0100
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Sat Mar 19 19:31:31 2011 +0100
@@ -64,11 +64,9 @@
 import android.content.SharedPreferences;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
-import android.os.Environment;
 import android.util.Log;
 
 import java.util.Iterator;
-import java.io.File;
 
 import com.beem.project.beem.BeemService;
 import com.beem.project.beem.R;
@@ -83,7 +81,6 @@
 import com.beem.project.beem.utils.Status;
 import com.beem.project.beem.smack.pep.PepSubManager;
 import com.beem.project.beem.smack.avatar.AvatarCache;
-import com.beem.project.beem.smack.avatar.FileAvatarCache;
 import com.beem.project.beem.smack.avatar.AvatarManager;
 
 /**
@@ -483,7 +480,7 @@
 	try {
 	    // jid et server
 	    ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(mAdaptee);
-	    DiscoverInfo info = sdm.discoverInfo("elyzion.net");
+	    DiscoverInfo info = sdm.discoverInfo(mAdaptee.getServiceName());
 	    Iterator<DiscoverInfo.Identity> it = info.getIdentities();
 	    while (it.hasNext()) {
 		DiscoverInfo.Identity identity = it.next();
@@ -504,9 +501,7 @@
 	// API 8
 	// mService.getExternalCacheDir()
 	mPepManager = new PepSubManager(mAdaptee);
-	File cacheDir = Environment.getExternalStorageDirectory();
-	cacheDir = new File(cacheDir, "/Android/data/com.beem.project.beem/cache/");
-	AvatarCache avatarCache = new FileAvatarCache(cacheDir);
+	AvatarCache avatarCache = new BeemAvatarCache(mService);
 	mAvatarManager = new AvatarManager(mAdaptee, mPepManager, avatarCache, true);
     }
 
--- a/src/com/beem/project/beem/smack/avatar/AvatarMetadataProvider.java	Fri Feb 25 15:11:29 2011 +0100
+++ b/src/com/beem/project/beem/smack/avatar/AvatarMetadataProvider.java	Sat Mar 19 19:31:31 2011 +0100
@@ -70,16 +70,34 @@
 	    int eventType = parser.next();
 	    if (eventType == XmlPullParser.START_TAG) {
 		if ("info".equals(parser.getName())) {
-		    int bytes = Integer.parseInt(parser.getAttributeValue(null, "bytes"));
-		    int height = Integer.parseInt(parser.getAttributeValue(null, "height"));
-		    int width = Integer.parseInt(parser.getAttributeValue(null, "width"));
 		    String id = parser.getAttributeValue(null, "id");
 		    String type = parser.getAttributeValue(null, "type");
+		    String sbytes = parser.getAttributeValue(null, "bytes");
+		    String sheight = parser.getAttributeValue(null, "height");
+		    String swidth = parser.getAttributeValue(null, "width");
+		    int bytes = 0;
+		    AvatarMetadataExtension.Info info = null;
+		    try {
+			if (sbytes != null)
+			    bytes = Integer.parseInt(sbytes);
+		    } catch (NumberFormatException e) { }
+		    if (bytes != 0 && id != null && type != null)
+			info = new AvatarMetadataExtension.Info(id, type, bytes);
+		    else // invalid info
+			continue;
+
 		    String url = parser.getAttributeValue(null, "url");
-		    AvatarMetadataExtension.Info info = new AvatarMetadataExtension.Info(id, type, bytes);
-		    info.setHeight(height);
-		    info.setWidth(width);
 		    info.setUrl(url);
+		    try {
+			int height = 0;
+			int width = 0;
+			if (sheight != null)
+			    height = Integer.parseInt(parser.getAttributeValue(null, "height"));
+			if (swidth != null)
+			    width = Integer.parseInt(parser.getAttributeValue(null, "width"));
+			info.setHeight(height);
+			info.setWidth(width);
+		    } catch (NumberFormatException e) { }
 		    metadata.addInfo(info);
 		}
 	    } else if (eventType == XmlPullParser.END_TAG) {
--- a/src/com/beem/project/beem/smack/caps/CapsManager.java	Fri Feb 25 15:11:29 2011 +0100
+++ b/src/com/beem/project/beem/smack/caps/CapsManager.java	Sat Mar 19 19:31:31 2011 +0100
@@ -178,7 +178,7 @@
 		PacketExtension p = packet.getExtension("c", "http://jabber.org/protocol/caps");
 		CapsExtension caps = (CapsExtension) p;
 		if (!isInCache(caps.getVer())) {
-		    validate(packet.getFrom(), caps.getVer(), caps.getHash());
+		    validate(packet.getFrom(), caps.getNode(), caps.getVer(), caps.getHash());
 		}
 	    }
 	}, filter);
@@ -204,13 +204,14 @@
      * Validate the ver attribute of a received capability.
      *
      * @param jid the jid of the sender of the capability.
+     * @param node the node attribute of the capability.
      * @param ver the ver attribute of the capability.
      * @param hashMethod the hash algorithm to use to calculate ver
      * @return true if the ver attribute is valid false otherwise.
      */
-    private boolean validate(String jid, String ver, String hashMethod) {
+    private boolean validate(String jid, String node, String ver, String hashMethod) {
 	try {
-	    DiscoverInfo info = mSdm.discoverInfo(jid);
+	    DiscoverInfo info = mSdm.discoverInfo(jid, node + "#" + ver);
 	    if (!mSupportedAlgorithm.contains(hashMethod)) {
 		mJidCache.put(jid, info);
 		return false;
--- a/src/com/beem/project/beem/ui/Chat.java	Fri Feb 25 15:11:29 2011 +0100
+++ b/src/com/beem/project/beem/ui/Chat.java	Sat Mar 19 19:31:31 2011 +0100
@@ -49,6 +49,8 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.io.InputStream;
+import java.io.IOException;
 
 import org.jivesoftware.smack.packet.Presence.Mode;
 import org.jivesoftware.smack.util.StringUtils;
@@ -65,6 +67,7 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Color;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -88,9 +91,9 @@
 import android.widget.ListView;
 import android.widget.TextView;
 
-import java.io.ByteArrayInputStream;
 
 import com.beem.project.beem.R;
+import com.beem.project.beem.providers.AvatarProvider;
 import com.beem.project.beem.service.Contact;
 import com.beem.project.beem.service.Message;
 import com.beem.project.beem.service.PresenceAdapter;
@@ -143,6 +146,7 @@
     private final BeemBroadcastReceiver mBroadcastReceiver = new BeemBroadcastReceiver();
     private final BeemRosterListener mBeemRosterListener = new BeemRosterListener();
     private IXmppFacade mXmppFacade;
+    private String mCurrentAvatarId;
     private boolean mBinded;
     private boolean mCompact;
 
@@ -576,7 +580,11 @@
 	    }
 	} else {
 	    Mode m = Status.getPresenceModeFromStatus(mContact.getStatus());
-	    setTitle(getString(R.string.chat_name) + " " + mContact.getName() + " (" + m.name() + ")");
+	    if (m == null)
+		setTitle(getString(R.string.chat_name) + " " + name
+		    + " (" + getString(R.string.contact_status_msg_offline) + ")");
+	    else
+		setTitle(getString(R.string.chat_name) + " " + name + " (" + m.name() + ")");
 	}
     }
 
@@ -588,8 +596,15 @@
     private void updateContactStatusIcon() {
 	if (mCompact)
 	    return;
-	Drawable avatar = getAvatarDrawable(mContact.getAvatarId());
-	mAvatarStatusDrawable.setDrawableByLayerId(R.id.avatar, avatar);
+	String id = mContact.getAvatarId();
+	if (id == null)
+	    id = "";
+	Log.d(TAG, "update contact icon  : " + id);
+	if (!id.equals(mCurrentAvatarId)) {
+	    Drawable avatar = getAvatarDrawable(mContact.getAvatarId());
+	    mAvatarStatusDrawable.setDrawableByLayerId(R.id.avatar, avatar);
+	    mCurrentAvatarId = id;
+	}
 	mContactStatusIcon.setImageLevel(mContact.getStatus());
     }
 
@@ -601,19 +616,25 @@
      */
     private Drawable getAvatarDrawable(String avatarId) {
 	Drawable avatarDrawable = null;
-	try {
-	    byte[] avatar = mXmppFacade.getAvatar(avatarId);
-	    if (avatar != null) {
-		ByteArrayInputStream in = new ByteArrayInputStream(avatar);
-		avatarDrawable = Drawable.createFromStream(in, avatarId);
+	if (avatarId != null) {
+	    Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(avatarId).build();
+	    InputStream in = null;
+	    try {
+		try {
+		    in = getContentResolver().openInputStream(uri);
+	    avatarDrawable = Drawable.createFromStream(in, avatarId);
+		} finally {
+		    if (in != null)
+			in.close();
+		}
+	    } catch (IOException e) {
+		Log.w(TAG, "Error while setting the avatar", e);
 	    }
-	} catch (RemoteException e) {
-	    Log.e(TAG, "Error while setting the avatar", e);
 	}
 	if (avatarDrawable == null)
 	    avatarDrawable = getResources().getDrawable(R.drawable.beem_launcher_icon_silver);
 	return avatarDrawable;
-     }
+    }
 
     /**
      * Prepare the status icons map.
--- a/src/com/beem/project/beem/ui/ContactList.java	Fri Feb 25 15:11:29 2011 +0100
+++ b/src/com/beem/project/beem/ui/ContactList.java	Sat Mar 19 19:31:31 2011 +0100
@@ -49,7 +49,8 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.IOException;
 
 import org.jivesoftware.smack.util.StringUtils;
 
@@ -60,6 +61,7 @@
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -89,6 +91,7 @@
 import android.graphics.drawable.LayerDrawable;
 
 import com.beem.project.beem.R;
+import com.beem.project.beem.providers.AvatarProvider;
 import com.beem.project.beem.service.Contact;
 import com.beem.project.beem.service.PresenceAdapter;
 import com.beem.project.beem.service.aidl.IBeemRosterListener;
@@ -676,16 +679,20 @@
 	 */
 	private Drawable getAvatarStatusDrawable(String avatarId) {
 	    Drawable avatarDrawable = null;
-	    try {
-		if (mXmppFacade != null) {
-		    byte[] avatar = mXmppFacade.getAvatar(avatarId);
-		    if (avatar != null) {
-			ByteArrayInputStream in = new ByteArrayInputStream(avatar);
+	    if (avatarId != null) {
+		Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(avatarId).build();
+		InputStream in = null;
+		try {
+		    try {
+			in = getContentResolver().openInputStream(uri);
 			avatarDrawable = Drawable.createFromStream(in, avatarId);
+		    } finally {
+			if (in != null)
+			    in.close();
 		    }
+		} catch (IOException e) {
+		    Log.w(TAG, "Error while setting the avatar", e);
 		}
-	    } catch (RemoteException e) {
-		Log.e(TAG, "Error while setting the avatar", e);
 	    }
 	    if (avatarDrawable == null)
 		avatarDrawable = getResources().getDrawable(R.drawable.beem_launcher_icon_silver);