# HG changeset patch # User Jean-Manuel Da Silva # Date 1258499795 -3600 # Node ID a77a7b4e7f34678b254b77e5a2627f6aa6a4bbf8 # Parent d9e22d4c2bb24f9f256599741b74802e9df5cc09 ClassCastException resolved, PrivacyList creation fixed. diff -r d9e22d4c2bb2 -r a77a7b4e7f34 src/com/beem/project/beem/BeemService.java --- a/src/com/beem/project/beem/BeemService.java Tue Nov 17 00:29:37 2009 +0100 +++ b/src/com/beem/project/beem/BeemService.java Wed Nov 18 00:16:35 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()); + } } diff -r d9e22d4c2bb2 -r a77a7b4e7f34 src/com/beem/project/beem/service/PrivacyListManagerAdapter.java --- a/src/com/beem/project/beem/service/PrivacyListManagerAdapter.java Tue Nov 17 00:29:37 2009 +0100 +++ b/src/com/beem/project/beem/service/PrivacyListManagerAdapter.java Wed Nov 18 00:16:35 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 mPrivacyListListeners = new RemoteCallbackList(); @@ -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 items) throws RemoteException { + Log.d(TAG, "BEGIN createPrivacyList."); try { - mPrivacyListManager.createPrivacyList(listName, tranformPrivacyListItemsToPrivacyItems(items)); + List privacyItems = new ArrayList(); + + 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 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 tranformPrivacyItemsToPrivacyListItems(List items) { List rItems = new ArrayList(); - 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 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 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 getPrivacyLists() throws RemoteException { + Log.d(TAG, "BEGIN getPrivacyLists."); List res = new ArrayList(); 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; } } diff -r d9e22d4c2bb2 -r a77a7b4e7f34 src/com/beem/project/beem/service/XmppConnectionAdapter.java --- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java Tue Nov 17 00:29:37 2009 +0100 +++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java Wed Nov 18 00:16:35 2009 +0100 @@ -28,9 +28,9 @@ import com.beem.project.beem.service.aidl.IChatManager; import com.beem.project.beem.service.aidl.IRoster; import com.beem.project.beem.service.aidl.IXmppConnection; +import com.beem.project.beem.ui.ChangeStatus; import com.beem.project.beem.ui.Subscription; import com.beem.project.beem.utils.BeemBroadcastReceiver; -import com.beem.project.beem.ui.ChangeStatus; import com.beem.project.beem.utils.Status; /** @@ -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 @@ -182,8 +182,10 @@ if (mode != null) pres.setMode(mode); // Smack limit : Priority between -128 and 128 - if (priority < -128) priority = -128; - if (priority > 128) priority = 128; + if (priority < -128) + priority = -128; + if (priority > 128) + priority = 128; mPreviousPriority = priority; pres.setPriority(priority); mAdaptee.sendPacket(pres); @@ -209,16 +211,16 @@ } 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; mStatusNotification.flags = Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT; - mStatusNotification.setLatestEventInfo(mService, "Beem Status", text, PendingIntent.getActivity( - mService, 0, new Intent(mService, ChangeStatus.class), 0)); + mStatusNotification.setLatestEventInfo(mService, "Beem Status", text, PendingIntent.getActivity(mService, 0, + new Intent(mService, ChangeStatus.class), 0)); mService.sendNotification(BeemService.NOTIFICATION_STATUS_ID, mStatusNotification); - + } /** @@ -405,8 +407,8 @@ @Override public void processPacket(Packet packet) { String from = packet.getFrom(); - Notification notif = new Notification(android.R.drawable.stat_notify_more, mService - .getString(R.string.AcceptContactRequest, from), System.currentTimeMillis()); + Notification notif = new Notification(android.R.drawable.stat_notify_more, mService.getString( + R.string.AcceptContactRequest, from), System.currentTimeMillis()); notif.defaults = Notification.DEFAULT_ALL; notif.flags = Notification.FLAG_AUTO_CANCEL; Intent intent = new Intent(mService, Subscription.class); @@ -505,8 +507,8 @@ @Override public void processPacket(Packet packet) { String from = packet.getFrom(); - Notification notif = new Notification(android.R.drawable.stat_notify_more, mService - .getString(R.string.AcceptContactRequest, from), System.currentTimeMillis()); + Notification notif = new Notification(android.R.drawable.stat_notify_more, mService.getString( + R.string.AcceptContactRequest, from), System.currentTimeMillis()); notif.defaults = Notification.DEFAULT_ALL; notif.flags = Notification.FLAG_AUTO_CANCEL; Intent intent = new Intent(mService, Subscription.class); diff -r d9e22d4c2bb2 -r a77a7b4e7f34 src/com/beem/project/beem/service/XmppFacade.java --- a/src/com/beem/project/beem/service/XmppFacade.java Tue Nov 17 00:29:37 2009 +0100 +++ b/src/com/beem/project/beem/service/XmppFacade.java Wed Nov 18 00:16:35 2009 +0100 @@ -4,9 +4,6 @@ import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smackx.packet.VCard; -import android.app.Notification; -import android.app.PendingIntent; -import android.content.Intent; import android.os.RemoteException; import com.beem.project.beem.BeemService; @@ -16,9 +13,7 @@ import com.beem.project.beem.service.aidl.IRoster; import com.beem.project.beem.service.aidl.IXmppConnection; import com.beem.project.beem.service.aidl.IXmppFacade; -import com.beem.project.beem.ui.ChangeStatus; import com.beem.project.beem.utils.PresenceType; -import com.beem.project.beem.utils.Status; /** * This class is a facade for the Beem Service. diff -r d9e22d4c2bb2 -r a77a7b4e7f34 src/com/beem/project/beem/ui/PrivacyList.java --- a/src/com/beem/project/beem/ui/PrivacyList.java Tue Nov 17 00:29:37 2009 +0100 +++ b/src/com/beem/project/beem/ui/PrivacyList.java Wed Nov 18 00:16:35 2009 +0100 @@ -20,8 +20,10 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; +import android.widget.AdapterView.OnItemClickListener; import com.beem.project.beem.BeemService; import com.beem.project.beem.R; @@ -74,6 +76,12 @@ mAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, mPrivacyListNames); setListAdapter(mAdapter); + this.getListView().setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) { + } + }); + mPrivacyListListener = new PrivacyListListener(); mBroadcastReceiver = new BeemBroadcastReceiver(mConn); this.registerReceiver(mBroadcastReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED)); @@ -90,6 +98,13 @@ 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."); } @@ -157,14 +172,8 @@ 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.addAll(mPrivacyListManager.getPrivacyLists()); + mAdapter.notifyDataSetChanged(); } catch (RemoteException e) { Log.e(TAG, e.getMessage()); } @@ -176,6 +185,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,14 +199,27 @@ @Override public void setPrivacyList(String listName, List 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."); } }