Use a content provider to store the avatars
authorDa Risk <darisk972@gmail.com>
Sat, 19 Feb 2011 22:06:26 +0100
changeset 875 70ca3ab6e459
parent 874 4dd9fe4d0a3e
child 876 0173963643d1
Use a content provider to store the avatars
AndroidManifest.xml
src/com/beem/project/beem/providers/AvatarProvider.java
src/com/beem/project/beem/providers/package-info.java
src/com/beem/project/beem/service/BeemAvatarCache.java
src/com/beem/project/beem/service/XmppConnectionAdapter.java
--- a/AndroidManifest.xml	Tue Feb 08 22:11:58 2011 +0100
+++ b/AndroidManifest.xml	Sat Feb 19 22:06:26 2011 +0100
@@ -39,6 +39,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="BeemService" android:enabled="true"
 			android:label="Beem Service" android:permission="com.beem.project.beem.BEEM_SERVICE">
 			<intent-filter>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/providers/AvatarProvider.java	Sat Feb 19 22:06:26 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 Feb 19 22:06:26 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 Feb 19 22:06:26 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	Tue Feb 08 22:11:58 2011 +0100
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Sat Feb 19 22:06:26 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;
 
 /**
@@ -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);
     }