aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/de/gultsch/chat/entities/Contact.java60
-rw-r--r--src/de/gultsch/chat/persistance/DatabaseBackend.java2
-rw-r--r--src/de/gultsch/chat/services/XmppConnectionService.java78
-rw-r--r--src/de/gultsch/chat/ui/DialogContactDetails.java93
4 files changed, 199 insertions, 34 deletions
diff --git a/src/de/gultsch/chat/entities/Contact.java b/src/de/gultsch/chat/entities/Contact.java
index eff46e53b..a01e20b0a 100644
--- a/src/de/gultsch/chat/entities/Contact.java
+++ b/src/de/gultsch/chat/entities/Contact.java
@@ -9,6 +9,8 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import de.gultsch.chat.xml.Element;
+
import android.content.ContentValues;
import android.database.Cursor;
@@ -29,7 +31,7 @@ public class Contact extends AbstractEntity implements Serializable {
protected String accountUuid;
protected String displayName;
protected String jid;
- protected String subscription;
+ protected int subscription = 0;
protected String systemAccount;
protected String photoUri;
protected JSONObject keys = new JSONObject();
@@ -52,7 +54,7 @@ public class Contact extends AbstractEntity implements Serializable {
}
public Contact(String uuid, String account, String displayName, String jid,
- String subscription, String photoUri, String systemAccount,
+ int subscription, String photoUri, String systemAccount,
String keys, String presences) {
this.uuid = uuid;
this.accountUuid = account;
@@ -109,18 +111,14 @@ public class Contact extends AbstractEntity implements Serializable {
cursor.getString(cursor.getColumnIndex(ACCOUNT)),
cursor.getString(cursor.getColumnIndex(DISPLAYNAME)),
cursor.getString(cursor.getColumnIndex(JID)),
- cursor.getString(cursor.getColumnIndex(SUBSCRIPTION)),
+ cursor.getInt(cursor.getColumnIndex(SUBSCRIPTION)),
cursor.getString(cursor.getColumnIndex(PHOTOURI)),
cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)),
cursor.getString(cursor.getColumnIndex(KEYS)),
cursor.getString(cursor.getColumnIndex(PRESENCES)));
}
-
- public void setSubscription(String subscription) {
- this.subscription = subscription;
- }
-
- public String getSubscription() {
+
+ public int getSubscription() {
return this.subscription;
}
@@ -220,4 +218,48 @@ public class Contact extends AbstractEntity implements Serializable {
}
}
+
+ public void setSubscriptionOption(int option) {
+ this.subscription |= 1 << option;
+ }
+
+ public void resetSubscriptionOption(int option) {
+ this.subscription &= ~(1 << option);
+ }
+
+ public boolean getSubscriptionOption(int option) {
+ return ((this.subscription & (1 << option)) != 0);
+ }
+
+ public void parseSubscriptionFromElement(Element item) {
+ String ask = item.getAttribute("ask");
+ String subscription = item.getAttribute("subscription");
+
+ if (subscription!=null) {
+ if (subscription.equals("to")) {
+ this.resetSubscriptionOption(Contact.Subscription.FROM);
+ this.setSubscriptionOption(Contact.Subscription.TO);
+ } else if (subscription.equals("from")) {
+ this.resetSubscriptionOption(Contact.Subscription.TO);
+ this.setSubscriptionOption(Contact.Subscription.FROM);
+ } else if (subscription.equals("both")) {
+ this.setSubscriptionOption(Contact.Subscription.TO);
+ this.setSubscriptionOption(Contact.Subscription.FROM);
+ }
+ }
+
+ if ((ask!=null)&&(ask.equals("subscribe"))) {
+ this.setSubscriptionOption(Contact.Subscription.ASKING);
+ } else {
+ this.resetSubscriptionOption(Contact.Subscription.ASKING);
+ }
+ }
+
+
+ public class Subscription {
+ public static final int TO = 0;
+ public static final int FROM = 1;
+ public static final int ASKING = 2;
+ public static final int PREEMPTIVE_GRANT = 4;
+ }
}
diff --git a/src/de/gultsch/chat/persistance/DatabaseBackend.java b/src/de/gultsch/chat/persistance/DatabaseBackend.java
index caee4e8f6..18fad7c42 100644
--- a/src/de/gultsch/chat/persistance/DatabaseBackend.java
+++ b/src/de/gultsch/chat/persistance/DatabaseBackend.java
@@ -58,7 +58,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
+ Contact.DISPLAYNAME + " TEXT," + Contact.JID + " TEXT,"
+ Contact.PRESENCES + " TEXT, " + Contact.KEYS
+ " TEXT," + Contact.PHOTOURI + " TEXT," + Contact.SUBSCRIPTION
- + " TEXT," + Contact.SYSTEMACCOUNT + " NUMBER, "
+ + " NUMBER," + Contact.SYSTEMACCOUNT + " NUMBER, "
+ "FOREIGN KEY(" + Contact.ACCOUNT + ") REFERENCES "
+ Account.TABLENAME + "(" + Account.UUID
+ ") ON DELETE CASCADE);");
diff --git a/src/de/gultsch/chat/services/XmppConnectionService.java b/src/de/gultsch/chat/services/XmppConnectionService.java
index 2bff2af42..a3e5d7cd7 100644
--- a/src/de/gultsch/chat/services/XmppConnectionService.java
+++ b/src/de/gultsch/chat/services/XmppConnectionService.java
@@ -200,6 +200,20 @@ public class XmppConnectionService extends Service {
contact.removePresence(fromParts[1]);
databaseBackend.updateContact(contact);
}
+ } else if (type.equals("subscribe")) {
+ Log.d(LOGTAG,account.getJid()+": "+contact.getJid()+" asked to subscribe");
+ if (contact.getSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT)) {
+ Log.d(LOGTAG,"preemptive grant existed. granting");
+ sendPresenceUpdatesTo(contact);
+ contact.setSubscriptionOption(Contact.Subscription.FROM);
+ contact.resetSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT);
+ replaceContactInConversation(contact.getJid(), contact);
+ databaseBackend.updateContact(contact);
+ } else {
+ //TODO: ask user to handle it maybe
+ }
+ } else {
+ Log.d(LOGTAG,packet.toString());
}
replaceContactInConversation(contact.getJid(),contact);
}
@@ -227,19 +241,21 @@ public class XmppConnectionService extends Service {
String subscription = item.getAttribute("subscription");
Contact contact = databaseBackend.findContact(account, jid);
if (contact == null) {
- String name = item.getAttribute("name");
- if (name == null) {
- name = jid.split("@")[0];
+ if (!subscription.equals("remove")) {
+ String name = item.getAttribute("name");
+ if (name == null) {
+ name = jid.split("@")[0];
+ }
+ contact = new Contact(account, name, jid, null);
+ contact.parseSubscriptionFromElement(item);
+ databaseBackend.createContact(contact);
}
- contact = new Contact(account, name, jid, null);
- contact.setSubscription(subscription);
- databaseBackend.createContact(contact);
} else {
if (subscription.equals("remove")) {
databaseBackend.deleteContact(contact);
replaceContactInConversation(contact.getJid(), null);
} else {
- contact.setSubscription(subscription);
+ contact.parseSubscriptionFromElement(item);
databaseBackend.updateContact(contact);
replaceContactInConversation(contact.getJid(),contact);
}
@@ -506,12 +522,14 @@ public class XmppConnectionService extends Service {
contact.setDisplayName(phoneContact
.getString("displayname"));
databaseBackend.updateContact(contact);
+ replaceContactInConversation(contact.getJid(), contact);
} else {
if ((contact.getSystemAccount() != null)
|| (contact.getProfilePhoto() != null)) {
contact.setSystemAccount(null);
contact.setPhotoUri(null);
databaseBackend.updateContact(contact);
+ replaceContactInConversation(contact.getJid(), contact);
}
}
}
@@ -545,7 +563,11 @@ public class XmppConnectionService extends Service {
}
public Contact findContact(Account account, String jid) {
- return databaseBackend.findContact(account, jid);
+ Contact contact = databaseBackend.findContact(account, jid);
+ if (contact!=null) {
+ contact.setAccount(account);
+ }
+ return contact;
}
public Conversation findOrCreateConversation(Account account, String jid,
@@ -766,4 +788,44 @@ public class XmppConnectionService extends Service {
replaceContactInConversation(contact.getJid(), contact);
databaseBackend.createContact(contact);
}
+
+ public void requestPresenceUpdatesFrom(Contact contact) {
+ //Requesting a Subscription type=subscribe
+ PresencePacket packet = new PresencePacket();
+ packet.setAttribute("type", "subscribe");
+ packet.setAttribute("to", contact.getJid());
+ packet.setAttribute("from",contact.getAccount().getJid());
+ Log.d(LOGTAG,packet.toString());
+ contact.getAccount().getXmppConnection().sendPresencePacket(packet);
+ }
+
+ public void stopPresenceUpdatesFrom(Contact contact) {
+ //Unsubscribing type='unsubscribe'
+ PresencePacket packet = new PresencePacket();
+ packet.setAttribute("type", "unsubscribe");
+ packet.setAttribute("to", contact.getJid());
+ packet.setAttribute("from",contact.getAccount().getJid());
+ Log.d(LOGTAG,packet.toString());
+ contact.getAccount().getXmppConnection().sendPresencePacket(packet);
+ }
+
+ public void stopPresenceUpdatesTo(Contact contact) {
+ //Canceling a Subscription type=unsubscribed
+ PresencePacket packet = new PresencePacket();
+ packet.setAttribute("type", "unsubscribed");
+ packet.setAttribute("to", contact.getJid());
+ packet.setAttribute("from",contact.getAccount().getJid());
+ Log.d(LOGTAG,packet.toString());
+ contact.getAccount().getXmppConnection().sendPresencePacket(packet);
+ }
+
+ public void sendPresenceUpdatesTo(Contact contact) {
+ //type='subscribed'
+ PresencePacket packet = new PresencePacket();
+ packet.setAttribute("type", "subscribed");
+ packet.setAttribute("to", contact.getJid());
+ packet.setAttribute("from",contact.getAccount().getJid());
+ Log.d(LOGTAG,packet.toString());
+ contact.getAccount().getXmppConnection().sendPresencePacket(packet);
+ }
} \ No newline at end of file
diff --git a/src/de/gultsch/chat/ui/DialogContactDetails.java b/src/de/gultsch/chat/ui/DialogContactDetails.java
index 20be4b397..8983a8730 100644
--- a/src/de/gultsch/chat/ui/DialogContactDetails.java
+++ b/src/de/gultsch/chat/ui/DialogContactDetails.java
@@ -13,6 +13,7 @@ import android.os.Bundle;
import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Intents;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -28,6 +29,9 @@ public class DialogContactDetails extends DialogFragment {
private DialogContactDetails mDetailsDialog = this;
private XmppActivity activity;
+ private CheckBox send;
+ private CheckBox receive;
+
private DialogInterface.OnClickListener askRemoveFromRoster = new DialogInterface.OnClickListener() {
@Override
@@ -64,6 +68,58 @@ public class DialogContactDetails extends DialogFragment {
}
};
+ private DialogInterface.OnClickListener updateSubscriptions = new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ boolean needsUpdating = false;
+ if (contact.getSubscriptionOption(Contact.Subscription.FROM)) {
+ if (!send.isChecked()) {
+ contact.resetSubscriptionOption(Contact.Subscription.FROM);
+ contact.resetSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT);
+ activity.xmppConnectionService.stopPresenceUpdatesTo(contact);
+ needsUpdating=true;
+ }
+ } else {
+ if (contact.getSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT)) {
+ if (!send.isChecked()) {
+ contact.resetSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT);
+ needsUpdating=true;
+ }
+ } else {
+ if (send.isChecked()) {
+ contact.setSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT);
+ needsUpdating=true;
+ }
+ }
+ }
+ if (contact.getSubscriptionOption(Contact.Subscription.TO)) {
+ if (!receive.isChecked()) {
+ contact.resetSubscriptionOption(Contact.Subscription.TO);
+ activity.xmppConnectionService.stopPresenceUpdatesFrom(contact);
+ needsUpdating=true;
+ }
+ } else {
+ if (contact.getSubscriptionOption(Contact.Subscription.ASKING)) {
+ if (!receive.isChecked()) {
+ contact.resetSubscriptionOption(Contact.Subscription.ASKING);
+ activity.xmppConnectionService.stopPresenceUpdatesFrom(contact);
+ needsUpdating=true;
+ }
+ } else {
+ if (receive.isChecked()) {
+ contact.setSubscriptionOption(Contact.Subscription.ASKING);
+ activity.xmppConnectionService.requestPresenceUpdatesFrom(contact);
+ needsUpdating=true;
+ }
+ }
+ }
+ if (needsUpdating) {
+ activity.xmppConnectionService.updateContact(contact);
+ }
+ }
+ };
+
public void setContact(Contact contact) {
this.contact = contact;
}
@@ -77,21 +133,29 @@ public class DialogContactDetails extends DialogFragment {
TextView contactJid = (TextView) view.findViewById(R.id.details_contactjid);
TextView accountJid = (TextView) view.findViewById(R.id.details_account);
TextView status = (TextView) view.findViewById(R.id.details_contactstatus);
- CheckBox send = (CheckBox) view.findViewById(R.id.details_send_presence);
- CheckBox receive = (CheckBox) view.findViewById(R.id.details_receive_presence);
+ send = (CheckBox) view.findViewById(R.id.details_send_presence);
+ receive = (CheckBox) view.findViewById(R.id.details_receive_presence);
//ImageView contactPhoto = (ImageView) view.findViewById(R.id.details_contact_picture);
QuickContactBadge badge = (QuickContactBadge) view.findViewById(R.id.details_contact_badge);
- boolean subscriptionSend = false;
- boolean subscriptionReceive = false;
- if (contact.getSubscription()!=null) {
- if (contact.getSubscription().equals("both")) {
- subscriptionReceive = true;
- subscriptionSend = true;
- } else if (contact.getSubscription().equals("from")) {
- subscriptionSend = true;
- } else if (contact.getSubscription().equals("to")) {
- subscriptionReceive = true;
+ if (contact.getSubscriptionOption(Contact.Subscription.FROM)) {
+ send.setChecked(true);
+ } else {
+ send.setText("Preemptively grant subscription request");
+ if (contact.getSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT)) {
+ send.setChecked(true);
+ } else {
+ send.setChecked(false);
+ }
+ }
+ if (contact.getSubscriptionOption(Contact.Subscription.TO)) {
+ receive.setChecked(true);
+ } else {
+ receive.setText("Request presence updates");
+ if (contact.getSubscriptionOption(Contact.Subscription.ASKING)) {
+ receive.setChecked(true);
+ } else {
+ receive.setChecked(false);
}
}
@@ -125,9 +189,6 @@ public class DialogContactDetails extends DialogFragment {
status.setTextColor(0xFFe92727);
break;
}
-
- send.setChecked(subscriptionSend);
- receive.setChecked(subscriptionReceive);
contactJid.setText(contact.getJid());
accountJid.setText(contact.getAccount().getJid());
@@ -151,7 +212,7 @@ public class DialogContactDetails extends DialogFragment {
builder.setView(view);
builder.setTitle(contact.getDisplayName());
- builder.setNeutralButton("Done", null);
+ builder.setNeutralButton("Done", this.updateSubscriptions);
builder.setPositiveButton("Remove from roster", this.askRemoveFromRoster);
return builder.create();
}