merge
authorDa Risk <darisk972@gmail.com>
Thu, 19 Nov 2009 01:56:33 +0100
changeset 532 58a827799e79
parent 531 e344b51f93ff (current diff)
parent 529 7964f04c2bf7 (diff)
child 533 f9e19652887e
merge
src/com/beem/project/beem/service/XmppConnectionAdapter.java
--- a/res/values-fr/arrays.xml	Thu Nov 19 01:48:54 2009 +0100
+++ b/res/values-fr/arrays.xml	Thu Nov 19 01:56:33 2009 +0100
@@ -13,4 +13,9 @@
 		<item name="Unavailable">Indisponible</item>
 		<item name="Disconnected">Déconnecté(e)</item>
 	</string-array>
+	<string-array name="privacy_list_select_dialog">
+		<item name="@string/privacy_list_select_dialog_buddies">Contacts</item>
+		<item name="@string/privacy_list_select_dialog_groups">Groupes</item>
+		<item name="@string/privacy_list_select_dialog_delete">Supprimer</item>
+	</string-array>
 </resources>
--- a/res/values/arrays.xml	Thu Nov 19 01:48:54 2009 +0100
+++ b/res/values/arrays.xml	Thu Nov 19 01:56:33 2009 +0100
@@ -13,4 +13,9 @@
 		<item name="Unavailable">Unavailable</item>
 		<item name="Disconnected">Disconnected</item>
 	</string-array>
+	<string-array name="privacy_list_select_dialog">
+		<item name="@string/privacy_list_select_dialog_buddies">Buddies</item>
+		<item name="@string/privacy_list_select_dialog_groups">Groups</item>
+		<item name="@string/privacy_list_select_dialog_delete">Delete</item>
+	</string-array>
 </resources>
--- a/res/values/strings.xml	Thu Nov 19 01:48:54 2009 +0100
+++ b/res/values/strings.xml	Thu Nov 19 01:56:33 2009 +0100
@@ -280,6 +280,9 @@
 	<string name="privacy_list_create_dialog_title">Create a privacy list</string>
 	<string name="privacy_list_create_dialog_list_name_label">Title</string>
 	<string name="privacy_list_create_dialog_create_button">Create</string>
+	<string name="privacy_list_select_dialog_buddies">Buddies</string>
+	<string name="privacy_list_select_dialog_groups">Groups</string>
+	<string name="privacy_list_select_dialog_delete">Delete</string>
 
 	<string name="UpdateButton">Update</string>
 </resources>
--- a/src/com/beem/project/beem/BeemService.java	Thu Nov 19 01:48:54 2009 +0100
+++ b/src/com/beem/project/beem/BeemService.java	Thu Nov 19 01:56:33 2009 +0100
@@ -5,9 +5,35 @@
 import org.jivesoftware.smack.XMPPConnection;
 import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
 import org.jivesoftware.smack.Roster.SubscriptionMode;
+import org.jivesoftware.smack.provider.PrivacyProvider;
+import org.jivesoftware.smack.provider.ProviderManager;
 import org.jivesoftware.smack.proxy.ProxyInfo;
 import org.jivesoftware.smack.proxy.ProxyInfo.ProxyType;
 import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smackx.GroupChatInvitation;
+import org.jivesoftware.smackx.PrivateDataManager;
+import org.jivesoftware.smackx.packet.ChatStateExtension;
+import org.jivesoftware.smackx.packet.LastActivity;
+import org.jivesoftware.smackx.packet.OfflineMessageInfo;
+import org.jivesoftware.smackx.packet.OfflineMessageRequest;
+import org.jivesoftware.smackx.packet.SharedGroupsInfo;
+import org.jivesoftware.smackx.provider.AdHocCommandDataProvider;
+import org.jivesoftware.smackx.provider.BytestreamsProvider;
+import org.jivesoftware.smackx.provider.DataFormProvider;
+import org.jivesoftware.smackx.provider.DelayInformationProvider;
+import org.jivesoftware.smackx.provider.DiscoverInfoProvider;
+import org.jivesoftware.smackx.provider.DiscoverItemsProvider;
+import org.jivesoftware.smackx.provider.IBBProviders;
+import org.jivesoftware.smackx.provider.MUCAdminProvider;
+import org.jivesoftware.smackx.provider.MUCOwnerProvider;
+import org.jivesoftware.smackx.provider.MUCUserProvider;
+import org.jivesoftware.smackx.provider.MessageEventProvider;
+import org.jivesoftware.smackx.provider.MultipleAddressesProvider;
+import org.jivesoftware.smackx.provider.RosterExchangeProvider;
+import org.jivesoftware.smackx.provider.StreamInitiationProvider;
+import org.jivesoftware.smackx.provider.VCardProvider;
+import org.jivesoftware.smackx.provider.XHTMLExtensionProvider;
+import org.jivesoftware.smackx.search.UserSearch;
 
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -53,6 +79,7 @@
     private ProxyInfo mProxyInfo;
     private boolean mUseProxy;
     private IXmppFacade.Stub mBind;
