1package de.gultsch.chat.services;
2
3import java.util.Hashtable;
4import java.util.List;
5
6
7import de.gultsch.chat.entities.Account;
8import de.gultsch.chat.entities.Contact;
9import de.gultsch.chat.entities.Conversation;
10import de.gultsch.chat.entities.Message;
11import de.gultsch.chat.persistance.DatabaseBackend;
12import de.gultsch.chat.ui.OnConversationListChangedListener;
13import de.gultsch.chat.xmpp.MessagePacket;
14import de.gultsch.chat.xmpp.OnMessagePacketReceived;
15import de.gultsch.chat.xmpp.XmppConnection;
16import android.app.Service;
17import android.content.Context;
18import android.content.Intent;
19import android.os.Binder;
20import android.os.IBinder;
21import android.os.PowerManager;
22import android.util.Log;
23
24public class XmppConnectionService extends Service {
25
26 protected static final String LOGTAG = "xmppService";
27 protected DatabaseBackend databaseBackend;
28
29 public long startDate;
30
31 private List<Account> accounts;
32 private List<Conversation> conversations = null;
33
34 private Hashtable<Account,XmppConnection> connections = new Hashtable<Account, XmppConnection>();
35
36 private OnConversationListChangedListener convChangedListener = null;
37
38 private final IBinder mBinder = new XmppConnectionBinder();
39 private OnMessagePacketReceived messageListener = new OnMessagePacketReceived() {
40
41 @Override
42 public void onMessagePacketReceived(Account account, MessagePacket packet) {
43 String fullJid = packet.getFrom();
44 String jid = fullJid.split("/")[0];
45 String name = jid.split("@")[0];
46 Log.d(LOGTAG,"message received for "+account.getJid()+" from "+jid);
47 Log.d(LOGTAG,packet.toString());
48 Contact contact = new Contact(name,jid,null); //dummy contact
49 Conversation conversation = findOrCreateConversation(account, contact);
50 Message message = new Message(conversation, fullJid, packet.getBody(), Message.ENCRYPTION_NONE, Message.STATUS_RECIEVED);
51 conversation.getMessages().add(message);
52 databaseBackend.createMessage(message);
53 if (convChangedListener != null) {
54 convChangedListener.onConversationListChanged();
55 }
56 }
57 };
58
59 public class XmppConnectionBinder extends Binder {
60 public XmppConnectionService getService() {
61 return XmppConnectionService.this;
62 }
63 }
64
65 @Override
66 public int onStartCommand(Intent intent, int flags, int startId) {
67 PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
68 for(Account account : accounts) {
69 if (!connections.containsKey(account)) {
70 XmppConnection connection = new XmppConnection(account, pm);
71 connection.setOnMessagePacketReceivedListener(this.messageListener );
72 Thread thread = new Thread(connection);
73 thread.start();
74 this.connections.put(account, connection);
75 }
76 }
77 return START_STICKY;
78 }
79
80 @Override
81 public void onCreate() {
82 databaseBackend = DatabaseBackend.getInstance(getApplicationContext());
83 this.accounts = databaseBackend.getAccounts();
84 }
85
86 @Override
87 public IBinder onBind(Intent intent) {
88 return mBinder;
89 }
90
91 public void sendMessage(Message message) {
92 databaseBackend.createMessage(message);
93 }
94
95 public void addConversation(Conversation conversation) {
96 databaseBackend.createConversation(conversation);
97 }
98
99 public List<Conversation> getConversations() {
100 if (this.conversations == null) {
101 Hashtable<String, Account> accountLookupTable = new Hashtable<String, Account>();
102 for(Account account : this.accounts) {
103 accountLookupTable.put(account.getUuid(), account);
104 }
105 this.conversations = databaseBackend.getConversations(Conversation.STATUS_AVAILABLE);
106 for(Conversation conv : this.conversations) {
107 conv.setAccount(accountLookupTable.get(conv.getAccountUuid()));
108 }
109 }
110 return this.conversations;
111 }
112
113 public List<Account> getAccounts() {
114 return databaseBackend.getAccounts();
115 }
116
117 public List<Message> getMessages(Conversation conversation) {
118 return databaseBackend.getMessages(conversation, 100);
119 }
120
121 public Conversation findOrCreateConversation(Account account, Contact contact) {
122 Log.d(LOGTAG,"was asked to find conversation for "+contact.getJid());
123 for(Conversation conv : this.getConversations()) {
124 if ((conv.getAccount().equals(account))&&(conv.getContactJid().equals(contact.getJid()))) {
125 Log.d(LOGTAG,"found one in memory");
126 return conv;
127 }
128 }
129 Conversation conversation = databaseBackend.findConversation(account, contact.getJid());
130 if (conversation!=null) {
131 Log.d("gultsch","found one. unarchive it");
132 conversation.setStatus(Conversation.STATUS_AVAILABLE);
133 conversation.setAccount(account);
134 this.databaseBackend.updateConversation(conversation);
135 } else {
136 Log.d(LOGTAG,"didnt find one in archive. create new one");
137 conversation = new Conversation(contact.getDisplayName(), contact.getProfilePhoto(), account, contact.getJid());
138 this.databaseBackend.createConversation(conversation);
139 }
140 this.conversations.add(conversation);
141 if (this.convChangedListener != null) {
142 this.convChangedListener.onConversationListChanged();
143 }
144 return conversation;
145 }
146
147 public void archiveConversation(Conversation conversation) {
148 this.databaseBackend.updateConversation(conversation);
149 this.conversations.remove(conversation);
150 if (this.convChangedListener != null) {
151 this.convChangedListener.onConversationListChanged();
152 }
153 }
154
155 public int getConversationCount() {
156 return this.databaseBackend.getConversationCount();
157 }
158
159 public void createAccount(Account account) {
160 databaseBackend.createAccount(account);
161 }
162
163 public void updateAccount(Account account) {
164 databaseBackend.updateAccount(account);
165 }
166
167 public void deleteAccount(Account account) {
168 databaseBackend.deleteAccount(account);
169 }
170
171 public void setOnConversationListChangedListener(OnConversationListChangedListener listener) {
172 this.convChangedListener = listener;
173 }
174
175 public void removeOnConversationListChangedListener() {
176 this.convChangedListener = null;
177 }
178}