/* * Copyright (C) 2007-2008 Esmertec AG. Copyright (C) 2007-2008 The Android Open * Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package info.guardianproject.otr.app.im.service; import info.guardianproject.otr.app.im.IChatSession; import info.guardianproject.otr.app.im.IChatSessionListener; import info.guardianproject.otr.app.im.app.ImApp; import info.guardianproject.otr.app.im.engine.Address; import info.guardianproject.otr.app.im.engine.ChatGroup; import info.guardianproject.otr.app.im.engine.ChatGroupManager; import info.guardianproject.otr.app.im.engine.ChatSession; import info.guardianproject.otr.app.im.engine.ChatSessionListener; import info.guardianproject.otr.app.im.engine.ChatSessionManager; import info.guardianproject.otr.app.im.engine.Contact; import info.guardianproject.otr.app.im.engine.GroupListener; import info.guardianproject.otr.app.im.engine.ImConnection; import info.guardianproject.otr.app.im.engine.ImErrorInfo; import info.guardianproject.otr.app.im.plugin.xmpp.XmppAddress; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.jivesoftware.smackx.muc.MultiUserChat; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.util.Log; /** manages the chat sessions for a given protocol */ public class ChatSessionManagerAdapter extends info.guardianproject.otr.app.im.IChatSessionManager.Stub { ImConnectionAdapter mConnection; ChatSessionListenerAdapter mSessionListenerAdapter; final RemoteCallbackList<IChatSessionListener> mRemoteListeners = new RemoteCallbackList<IChatSessionListener>(); static HashMap<String, ChatSessionAdapter> mActiveChatSessionAdapters; public ChatSessionManagerAdapter(ImConnectionAdapter connection) { mConnection = connection; ImConnection connAdaptee = connection.getAdaptee(); connAdaptee.getChatSessionManager().setAdapter(this); mActiveChatSessionAdapters = new HashMap<String, ChatSessionAdapter>(); mSessionListenerAdapter = new ChatSessionListenerAdapter(); getChatSessionManager().addChatSessionListener(mSessionListenerAdapter); } public ChatGroupManager getChatGroupManager () { if ((mConnection.getAdaptee().getCapability() & ImConnection.CAPABILITY_GROUP_CHAT) != 0) { ChatGroupManager groupManager = mConnection.getAdaptee().getChatGroupManager(); groupManager.addGroupListener(new ChatGroupListenerAdapter()); return groupManager; } else return null; } public ChatSessionManager getChatSessionManager() { return mConnection.getAdaptee().getChatSessionManager(); } public IChatSession createChatSession(String contactAddress, boolean isNewSession) { ContactListManagerAdapter listManager = (ContactListManagerAdapter) mConnection .getContactListManager(); Contact contact = listManager.getContactByAddress(Address.stripResource(contactAddress)); if (contact == null) { try { contact = new Contact (new XmppAddress(contactAddress),contactAddress); long contactId = listManager.queryOrInsertContact(contact); // String[] address = {Address.stripResource(contactAddress)}; //contact = listManager.createTemporaryContacts(address)[0]; } catch (IllegalArgumentException e) { mSessionListenerAdapter.notifyChatSessionCreateFailed(contactAddress, new ImErrorInfo(ImErrorInfo.ILLEGAL_CONTACT_ADDRESS, "Invalid contact address:" + contactAddress)); return null; } } ChatSession session = getChatSessionManager().createChatSession(contact, isNewSession); return getChatSessionAdapter(session, isNewSession); } public String getDefaultMultiUserChatServer () { ChatGroupManager groupMan = mConnection.getAdaptee().getChatGroupManager(); return groupMan.getDefaultMultiUserChatServer(); } public IChatSession createMultiUserChatSession(String roomAddress, String nickname, boolean isNewChat) { ChatGroupManager groupMan = mConnection.getAdaptee().getChatGroupManager(); try { groupMan.createChatGroupAsync(roomAddress, nickname); Address address = new XmppAddress(roomAddress); //TODO hard coding XMPP for now // ContactListManagerAdapter listManager = (ContactListManagerAdapter) mConnection // .getContactListManager(); // long contactId = listManager.queryOrInsertContact(new Contact (new XmppAddress(roomAddress),roomAddress)); ChatGroup chatGroup = groupMan.getChatGroup(address); if (chatGroup != null) { ChatSession session = getChatSessionManager().createChatSession(chatGroup,isNewChat); return getChatSessionAdapter(session, isNewChat); } else { return null; } } catch (Exception e) { Log.e(ImApp.LOG_TAG,"unable to join group chat",e); return null; } } public void closeChatSession(ChatSessionAdapter adapter) { synchronized (mActiveChatSessionAdapters) { ChatSession session = adapter.getAdaptee(); getChatSessionManager().closeChatSession(session); String key = Address.stripResource(adapter.getAddress()); mActiveChatSessionAdapters.remove(key); } } public void closeAllChatSessions() { synchronized (mActiveChatSessionAdapters) { ArrayList<ChatSessionAdapter> adapters = new ArrayList<ChatSessionAdapter>( mActiveChatSessionAdapters.values()); for (ChatSessionAdapter adapter : adapters) { adapter.leave(); } } } public void updateChatSession(String oldAddress, ChatSessionAdapter adapter) { synchronized (mActiveChatSessionAdapters) { mActiveChatSessionAdapters.remove(oldAddress); mActiveChatSessionAdapters.put(Address.stripResource(adapter.getAddress()), adapter); } } public IChatSession getChatSession(String address) { synchronized (mActiveChatSessionAdapters) { return mActiveChatSessionAdapters.get(Address.stripResource(address)); } } public List<ChatSessionAdapter> getActiveChatSessions() { synchronized (mActiveChatSessionAdapters) { return new ArrayList<ChatSessionAdapter>(mActiveChatSessionAdapters.values()); } } public int getChatSessionCount() { synchronized (mActiveChatSessionAdapters) { return mActiveChatSessionAdapters.size(); } } public void registerChatSessionListener(IChatSessionListener listener) { if (listener != null) { mRemoteListeners.register(listener); } } public void unregisterChatSessionListener(IChatSessionListener listener) { if (listener != null) { mRemoteListeners.unregister(listener); } } public synchronized ChatSessionAdapter getChatSessionAdapter(ChatSession session, boolean isNewSession) { Address participantAddress = session.getParticipant().getAddress(); String key = Address.stripResource(participantAddress.getAddress()); ChatSessionAdapter adapter = mActiveChatSessionAdapters.get(key); if (adapter == null) { adapter = new ChatSessionAdapter(session, mConnection, isNewSession); mActiveChatSessionAdapters.put(key, adapter); } return adapter; } class ChatSessionListenerAdapter implements ChatSessionListener { public void onChatSessionCreated(ChatSession session) { final IChatSession sessionAdapter = getChatSessionAdapter(session, false); final int N = mRemoteListeners.beginBroadcast(); for (int i = 0; i < N; i++) { IChatSessionListener listener = mRemoteListeners.getBroadcastItem(i); try { listener.onChatSessionCreated(sessionAdapter); } catch (RemoteException e) { // The RemoteCallbackList will take care of removing the // dead listeners. } } mRemoteListeners.finishBroadcast(); } public void notifyChatSessionCreateFailed(final String name, final ImErrorInfo error) { final int N = mRemoteListeners.beginBroadcast(); for (int i = 0; i < N; i++) { IChatSessionListener listener = mRemoteListeners.getBroadcastItem(i); try { listener.onChatSessionCreateError(name, error); } catch (RemoteException e) { // The RemoteCallbackList will take care of removing the // dead listeners. } } mRemoteListeners.finishBroadcast(); } } class ChatGroupListenerAdapter implements GroupListener { public void onGroupCreated(ChatGroup group) { } public void onGroupDeleted(ChatGroup group) { closeSession(group); } public void onGroupError(int errorType, String name, ImErrorInfo error) { if (errorType == ERROR_CREATING_GROUP) { mSessionListenerAdapter.notifyChatSessionCreateFailed(name, error); } } public void onJoinedGroup(ChatGroup group) { getChatSessionManager().createChatSession(group,false); } public void onLeftGroup(ChatGroup group) { closeSession(group); } private void closeSession(ChatGroup group) { String address = group.getAddress().getAddress(); IChatSession session = getChatSession(address); if (session != null) { closeChatSession((ChatSessionAdapter) session); } } } }