+    private ProviderManager mProviderManager;
 
     /**
      * Constructor.
@@ -136,6 +163,8 @@
 	}
 
 	initConnectionConfig();
+	configure(ProviderManager.getInstance());
+
 	mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
 	mConnection = new XmppConnectionAdapter(mConnectionConfiguration, mLogin, mPassword, this);
 
@@ -220,4 +249,91 @@
     public SharedPreferences getServicePreference() {
 	return mSettings;
     }
+
+    /**
+     * A sort of patch from this thread: http://www.igniterealtime.org/community/thread/31118. Avoid ClassCastException
+     * by bypassing the classloading shit of Smack.
+     * @param pm The ProviderManager.
+     */
+    private void configure(ProviderManager pm) {
+	// Private Data Storage
+	pm.addIQProvider("query", "jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider());
+	// Time
+	try {
+	    pm.addIQProvider("query", "jabber:iq:time", Class.forName("org.jivesoftware.smackx.packet.Time"));
+	} catch (ClassNotFoundException e) {
+	    Log.w("TestClient", "Can't load class for org.jivesoftware.smackx.packet.Time");
+	}
+	// Roster Exchange
+	pm.addExtensionProvider("x", "jabber:x:roster", new RosterExchangeProvider());
+	// Message Events
+	pm.addExtensionProvider("x", "jabber:x:event", new MessageEventProvider());
+	// Chat State
+	pm.addExtensionProvider("active", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
+	pm.addExtensionProvider("composing", "http://jabber.org/protocol/chatstates",
+	    new ChatStateExtension.Provider());
+	pm.addExtensionProvider("paused", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
+	pm
+	    .addExtensionProvider("inactive", "http://jabber.org/protocol/chatstates",
+		new ChatStateExtension.Provider());
+	pm.addExtensionProvider("gone", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
+	// XHTML
+	pm.addExtensionProvider("html", "http://jabber.org/protocol/xhtml-im", new XHTMLExtensionProvider());
+	// Group Chat Invitations
+	pm.addExtensionProvider("x", "jabber:x:conference", new GroupChatInvitation.Provider());
+	// Service Discovery # Items
+	pm.addIQProvider("query", "http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
+	// Service Discovery # Info
+	pm.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
+	// Data Forms
+	pm.addExtensionProvider("x", "jabber:x:data", new DataFormProvider());
+	// MUC User
+	pm.addExtensionProvider("x", "http://jabber.org/protocol/muc#user", new MUCUserProvider());
+	// MUC Admin
+	pm.addIQProvider("query", "http://jabber.org/protocol/muc#admin", new MUCAdminProvider());
+	// MUC Owner
+	pm.addIQProvider("query", "http://jabber.org/protocol/muc#owner", new MUCOwnerProvider());
+	// Delayed Delivery
+	pm.addExtensionProvider("x", "jabber:x:delay", new DelayInformationProvider());
+	// Version
+	try {
+	    pm.addIQProvider("query", "jabber:iq:version", Class.forName("org.jivesoftware.smackx.packet.Version"));
+	} catch (ClassNotFoundException e) {
+	    // Not sure what's happening here.
+	}
+	// VCard
+	pm.addIQProvider("vCard", "vcard-temp", new VCardProvider());
+	// Offline Message Requests
+	pm.addIQProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageRequest.Provider());
+	// Offline Message Indicator
+	pm.addExtensionProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageInfo.Provider());
+	// Last Activity
+	pm.addIQProvider("query", "jabber:iq:last", new LastActivity.Provider());
+	// User Search
+	pm.addIQProvider("query", "jabber:iq:search", new UserSearch.Provider());
+	// SharedGroupsInfo
+	pm.addIQProvider("sharedgroup", "http://www.jivesoftware.org/protocol/sharedgroup",
+	    new SharedGroupsInfo.Provider());
+	// JEP-33: Extended Stanza Addressing
+	pm.addExtensionProvider("addresses", "http://jabber.org/protocol/address", new MultipleAddressesProvider());
+	// FileTransfer
+	pm.addIQProvider("si", "http://jabber.org/protocol/si", new StreamInitiationProvider());
+	pm.addIQProvider("query", "http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
+	pm.addIQProvider("open", "http://jabber.org/protocol/ibb", new IBBProviders.Open());
+	pm.addIQProvider("close", "http://jabber.org/protocol/ibb", new IBBProviders.Close());
+	pm.addExtensionProvider("data", "http://jabber.org/protocol/ibb", new IBBProviders.Data());
+	// Privacy
+	pm.addIQProvider("query", "jabber:iq:privacy", new PrivacyProvider());
+	pm.addIQProvider("command", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider());
+	pm.addExtensionProvider("malformed-action", "http://jabber.org/protocol/commands",
+	    new AdHocCommandDataProvider.MalformedActionError());
+	pm.addExtensionProvider("bad-locale", "http://jabber.org/protocol/commands",
+	    new AdHocCommandDataProvider.BadLocaleError());
+	pm.addExtensionProvider("bad-payload", "http://jabber.org/protocol/commands",
+	    new AdHocCommandDataProvider.BadPayloadError());
+	pm.addExtensionProvider("bad-sessionid", "http://jabber.org/protocol/commands",
+	    new AdHocCommandDataProvider.BadSessionIDError());
+	pm.addExtensionProvider("session-expired", "http://jabber.org/protocol/commands",
+	    new AdHocCommandDataProvider.SessionExpiredError());
+    }
 }
--- a/src/com/beem/project/beem/service/PrivacyListManagerAdapter.java	Thu Nov 19 01:48:54 2009 +0100
+++ b/src/com/beem/project/beem/service/PrivacyListManagerAdapter.java	Thu Nov 19 01:56:33 2009 +0100
@@ -6,9 +6,9 @@
 import org.jivesoftware.smack.PrivacyList;
 import org.jivesoftware.smack.PrivacyListListener;
 import org.jivesoftware.smack.PrivacyListManager;
-import org.jivesoftware.smack.XMPPConnection;
 import org.jivesoftware.smack.XMPPException;
 import org.jivesoftware.smack.packet.PrivacyItem;
+import org.jivesoftware.smack.packet.PrivacyItem.PrivacyRule;
 
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -28,7 +28,6 @@
      */
     public static final String TAG = "PrivacyListManagerAdapter";
 
-    private final XMPPConnection mXmppConnection;
     private final PrivacyListManager mPrivacyListManager;
 
     private final RemoteCallbackList<IPrivacyListListener> mPrivacyListListeners = new RemoteCallbackList<IPrivacyListListener>();
@@ -38,9 +37,8 @@
      * Constructor.
      * @param connection The XMPP connection that will be used by the PrivacyListManagerAdapter.
      */
-    public PrivacyListManagerAdapter(final XMPPConnection connection) {
-	mXmppConnection = connection;
-	mPrivacyListManager = PrivacyListManager.getInstanceFor(mXmppConnection);
+    public PrivacyListManagerAdapter(final PrivacyListManager privacyListManager) {
+	mPrivacyListManager = privacyListManager;
 	mPrivacyListManager.addListener(mPrivacyListListener);
     }
 
@@ -50,11 +48,19 @@
 
     @Override
     public void createPrivacyList(String listName, List<PrivacyListItem> items) throws RemoteException {
+	Log.d(TAG, "BEGIN createPrivacyList.");
 	try {
-	    mPrivacyListManager.createPrivacyList(listName, tranformPrivacyListItemsToPrivacyItems(items));
+	    List<PrivacyItem> privacyItems = new ArrayList<PrivacyItem>();
+
+	    PrivacyItem item = new PrivacyItem(PrivacyItem.Type.subscription.name(), true, 2);
+	    item.setValue(PrivacyRule.SUBSCRIPTION_BOTH);
+	    privacyItems.add(item);
+
+	    mPrivacyListManager.createPrivacyList(listName, privacyItems);
 	} catch (XMPPException e) {
 	    Log.e(TAG, e.getMessage());
 	}
+	Log.d(TAG, "END createPrivacyList.");
     }
 
     @Override
@@ -77,11 +83,13 @@
 
     @Override
     public void editPrivacyList(String listName, List<PrivacyListItem> items) throws RemoteException {
+	Log.d(TAG, "BEGIN editPrivacyList.");
 	try {
 	    mPrivacyListManager.updatePrivacyList(listName, tranformPrivacyListItemsToPrivacyItems(items));
 	} catch (XMPPException e) {
 	    Log.e(TAG, e.getMessage());
 	}
+	Log.d(TAG, "END editPrivacyList.");
     }
 
     @Override
@@ -159,7 +167,7 @@
 	try {
 	    mPrivacyListManager.setDefaultListName(listName);
 	} catch (XMPPException e) {
-	    e.getMessage();
+	    Log.e(TAG, e.getMessage());
 	}
     }
 
@@ -186,7 +194,6 @@
      */
     private List<PrivacyListItem> tranformPrivacyItemsToPrivacyListItems(List<PrivacyItem> items) {
 	List<PrivacyListItem> rItems = new ArrayList<PrivacyListItem>();
-	PrivacyItem.Type[] itemTypes = PrivacyItem.Type.values();
 
 	for (int i = 0; i < items.size(); i++) {
 	    rItems.add(new PrivacyListItem(items.get(i).getType().ordinal(), items.get(i).getValue()));
@@ -201,12 +208,13 @@
     private class PrivacyListListenerAdapter implements PrivacyListListener {
 
 	@Override
-	public void setPrivacyList(String listName, List<PrivacyItem> listItem) {
-	    final int n = mPrivacyListListeners.beginBroadcast();
-	    for (int i = 0; i < n; i++) {
-		IPrivacyListListener listener = mPrivacyListListeners.getBroadcastItem(i);
+	public void setPrivacyList(final String listName, final List<PrivacyItem> listItem) {
+	    int i = mPrivacyListListeners.beginBroadcast();
+	    while (i > 0) {
+		i--;
 		try {
-		    listener.setPrivacyList(listName, tranformPrivacyItemsToPrivacyListItems(listItem));
+		    mPrivacyListListeners.getBroadcastItem(i).setPrivacyList(listName,
+			tranformPrivacyItemsToPrivacyListItems(listItem));
 		} catch (RemoteException e) {
 		    Log.w(TAG, e.getMessage());
 		}
@@ -215,17 +223,19 @@
 	}
 
 	@Override
-	public void updatedPrivacyList(String listName) {
-	    final int n = mPrivacyListListeners.beginBroadcast();
-	    for (int i = 0; i < n; i++) {
-		IPrivacyListListener listener = mPrivacyListListeners.getBroadcastItem(i);
+	public void updatedPrivacyList(final String listName) {
+	    Log.d(TAG, "BEGIN updatedPrivacyList.");
+	    int i = mPrivacyListListeners.beginBroadcast();
+	    while (i > 0) {
+		i--;
 		try {
-		    listener.updatedPrivacyList(listName);
+		    mPrivacyListListeners.getBroadcastItem(i).updatedPrivacyList(listName);
 		} catch (RemoteException e) {
 		    Log.w(TAG, e.getMessage());
 		}
 	    }
 	    mPrivacyListListeners.finishBroadcast();
+	    Log.d(TAG, "END updatedPrivacyList.");
 	}
     }
 
@@ -243,16 +253,21 @@
 
     @Override
     public List<String> getPrivacyLists() throws RemoteException {
+	Log.d(TAG, "BEGIN getPrivacyLists.");
 	List<String> res = new ArrayList<String>();
 	try {
-	    PrivacyList[] serverPrivacyLists = mPrivacyListManager.getPrivacyLists();
-	    if (serverPrivacyLists.length > 0) {
-		for (int i = 0; i < serverPrivacyLists.length; i++)
-		    res.add(serverPrivacyLists[i].toString());
+	    PrivacyList[] registeredPrivacyLists = mPrivacyListManager.getPrivacyLists();
+	    Log.d(TAG, "> registeredPrivacyLists size: " + registeredPrivacyLists.length);
+	    if (registeredPrivacyLists.length > 0) {
+		for (int i = 0; i < registeredPrivacyLists.length; i++) {
+		    res.add(registeredPrivacyLists[i].toString());
+		    Log.d(TAG, "> " + res.get(i) + " added.");
+		}
 	    }
 	} catch (XMPPException e) {
 	    Log.e(TAG, e.getMessage());
 	}
+	Log.d(TAG, "END getPrivacyLists.");
 	return res;
     }
 }
--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Thu Nov 19 01:48:54 2009 +0100
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Thu Nov 19 01:56:33 2009 +0100
@@ -145,7 +145,7 @@
 	    mAdaptee.login(mLogin, mPassword, mResource);
 
 	    mChatManager = new BeemChatManager(mAdaptee.getChatManager(), mService);
-	    mPrivacyListManager = new PrivacyListManagerAdapter(mAdaptee);
+	    mPrivacyListManager = new PrivacyListManagerAdapter(PrivacyListManager.getInstanceFor(mAdaptee));
 
 	    this.initFeatures(); // pour declarer les features xmpp qu'on
 	    // supporte
@@ -218,7 +218,7 @@
      * @param text the text to display.
      */
     private void updateNotification(String text) {
- 	Notification mStatusNotification;
+	Notification mStatusNotification;
 	mStatusNotification = new Notification(com.beem.project.beem.R.drawable.beem_status_icon, text, System
 	    .currentTimeMillis());
 	mStatusNotification.defaults = Notification.DEFAULT_LIGHTS;
--- a/src/com/beem/project/beem/ui/PrivacyList.java	Thu Nov 19 01:48:54 2009 +0100
+++ b/src/com/beem/project/beem/ui/PrivacyList.java	Thu Nov 19 01:56:33 2009 +0100
@@ -4,6 +4,7 @@
 import java.util.List;
 
 import android.app.AlertDialog;
+import android.app.Dialog;
 import android.app.ListActivity;
 import android.content.ComponentName;
 import android.content.DialogInterface;
@@ -22,6 +23,7 @@
 import android.view.View;
 import android.widget.ArrayAdapter;
 import android.widget.EditText;
+import android.widget.ListView;
 
 import com.beem.project.beem.BeemService;
 import com.beem.project.beem.R;
@@ -42,10 +44,17 @@
     static {
 	SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
     }
+    private static final int DIALOG_PRIVACY_LIST_ITEM = 1;
+    private static final int DIALOG_CREATE_PRIVACY_LIST = 2;
+
+    private static final String SAVED_INSTANCE_KEY_PRIVACY_LISTS = "PRIVACY_LISTS";
+    private static final String SAVED_INSTANCE_KEY_LAST_CLICKED_ITEM = "LAST_CLICKED_ITEM";
+
     private Handler mHandler = new Handler();
 
     private ArrayAdapter<String> mAdapter;
     private final List<String> mPrivacyListNames = new ArrayList<String>();
+    private int mPosLastClickedItem;
 
     private final ServiceConnection mConn = new BeemServiceConnection();
     private BeemBroadcastReceiver mBroadcastReceiver;
@@ -64,6 +73,18 @@
      * {@inheritDoc}.
      */
     @Override
+    protected void onSaveInstanceState(Bundle savedInstanceState) {
+	Log.d(TAG, "BEGIN onSaveInstanceState.");
+	savedInstanceState.putStringArrayList(SAVED_INSTANCE_KEY_PRIVACY_LISTS, (ArrayList<String>) mPrivacyListNames);
+	savedInstanceState.putInt(SAVED_INSTANCE_KEY_LAST_CLICKED_ITEM, mPosLastClickedItem);
+	Log.d(TAG, "END onSaveInstanceState.");
+	super.onSaveInstanceState(savedInstanceState);
+    }
+
+    /**
+     * {@inheritDoc}.
+     */
+    @Override
     protected void onCreate(Bundle savedInstanceState) {
 	super.onCreate(savedInstanceState);
 	Log.d(TAG, "BEGIN onCreate.");
@@ -71,6 +92,11 @@
 
 	mHandler = new Handler();
 
+	if (savedInstanceState != null && !savedInstanceState.isEmpty()) {
+	    mPrivacyListNames.addAll(savedInstanceState.getStringArrayList(SAVED_INSTANCE_KEY_PRIVACY_LISTS));
+	    mPosLastClickedItem = savedInstanceState.getInt(SAVED_INSTANCE_KEY_LAST_CLICKED_ITEM);
+	}
+
 	mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mPrivacyListNames);
 	setListAdapter(mAdapter);
 
@@ -85,11 +111,83 @@
      * {@inheritDoc}.
      */
     @Override
+    protected void onPrepareDialog(int id, Dialog dialog) {
+	Log.d(TAG, "BEGIN onPrepareDialog.");
+	switch (id) {
+	    case DIALOG_PRIVACY_LIST_ITEM:
+		String dialogTitle = (mPosLastClickedItem > mPrivacyListNames.size() ? "" : mPrivacyListNames
+		    .get(mPosLastClickedItem));
+		dialog.setTitle(dialogTitle);
+	}
+	Log.d(TAG, "END onPrepareDialog.");
+    }
+
+    /**
+     * {@inheritDoc}.
+     */
+    @Override
+    protected Dialog onCreateDialog(int id) {
+	Log.d(TAG, "BEGIN onCreateDialog.");
+	switch (id) {
+	    case DIALOG_PRIVACY_LIST_ITEM:
+		return new AlertDialog.Builder(this).setTitle("X").setItems(R.array.privacy_list_select_dialog,
+		    new DialogInterface.OnClickListener() {
+			public void onClick(DialogInterface dialog, int which) {
+			    String[] items = getResources().getStringArray(R.array.privacy_list_select_dialog);
+			    if (items[which].equals(getResources().getString(
+				R.string.privacy_list_select_dialog_delete))) {
+				try {
+				    mPrivacyListManager.removePrivacyList(mPrivacyListNames.get(mPosLastClickedItem));
+				} catch (RemoteException e) {
+				    Log.e(TAG, e.getMessage());
+				}
+				dismissDialog(DIALOG_PRIVACY_LIST_ITEM);
+			    }
+			}
+		    }).create();
+
+	    case DIALOG_CREATE_PRIVACY_LIST:
+		LayoutInflater factory = LayoutInflater.from(this);
+		final View textEntryView = factory.inflate(R.layout.privacy_list_create_dialog, null);
+
+		return new AlertDialog.Builder(this).setTitle(R.string.privacy_list_create_dialog_title).setView(
+		    textEntryView).setPositiveButton(R.string.privacy_list_create_dialog_create_button,
+		    new DialogInterface.OnClickListener() {
+			public void onClick(DialogInterface dialog, int whichButton) {
+			    EditText listNameField = (EditText) textEntryView
+				.findViewById(R.id.privacy_list_create_dialog_list_name);
+			    try {
+				mPrivacyListManager.createPrivacyList(listNameField.getText().toString(),
+				    new ArrayList<PrivacyListItem>());
+			    } catch (RemoteException e) {
+				Log.e(TAG, e.getMessage());
+			    }
+			}
+		    }).setNegativeButton(R.string.CancelButton, new DialogInterface.OnClickListener() {
+		    public void onClick(DialogInterface dialog, int whichButton) {
+		    }
+		}).create();
+	}
+	Log.d(TAG, "END onCreateDialog.");
+	return null;
+    }
+
+    /**
+     * {@inheritDoc}.
+     */
+    @Override
     protected void onDestroy() {
 	super.onDestroy();
 
 	Log.v(TAG, "BEGIN onDestroy.");
 	this.unregisterReceiver(mBroadcastReceiver);
+	if (mPrivacyListManager != null) {
+	    try {
+		mPrivacyListManager.removePrivacyListListener(mPrivacyListListener);
+	    } catch (RemoteException e) {
+		Log.e(TAG, e.getMessage());
+	    }
+	}
 	Log.v(TAG, "END onDestroy.");
     }
 
@@ -135,10 +233,19 @@
      * {@inheritDoc}.
      */
     @Override
+    public void onListItemClick(ListView l, View v, int position, long id) {
+	mPosLastClickedItem = position;
+	showDialog(DIALOG_PRIVACY_LIST_ITEM);
+    }
+
+    /**
+     * {@inheritDoc}.
+     */
+    @Override
     public final boolean onOptionsItemSelected(MenuItem item) {
 	switch (item.getItemId()) {
 	    case R.id.privacy_list_menu_create:
-		createCreatePrivacyListDialog();
+		showDialog(DIALOG_CREATE_PRIVACY_LIST);
 		return true;
 	    default:
 		return false;
@@ -157,14 +264,9 @@
 	    try {
 		mPrivacyListManager = mXmppFacade.getPrivacyListManager();
 		mPrivacyListManager.addPrivacyListListener(mPrivacyListListener);
-		/**
-		 * FIXME: ERROR /AndroidRuntime(21999): java.lang.ClassCastException:
-		 * org.jivesoftware.smack.PacketReader$4 ERROR/AndroidRuntime(21999): at
-		 * org.jivesoftware.smack.PrivacyListManager.getRequest(PrivacyListManager.java:189) at
-		 * org.jivesoftware.smack.PrivacyListManager.getPrivacyWithListNames(PrivacyListManager.java:254)
-		 */
-		// mPrivacyListNames = mPrivacyListManager.getPrivacyLists();
-		// mAdapter.notifyDataSetChanged();
+		mPrivacyListNames.clear();
+		mPrivacyListNames.addAll(mPrivacyListManager.getPrivacyLists());
+		mAdapter.notifyDataSetChanged();
 	    } catch (RemoteException e) {
 		Log.e(TAG, e.getMessage());
 	    }
@@ -176,6 +278,11 @@
 	    Log.v(TAG, "BEGIN onServiceDisconnected.");
 	    mXmppFacade = null;
 	    mBroadcastReceiver.setBinded(false);
+	    try {
+		mPrivacyListManager.removePrivacyListListener(mPrivacyListListener);
+	    } catch (RemoteException e) {
+		Log.e(TAG, e.getMessage());
+	    }
 	    Log.v(TAG, "END onServiceDisconnected.");
 	}
     }
@@ -185,45 +292,28 @@
 	@Override
 	public void setPrivacyList(String listName, List<PrivacyListItem> listItem) throws RemoteException {
 	    Log.d(TAG, "BEGIN PrivacyListListener >> setPrivacyList.");
-	    Log.d(TAG, listName);
+	    Log.d(TAG, "> " + listName + " has been setted.");
 	    Log.d(TAG, "END PrivacyListListener >> setPrivacyList.");
 	}
 
 	@Override
-	public void updatedPrivacyList(String listName) throws RemoteException {
+	public void updatedPrivacyList(final String listName) throws RemoteException {
 	    Log.d(TAG, "BEGIN PrivacyListListener >> updatedPrivacyList.");
-	    Log.d(TAG, listName);
+	    mHandler.post(new Runnable() {
+		@Override
+		public void run() {
+		    try {
+			mPrivacyListNames.clear();
+			// Not that much lists and require some server queries to know if the list has been
+			// updated/deleted or set to default/active by this activity or another IM client.
+			mPrivacyListNames.addAll(mPrivacyListManager.getPrivacyLists());
+		    } catch (RemoteException e) {
+			Log.e(TAG, e.getMessage());
+		    }
+		    mAdapter.notifyDataSetChanged();
+		}
+	    });
 	    Log.d(TAG, "END PrivacyListListener >> updatedPrivacyList.");
 	}
     }
-
-    private void createCreatePrivacyListDialog() {
-	LayoutInflater factory = LayoutInflater.from(this);
-	final View textEntryView = factory.inflate(R.layout.privacy_list_create_dialog, null);
-	AlertDialog.Builder builder = new AlertDialog.Builder(this);
-	builder.setTitle(R.string.privacy_list_create_dialog_title);
-	builder.setView(textEntryView);
-
-	builder.setPositiveButton(R.string.privacy_list_create_dialog_create_button,
-	    new DialogInterface.OnClickListener() {
-		public void onClick(DialogInterface dialog, int whichButton) {
-		    EditText listNameField = (EditText) textEntryView
-			.findViewById(R.id.privacy_list_create_dialog_list_name);
-		    try {
-			mPrivacyListManager.createPrivacyList(listNameField.getText().toString(),
-			    new ArrayList<PrivacyListItem>());
-		    } catch (RemoteException e) {
-			Log.e(TAG, e.getMessage());
-		    }
-		}
-	    });
-
-	builder.setNegativeButton(R.string.CancelButton, new DialogInterface.OnClickListener() {
-	    public void onClick(DialogInterface dialog, int whichButton) {
-	    }
-	});
-
-	AlertDialog createPrivacyListDialog = builder.create();
-	createPrivacyListDialog.show();
-    }
 }
--- a/src/com/beem/project/beem/ui/Settings.java	Thu Nov 19 01:48:54 2009 +0100
+++ b/src/com/beem/project/beem/ui/Settings.java	Thu Nov 19 01:56:33 2009 +0100
@@ -103,8 +103,9 @@
 		finish();
 		return true;
 	    case R.id.settings_menu_privacy_lists:
-		i = new Intent(this, PrivacyList.class);
-		startActivity(i);
+		/*
+		 * i = new Intent(this, PrivacyList.class); startActivity(i);
+		 */
 		return true;
 	    default:
 		return false;