subscription mgmt works

This commit is contained in:
Daniel Gultsch 2014-02-21 21:35:23 +01:00
parent b71bfbaa9d
commit b8e85a2846
4 changed files with 199 additions and 34 deletions

View file

@ -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;
}
}

View file

@ -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);");

View file

@ -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);
}
}

View file

@ -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();
}