ConferenceDetailsActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import android.annotation.TargetApi;
  4import android.app.AlertDialog;
  5import android.app.PendingIntent;
  6import android.content.Context;
  7import android.content.DialogInterface;
  8import android.content.IntentSender.SendIntentException;
  9import android.content.res.Configuration;
 10import android.graphics.Bitmap;
 11import android.os.Build;
 12import android.os.Bundle;
 13import android.view.ContextMenu;
 14import android.view.LayoutInflater;
 15import android.view.Menu;
 16import android.view.MenuItem;
 17import android.view.View;
 18import android.view.View.OnClickListener;
 19import android.widget.Button;
 20import android.widget.ImageButton;
 21import android.widget.ImageView;
 22import android.widget.LinearLayout;
 23import android.widget.TableLayout;
 24import android.widget.TextView;
 25import android.widget.Toast;
 26
 27import org.openintents.openpgp.util.OpenPgpUtils;
 28
 29import java.util.ArrayList;
 30import java.util.Collections;
 31import java.util.Comparator;
 32
 33import eu.siacs.conversations.Config;
 34import eu.siacs.conversations.R;
 35import eu.siacs.conversations.crypto.PgpEngine;
 36import eu.siacs.conversations.entities.Account;
 37import eu.siacs.conversations.entities.Bookmark;
 38import eu.siacs.conversations.entities.Contact;
 39import eu.siacs.conversations.entities.Conversation;
 40import eu.siacs.conversations.entities.MucOptions;
 41import eu.siacs.conversations.entities.MucOptions.User;
 42import eu.siacs.conversations.services.XmppConnectionService;
 43import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate;
 44import eu.siacs.conversations.services.XmppConnectionService.OnMucRosterUpdate;
 45import eu.siacs.conversations.utils.UIHelper;
 46import eu.siacs.conversations.xmpp.jid.Jid;
 47
 48public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged, XmppConnectionService.OnConferenceOptionsPushed {
 49	public static final String ACTION_VIEW_MUC = "view_muc";
 50	private Conversation mConversation;
 51	private OnClickListener inviteListener = new OnClickListener() {
 52
 53		@Override
 54		public void onClick(View v) {
 55			inviteToConversation(mConversation);
 56		}
 57	};
 58	private LinearLayout mMainLayout;
 59	private TextView mYourNick;
 60	private ImageView mYourPhoto;
 61	private ImageButton mEditNickButton;
 62	private TextView mRoleAffiliaton;
 63	private TextView mFullJid;
 64	private TextView mAccountJid;
 65	private LinearLayout membersView;
 66	private LinearLayout mMoreDetails;
 67	private TextView mConferenceType;
 68	private TableLayout mConferenceInfoTable;
 69	private TextView mConferenceInfoMam;
 70	private ImageButton mChangeConferenceSettingsButton;
 71	private Button mInviteButton;
 72	private String uuid = null;
 73	private User mSelectedUser = null;
 74
 75	private boolean mAdvancedMode = false;
 76
 77	private UiCallback<Conversation> renameCallback = new UiCallback<Conversation>() {
 78		@Override
 79		public void success(Conversation object) {
 80			runOnUiThread(new Runnable() {
 81				@Override
 82				public void run() {
 83					Toast.makeText(ConferenceDetailsActivity.this,getString(R.string.your_nick_has_been_changed),Toast.LENGTH_SHORT).show();
 84					updateView();
 85				}
 86			});
 87
 88		}
 89
 90		@Override
 91		public void error(final int errorCode, Conversation object) {
 92			runOnUiThread(new Runnable() {
 93				@Override
 94				public void run() {
 95					Toast.makeText(ConferenceDetailsActivity.this,getString(errorCode),Toast.LENGTH_SHORT).show();
 96				}
 97			});
 98		}
 99
100		@Override
101		public void userInputRequried(PendingIntent pi, Conversation object) {
102
103		}
104	};
105	private OnClickListener mChangeConferenceSettings = new OnClickListener() {
106		@Override
107		public void onClick(View v) {
108			final MucOptions mucOptions = mConversation.getMucOptions();
109			AlertDialog.Builder builder = new AlertDialog.Builder(ConferenceDetailsActivity.this);
110			builder.setTitle(R.string.conference_options);
111			final String[] options;
112			final boolean[] values;
113			if (mAdvancedMode) {
114				options = new String[]{
115						getString(R.string.members_only),
116						getString(R.string.moderated),
117						getString(R.string.non_anonymous)
118				};
119				values = new boolean[]{
120						mucOptions.membersOnly(),
121						mucOptions.moderated(),
122						mucOptions.nonanonymous()
123				};
124			} else {
125				options = new String[]{
126						getString(R.string.members_only),
127						getString(R.string.non_anonymous)
128				};
129				values = new boolean[]{
130						mucOptions.membersOnly(),
131						mucOptions.nonanonymous()
132				};
133			}
134			builder.setMultiChoiceItems(options,values,new DialogInterface.OnMultiChoiceClickListener() {
135				@Override
136				public void onClick(DialogInterface dialog, int which, boolean isChecked) {
137					values[which] = isChecked;
138				}
139			});
140			builder.setNegativeButton(R.string.cancel, null);
141			builder.setPositiveButton(R.string.confirm,new DialogInterface.OnClickListener() {
142				@Override
143				public void onClick(DialogInterface dialog, int which) {
144					if (!mucOptions.membersOnly() && values[0]) {
145						xmppConnectionService.changeAffiliationsInConference(mConversation,
146								MucOptions.Affiliation.NONE,
147								MucOptions.Affiliation.MEMBER);
148					}
149					Bundle options = new Bundle();
150					options.putString("muc#roomconfig_membersonly", values[0] ? "1" : "0");
151					if (values.length == 2) {
152						options.putString("muc#roomconfig_whois", values[1] ? "anyone" : "moderators");
153					} else if (values.length == 3) {
154						options.putString("muc#roomconfig_moderatedroom", values[1] ? "1" : "0");
155						options.putString("muc#roomconfig_whois", values[2] ? "anyone" : "moderators");
156					}
157					options.putString("muc#roomconfig_persistentroom", "1");
158					xmppConnectionService.pushConferenceConfiguration(mConversation,
159							options,
160							ConferenceDetailsActivity.this);
161				}
162			});
163			builder.create().show();
164		}
165	};
166	private OnValueEdited onSubjectEdited = new OnValueEdited() {
167
168		@Override
169		public void onValueEdited(String value) {
170			xmppConnectionService.pushSubjectToConference(mConversation,value);
171		}
172	};
173
174	@Override
175	public void onConversationUpdate() {
176		refreshUi();
177	}
178
179	@Override
180	public void onMucRosterUpdate() {
181		refreshUi();
182	}
183
184	@Override
185	protected void refreshUiReal() {
186		updateView();
187	}
188
189	@Override
190	protected void onCreate(Bundle savedInstanceState) {
191		super.onCreate(savedInstanceState);
192		setContentView(R.layout.activity_muc_details);
193		mMainLayout = (LinearLayout) findViewById(R.id.muc_main_layout);
194		mYourNick = (TextView) findViewById(R.id.muc_your_nick);
195		mYourPhoto = (ImageView) findViewById(R.id.your_photo);
196		mEditNickButton = (ImageButton) findViewById(R.id.edit_nick_button);
197		mFullJid = (TextView) findViewById(R.id.muc_jabberid);
198		membersView = (LinearLayout) findViewById(R.id.muc_members);
199		mAccountJid = (TextView) findViewById(R.id.details_account);
200		mMoreDetails = (LinearLayout) findViewById(R.id.muc_more_details);
201		mMoreDetails.setVisibility(View.GONE);
202		mChangeConferenceSettingsButton = (ImageButton) findViewById(R.id.change_conference_button);
203		mChangeConferenceSettingsButton.setOnClickListener(this.mChangeConferenceSettings);
204		mInviteButton = (Button) findViewById(R.id.invite);
205		mInviteButton.setOnClickListener(inviteListener);
206		mConferenceType = (TextView) findViewById(R.id.muc_conference_type);
207		if (getActionBar() != null) {
208			getActionBar().setHomeButtonEnabled(true);
209			getActionBar().setDisplayHomeAsUpEnabled(true);
210		}
211		mEditNickButton.setOnClickListener(new OnClickListener() {
212
213			@Override
214			public void onClick(View v) {
215				quickEdit(mConversation.getMucOptions().getActualNick(),
216						new OnValueEdited() {
217
218							@Override
219							public void onValueEdited(String value) {
220								xmppConnectionService.renameInMuc(mConversation,value,renameCallback);
221							}
222						});
223			}
224		});
225		this.mAdvancedMode = getPreferences().getBoolean("advanced_muc_mode", false);
226		this.mConferenceInfoTable = (TableLayout) findViewById(R.id.muc_info_more);
227		mConferenceInfoTable.setVisibility(this.mAdvancedMode ? View.VISIBLE : View.GONE);
228		this.mConferenceInfoMam = (TextView) findViewById(R.id.muc_info_mam);
229	}
230
231	@Override
232	public boolean onOptionsItemSelected(MenuItem menuItem) {
233		switch (menuItem.getItemId()) {
234			case android.R.id.home:
235				finish();
236				break;
237			case R.id.action_edit_subject:
238				if (mConversation != null) {
239					quickEdit(mConversation.getName(),this.onSubjectEdited);
240				}
241				break;
242			case R.id.action_save_as_bookmark:
243				saveAsBookmark();
244				break;
245			case R.id.action_delete_bookmark:
246				deleteBookmark();
247				break;
248			case R.id.action_advanced_mode:
249				this.mAdvancedMode = !menuItem.isChecked();
250				menuItem.setChecked(this.mAdvancedMode);
251				getPreferences().edit().putBoolean("advanced_muc_mode", mAdvancedMode).commit();
252				mConferenceInfoTable.setVisibility(this.mAdvancedMode ? View.VISIBLE : View.GONE);
253				invalidateOptionsMenu();
254				updateView();
255				break;
256		}
257		return super.onOptionsItemSelected(menuItem);
258	}
259
260	@Override
261	protected String getShareableUri() {
262		if (mConversation != null) {
263			return "xmpp:" + mConversation.getJid().toBareJid().toString() + "?join";
264		} else {
265			return "";
266		}
267	}
268
269	@Override
270	public boolean onPrepareOptionsMenu(Menu menu) {
271		MenuItem menuItemSaveBookmark = menu.findItem(R.id.action_save_as_bookmark);
272		MenuItem menuItemDeleteBookmark = menu.findItem(R.id.action_delete_bookmark);
273		MenuItem menuItemAdvancedMode = menu.findItem(R.id.action_advanced_mode);
274		menuItemAdvancedMode.setChecked(mAdvancedMode);
275		if (mConversation == null) {
276			return true;
277		}
278		Account account = mConversation.getAccount();
279		if (account.hasBookmarkFor(mConversation.getJid().toBareJid())) {
280			menuItemSaveBookmark.setVisible(false);
281			menuItemDeleteBookmark.setVisible(true);
282		} else {
283			menuItemDeleteBookmark.setVisible(false);
284			menuItemSaveBookmark.setVisible(true);
285		}
286		return true;
287	}
288
289	@Override
290	public boolean onCreateOptionsMenu(Menu menu) {
291		getMenuInflater().inflate(R.menu.muc_details, menu);
292		return true;
293	}
294
295	@Override
296	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
297		Object tag = v.getTag();
298		if (tag instanceof User) {
299			getMenuInflater().inflate(R.menu.muc_details_context,menu);
300			final User user = (User) tag;
301			final User self = mConversation.getMucOptions().getSelf();
302			this.mSelectedUser = user;
303			String name;
304			final Contact contact = user.getContact();
305			if (contact != null) {
306				name = contact.getDisplayName();
307			} else if (user.getJid() != null){
308				name = user.getJid().toBareJid().toString();
309			} else {
310				name = user.getName();
311			}
312			menu.setHeaderTitle(name);
313			if (user.getJid() != null) {
314				MenuItem showContactDetails = menu.findItem(R.id.action_contact_details);
315				MenuItem startConversation = menu.findItem(R.id.start_conversation);
316				MenuItem giveMembership = menu.findItem(R.id.give_membership);
317				MenuItem removeMembership = menu.findItem(R.id.remove_membership);
318				MenuItem giveAdminPrivileges = menu.findItem(R.id.give_admin_privileges);
319				MenuItem removeAdminPrivileges = menu.findItem(R.id.remove_admin_privileges);
320				MenuItem removeFromRoom = menu.findItem(R.id.remove_from_room);
321				MenuItem banFromConference = menu.findItem(R.id.ban_from_conference);
322				startConversation.setVisible(true);
323				if (contact != null) {
324					showContactDetails.setVisible(true);
325				}
326				if (self.getAffiliation().ranks(MucOptions.Affiliation.ADMIN) &&
327						self.getAffiliation().outranks(user.getAffiliation())) {
328					if (mAdvancedMode) {
329						if (user.getAffiliation() == MucOptions.Affiliation.NONE) {
330							giveMembership.setVisible(true);
331						} else {
332							removeMembership.setVisible(true);
333						}
334						banFromConference.setVisible(true);
335					} else {
336						removeFromRoom.setVisible(true);
337					}
338					if (user.getAffiliation() != MucOptions.Affiliation.ADMIN) {
339						giveAdminPrivileges.setVisible(true);
340					} else {
341						removeAdminPrivileges.setVisible(true);
342					}
343				}
344			} else {
345				MenuItem sendPrivateMessage = menu.findItem(R.id.send_private_message);
346				sendPrivateMessage.setVisible(true);
347			}
348
349		}
350		super.onCreateContextMenu(menu, v, menuInfo);
351	}
352
353	@Override
354	public boolean onContextItemSelected(MenuItem item) {
355		switch (item.getItemId()) {
356			case R.id.action_contact_details:
357				Contact contact = mSelectedUser.getContact();
358				if (contact != null) {
359					switchToContactDetails(contact);
360				}
361				return true;
362			case R.id.start_conversation:
363				startConversation(mSelectedUser);
364				return true;
365			case R.id.give_admin_privileges:
366				xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.ADMIN,this);
367				return true;
368			case R.id.give_membership:
369				xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.MEMBER,this);
370				return true;
371			case R.id.remove_membership:
372				xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.NONE,this);
373				return true;
374			case R.id.remove_admin_privileges:
375				xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.MEMBER,this);
376				return true;
377			case R.id.remove_from_room:
378				removeFromRoom(mSelectedUser);
379				return true;
380			case R.id.ban_from_conference:
381				xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.OUTCAST,this);
382				xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,this);
383				return true;
384			case R.id.send_private_message:
385				privateMsgInMuc(mConversation,mSelectedUser.getName());
386				return true;
387			default:
388				return super.onContextItemSelected(item);
389		}
390	}
391
392	private void removeFromRoom(final User user) {
393		if (mConversation.getMucOptions().membersOnly()) {
394			xmppConnectionService.changeAffiliationInConference(mConversation,user.getJid(), MucOptions.Affiliation.NONE,this);
395			xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,ConferenceDetailsActivity.this);
396		} else {
397			AlertDialog.Builder builder = new AlertDialog.Builder(this);
398			builder.setTitle(R.string.ban_from_conference);
399			builder.setMessage(getString(R.string.removing_from_public_conference,user.getName()));
400			builder.setNegativeButton(R.string.cancel,null);
401			builder.setPositiveButton(R.string.ban_now,new DialogInterface.OnClickListener() {
402				@Override
403				public void onClick(DialogInterface dialog, int which) {
404					xmppConnectionService.changeAffiliationInConference(mConversation,user.getJid(), MucOptions.Affiliation.OUTCAST,ConferenceDetailsActivity.this);
405					xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,ConferenceDetailsActivity.this);
406				}
407			});
408			builder.create().show();
409		}
410	}
411
412	protected void startConversation(User user) {
413		if (user.getJid() != null) {
414			Conversation conversation = xmppConnectionService.findOrCreateConversation(this.mConversation.getAccount(),user.getJid().toBareJid(),false);
415			switchToConversation(conversation);
416		}
417	}
418
419	protected void saveAsBookmark() {
420		Account account = mConversation.getAccount();
421		Bookmark bookmark = new Bookmark(account, mConversation.getJid().toBareJid());
422		if (!mConversation.getJid().isBareJid()) {
423			bookmark.setNick(mConversation.getJid().getResourcepart());
424		}
425		bookmark.setAutojoin(true);
426		account.getBookmarks().add(bookmark);
427		xmppConnectionService.pushBookmarks(account);
428		mConversation.setBookmark(bookmark);
429	}
430
431	protected void deleteBookmark() {
432		Account account = mConversation.getAccount();
433		Bookmark bookmark = mConversation.getBookmark();
434		bookmark.unregisterConversation();
435		account.getBookmarks().remove(bookmark);
436		xmppConnectionService.pushBookmarks(account);
437	}
438
439	@Override
440	void onBackendConnected() {
441		if (mPendingConferenceInvite != null) {
442			mPendingConferenceInvite.execute(this);
443			mPendingConferenceInvite = null;
444		}
445		if (getIntent().getAction().equals(ACTION_VIEW_MUC)) {
446			this.uuid = getIntent().getExtras().getString("uuid");
447		}
448		if (uuid != null) {
449			this.mConversation = xmppConnectionService
450				.findConversationByUuid(uuid);
451			if (this.mConversation != null) {
452				updateView();
453			}
454		}
455	}
456
457	@Override
458	public void onConfigurationChanged (Configuration newConfig) {
459		super.onConfigurationChanged(newConfig);
460		UIHelper.resetChildMargins(mMainLayout);
461	}
462
463	private void updateView() {
464		final MucOptions mucOptions = mConversation.getMucOptions();
465		final User self = mucOptions.getSelf();
466		String account;
467		if (Config.DOMAIN_LOCK != null) {
468			account = mConversation.getAccount().getJid().getLocalpart();
469		} else {
470			account = mConversation.getAccount().getJid().toBareJid().toString();
471		}
472		mAccountJid.setText(getString(R.string.using_account, account));
473		mYourPhoto.setImageBitmap(avatarService().get(mConversation.getAccount(), getPixel(48)));
474		setTitle(mConversation.getName());
475		mFullJid.setText(mConversation.getJid().toBareJid().toString());
476		mYourNick.setText(mucOptions.getActualNick());
477		mRoleAffiliaton = (TextView) findViewById(R.id.muc_role);
478		if (mucOptions.online()) {
479			mMoreDetails.setVisibility(View.VISIBLE);
480			final String status = getStatus(self);
481			if (status != null) {
482				mRoleAffiliaton.setVisibility(View.VISIBLE);
483				mRoleAffiliaton.setText(status);
484			} else {
485				mRoleAffiliaton.setVisibility(View.GONE);
486			}
487			if (mucOptions.membersOnly()) {
488				mConferenceType.setText(R.string.private_conference);
489			} else {
490				mConferenceType.setText(R.string.public_conference);
491			}
492			if (mucOptions.mamSupport()) {
493				mConferenceInfoMam.setText(R.string.server_info_available);
494			} else {
495				mConferenceInfoMam.setText(R.string.server_info_unavailable);
496			}
497			if (self.getAffiliation().ranks(MucOptions.Affiliation.OWNER)) {
498				mChangeConferenceSettingsButton.setVisibility(View.VISIBLE);
499			} else {
500				mChangeConferenceSettingsButton.setVisibility(View.GONE);
501			}
502		}
503		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
504		membersView.removeAllViews();
505		final ArrayList<User> users = new ArrayList<>();
506		users.addAll(mConversation.getMucOptions().getUsers());
507		Collections.sort(users,new Comparator<User>() {
508			@Override
509			public int compare(User lhs, User rhs) {
510				return lhs.getName().compareToIgnoreCase(rhs.getName());
511			}
512		});
513		for (final User user : users) {
514			View view = inflater.inflate(R.layout.contact, membersView,false);
515			this.setListItemBackgroundOnView(view);
516			view.setOnClickListener(new OnClickListener() {
517				@Override
518				public void onClick(View view) {
519					highlightInMuc(mConversation, user.getName());
520				}
521			});
522			registerForContextMenu(view);
523			view.setTag(user);
524			TextView tvDisplayName = (TextView) view.findViewById(R.id.contact_display_name);
525			TextView tvKey = (TextView) view.findViewById(R.id.key);
526			TextView tvStatus = (TextView) view.findViewById(R.id.contact_jid);
527			if (mAdvancedMode && user.getPgpKeyId() != 0) {
528				tvKey.setVisibility(View.VISIBLE);
529				tvKey.setOnClickListener(new OnClickListener() {
530
531					@Override
532					public void onClick(View v) {
533						viewPgpKey(user);
534					}
535				});
536				tvKey.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId()));
537			}
538			Bitmap bm;
539			Contact contact = user.getContact();
540			if (contact != null) {
541				bm = avatarService().get(contact, getPixel(48));
542				tvDisplayName.setText(contact.getDisplayName());
543				tvStatus.setText(user.getName() + " \u2022 " + getStatus(user));
544			} else {
545				bm = avatarService().get(user.getName(), getPixel(48));
546				tvDisplayName.setText(user.getName());
547				tvStatus.setText(getStatus(user));
548
549			}
550			ImageView iv = (ImageView) view.findViewById(R.id.contact_photo);
551			iv.setImageBitmap(bm);
552			membersView.addView(view);
553			if (mConversation.getMucOptions().canInvite()) {
554				mInviteButton.setVisibility(View.VISIBLE);
555			} else {
556				mInviteButton.setVisibility(View.GONE);
557			}
558		}
559	}
560
561	private String getStatus(User user) {
562		if (mAdvancedMode) {
563			StringBuilder builder = new StringBuilder();
564			builder.append(getString(user.getAffiliation().getResId()));
565			builder.append(" (");
566			builder.append(getString(user.getRole().getResId()));
567			builder.append(')');
568			return builder.toString();
569		} else {
570			return getString(user.getAffiliation().getResId());
571		}
572	}
573
574	@SuppressWarnings("deprecation")
575	@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
576	private void setListItemBackgroundOnView(View view) {
577		int sdk = android.os.Build.VERSION.SDK_INT;
578		if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
579			view.setBackgroundDrawable(getResources().getDrawable(R.drawable.greybackground));
580		} else {
581			view.setBackground(getResources().getDrawable(R.drawable.greybackground));
582		}
583	}
584
585	private void viewPgpKey(User user) {
586		PgpEngine pgp = xmppConnectionService.getPgpEngine();
587		if (pgp != null) {
588			PendingIntent intent = pgp.getIntentForKey(
589					mConversation.getAccount(), user.getPgpKeyId());
590			if (intent != null) {
591				try {
592					startIntentSenderForResult(intent.getIntentSender(), 0,
593							null, 0, 0, 0);
594				} catch (SendIntentException ignored) {
595
596				}
597			}
598		}
599	}
600
601	@Override
602	public void onAffiliationChangedSuccessful(Jid jid) {
603
604	}
605
606	@Override
607	public void onAffiliationChangeFailed(Jid jid, int resId) {
608		displayToast(getString(resId,jid.toBareJid().toString()));
609	}
610
611	@Override
612	public void onRoleChangedSuccessful(String nick) {
613
614	}
615
616	@Override
617	public void onRoleChangeFailed(String nick, int resId) {
618		displayToast(getString(resId,nick));
619	}
620
621	@Override
622	public void onPushSucceeded() {
623		displayToast(getString(R.string.modified_conference_options));
624	}
625
626	@Override
627	public void onPushFailed() {
628		displayToast(getString(R.string.could_not_modify_conference_options));
629	}
630
631	private void displayToast(final String msg) {
632		runOnUiThread(new Runnable() {
633			@Override
634			public void run() {
635				Toast.makeText(ConferenceDetailsActivity.this,msg,Toast.LENGTH_SHORT).show();
636			}
637		});
638	}
639}