1 /* 2 * Copyright (C) 2007-2008 Esmertec AG. 3 * Copyright (C) 2007-2008 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.android.im.service; 19 20 import java.util.ArrayList; 21 import java.util.HashMap; 22 import java.util.List; 23 24 import android.os.RemoteCallbackList; 25 import android.os.RemoteException; 26 27 import com.android.im.IChatSession; 28 import com.android.im.IChatSessionListener; 29 import com.android.im.IChatSessionManager; 30 import com.android.im.engine.Address; 31 import com.android.im.engine.ChatGroup; 32 import com.android.im.engine.ChatGroupManager; 33 import com.android.im.engine.ChatSession; 34 import com.android.im.engine.ChatSessionListener; 35 import com.android.im.engine.ChatSessionManager; 36 import com.android.im.engine.Contact; 37 import com.android.im.engine.GroupListener; 38 import com.android.im.engine.ImConnection; 39 import com.android.im.engine.ImErrorInfo; 40 41 public class ChatSessionManagerAdapter extends IChatSessionManager.Stub { 42 static final String TAG = RemoteImService.TAG; 43 44 ImConnectionAdapter mConnection; 45 ChatSessionManager mSessionManager; 46 ChatGroupManager mGroupManager; 47 HashMap<String, ChatSessionAdapter> mActiveSessions; 48 ChatSessionListenerAdapter mSessionListenerAdapter; 49 final RemoteCallbackList<IChatSessionListener> mRemoteListeners 50 = new RemoteCallbackList<IChatSessionListener>(); 51 ChatSessionManagerAdapter(ImConnectionAdapter connection)52 public ChatSessionManagerAdapter(ImConnectionAdapter connection) { 53 mConnection = connection; 54 ImConnection connAdaptee = connection.getAdaptee(); 55 mSessionManager = connAdaptee.getChatSessionManager(); 56 mActiveSessions = new HashMap<String, ChatSessionAdapter>(); 57 mSessionListenerAdapter = new ChatSessionListenerAdapter(); 58 mSessionManager.addChatSessionListener(mSessionListenerAdapter); 59 60 if((connAdaptee.getCapability() & ImConnection.CAPABILITY_GROUP_CHAT) != 0) { 61 mGroupManager = connAdaptee.getChatGroupManager(); 62 mGroupManager.addGroupListener(new ChatGroupListenerAdpater()); 63 } 64 } 65 createChatSession(String contactAddress)66 public IChatSession createChatSession(String contactAddress) { 67 ContactListManagerAdapter listManager = 68 (ContactListManagerAdapter) mConnection.getContactListManager(); 69 Contact contact = listManager.getContactByAddress(contactAddress); 70 if(contact == null) { 71 try { 72 contact = listManager.createTemporaryContact(contactAddress); 73 } catch (IllegalArgumentException e) { 74 mSessionListenerAdapter.notifyChatSessionCreateFailed(contactAddress, 75 new ImErrorInfo(ImErrorInfo.ILLEGAL_CONTACT_ADDRESS, 76 "Invalid contact address:" + contactAddress)); 77 return null; 78 } 79 } 80 ChatSession session = mSessionManager.createChatSession(contact); 81 return getChatSessionAdapter(session); 82 } 83 closeChatSession(ChatSessionAdapter adapter)84 public void closeChatSession(ChatSessionAdapter adapter) { 85 synchronized (mActiveSessions) { 86 ChatSession session = adapter.getAdaptee(); 87 mSessionManager.closeChatSession(session); 88 mActiveSessions.remove(adapter.getAddress()); 89 } 90 } 91 closeAllChatSessions()92 public void closeAllChatSessions() { 93 synchronized (mActiveSessions) { 94 ArrayList<ChatSessionAdapter> sessions = 95 new ArrayList<ChatSessionAdapter>(mActiveSessions.values()); 96 for (ChatSessionAdapter ses : sessions) { 97 ses.leave(); 98 } 99 } 100 } 101 updateChatSession(String oldAddress, ChatSessionAdapter adapter)102 public void updateChatSession(String oldAddress, ChatSessionAdapter adapter) { 103 synchronized (mActiveSessions) { 104 mActiveSessions.remove(oldAddress); 105 mActiveSessions.put(adapter.getAddress(), adapter); 106 } 107 } 108 getChatSession(String address)109 public IChatSession getChatSession(String address) { 110 synchronized (mActiveSessions) { 111 return mActiveSessions.get(address); 112 } 113 } 114 getActiveChatSessions()115 public List getActiveChatSessions() { 116 synchronized (mActiveSessions) { 117 return new ArrayList<ChatSessionAdapter>(mActiveSessions.values()); 118 } 119 } 120 getChatSessionCount()121 public int getChatSessionCount() { 122 synchronized (mActiveSessions) { 123 return mActiveSessions.size(); 124 } 125 } 126 registerChatSessionListener(IChatSessionListener listener)127 public void registerChatSessionListener(IChatSessionListener listener) { 128 if (listener != null) { 129 mRemoteListeners.register(listener); 130 } 131 } 132 unregisterChatSessionListener(IChatSessionListener listener)133 public void unregisterChatSessionListener(IChatSessionListener listener) { 134 if (listener != null) { 135 mRemoteListeners.unregister(listener); 136 } 137 } 138 getChatSessionAdapter(ChatSession session)139 ChatSessionAdapter getChatSessionAdapter(ChatSession session) { 140 synchronized (mActiveSessions) { 141 Address participantAddress = session.getParticipant().getAddress(); 142 String key = participantAddress.getFullName(); 143 ChatSessionAdapter adapter = mActiveSessions.get(key); 144 if (adapter == null) { 145 adapter = new ChatSessionAdapter(session, mConnection); 146 mActiveSessions.put(key, adapter); 147 } 148 return adapter; 149 } 150 } 151 152 class ChatSessionListenerAdapter implements ChatSessionListener { 153 onChatSessionCreated(ChatSession session)154 public void onChatSessionCreated(ChatSession session) { 155 final IChatSession sessionAdapter = getChatSessionAdapter(session); 156 final int N = mRemoteListeners.beginBroadcast(); 157 for (int i = 0; i < N; i++) { 158 IChatSessionListener listener = mRemoteListeners.getBroadcastItem(i); 159 try { 160 listener.onChatSessionCreated(sessionAdapter); 161 } catch (RemoteException e) { 162 // The RemoteCallbackList will take care of removing the 163 // dead listeners. 164 } 165 } 166 mRemoteListeners.finishBroadcast(); 167 } 168 notifyChatSessionCreateFailed(final String name, final ImErrorInfo error)169 public void notifyChatSessionCreateFailed(final String name, final ImErrorInfo error) { 170 final int N = mRemoteListeners.beginBroadcast(); 171 for (int i = 0; i < N; i++) { 172 IChatSessionListener listener = mRemoteListeners.getBroadcastItem(i); 173 try { 174 listener.onChatSessionCreateError(name, error); 175 } catch (RemoteException e) { 176 // The RemoteCallbackList will take care of removing the 177 // dead listeners. 178 } 179 } 180 mRemoteListeners.finishBroadcast(); 181 } 182 } 183 184 class ChatGroupListenerAdpater implements GroupListener { onGroupCreated(ChatGroup group)185 public void onGroupCreated(ChatGroup group) { 186 } 187 onGroupDeleted(ChatGroup group)188 public void onGroupDeleted(ChatGroup group) { 189 closeSession(group); 190 } 191 onGroupError(int errorType, String name, ImErrorInfo error)192 public void onGroupError(int errorType, String name, ImErrorInfo error) { 193 if(errorType == ERROR_CREATING_GROUP) { 194 mSessionListenerAdapter.notifyChatSessionCreateFailed(name, error); 195 } 196 } 197 onJoinedGroup(ChatGroup group)198 public void onJoinedGroup(ChatGroup group) { 199 mSessionManager.createChatSession(group); 200 } 201 onLeftGroup(ChatGroup group)202 public void onLeftGroup(ChatGroup group) { 203 closeSession(group); 204 } 205 closeSession(ChatGroup group)206 private void closeSession(ChatGroup group) { 207 String address = group.getAddress().getFullName(); 208 IChatSession session = getChatSession(address); 209 if(session != null) { 210 closeChatSession((ChatSessionAdapter) session); 211 } 212 } 213 } 214 } 215