/** * Method fired when "add" button is clicked. * * @param v add button's <tt>View</tt> */ public void onAddClicked(View v) { Spinner accountsSpiner = (Spinner) findViewById(R.id.selectAccountSpinner); Account selectedAcc = (Account) accountsSpiner.getSelectedItem(); if (selectedAcc == null) { logger.error("No account selected"); return; } ProtocolProviderService pps = selectedAcc.getProtocolProvider(); if (pps == null) { logger.error("No provider registered for account " + selectedAcc.getAccountName()); return; } View content = findViewById(android.R.id.content); String contactAddress = ViewUtil.getTextViewValue(content, R.id.editContactName); String displayName = ViewUtil.getTextViewValue(content, R.id.editDisplayName); if (displayName != null && displayName.length() > 0) { addRenameListener(pps, null, contactAddress, displayName); } Spinner groupSpinner = (Spinner) findViewById(R.id.selectGroupSpinner); ContactListUtils.addContact( pps, (MetaContactGroup) groupSpinner.getSelectedItem(), contactAddress); finish(); }
/** Updates Jitsi icon notification to reflect current global status. */ public void updateJitsiIconNotification() { String status; if (getGlobalStatus().isOnline()) { // At least one provider is online status = JitsiApplication.getResString(R.string.service_gui_ONLINE); } else { // There are no active providers so we consider to be in // the offline state status = JitsiApplication.getResString(R.string.service_gui_OFFLINE); } int notificationID = OSGiService.getGeneralNotificationId(); if (notificationID == -1) { logger.debug( "Not displaying status notification because" + " there's no global notification icon available."); return; } AndroidUtils.updateGeneralNotification( JitsiApplication.getGlobalContext(), notificationID, JitsiApplication.getResString(R.string.app_name), status, System.currentTimeMillis()); }
/** * Creates new call to target <tt>destination</tt>. * * @param context the android context * @param destination the target callee name that will be used. */ private static void createCall(Context context, String destination) { Iterator<ProtocolProviderService> allProviders = AccountUtils.getRegisteredProviders().iterator(); if (!allProviders.hasNext()) { logger.error("No registered providers found"); return; } createCall(context, destination, allProviders.next()); }
/** * Checks if there is a call in progress. If true then shows a warning toast and finishes the * activity. * * @param activity activity doing a check. * @return <tt>true</tt> if there is call in progress and <tt>Activity</tt> was finished. */ public static boolean checkCallInProgress(Activity activity) { if (CallManager.getActiveCallsCount() > 0) { logger.warn("Call is in progress"); Toast t = Toast.makeText(activity, R.string.service_gui_WARN_CALL_IN_PROGRESS, Toast.LENGTH_SHORT); t.show(); activity.finish(); return true; } else { return false; } }
/** * Creates new call to given <tt>destination</tt> using selected <tt>provider</tt>. * * @param context the android context * @param destination target callee name. * @param provider the provider that will be used to make a call. */ public static void createCall( final Context context, final String destination, final ProtocolProviderService provider) { if (createCallThread != null) { logger.warn("Another call is already being created"); return; } else if (CallManager.getActiveCallsCount() > 0) { logger.warn("Another call is in progress"); return; } final long dialogId = ProgressDialogFragment.showProgressDialog( JitsiApplication.getResString(R.string.service_gui_OUTGOING_CALL), JitsiApplication.getResString(R.string.service_gui_OUTGOING_CALL_MSG, destination)); createCallThread = new Thread("Create call thread") { public void run() { try { CallManager.createCall(provider, destination); } catch (Throwable t) { logger.error("Error creating the call: " + t.getMessage(), t); AndroidUtils.showAlertDialog( context, context.getString(R.string.service_gui_ERROR), t.getMessage()); } finally { if (DialogActivity.waitForDialogOpened(dialogId)) { DialogActivity.closeDialog(JitsiApplication.getGlobalContext(), dialogId); } else { logger.error("Failed to wait for the dialog: " + dialogId); } createCallThread = null; } } }; createCallThread.start(); }
/** * @author Yana Stamcheva * @author Pawel Domas */ public class AndroidCallUtil { /** The logger for this class. */ private static final Logger logger = Logger.getLogger(AndroidCallUtil.class); /** Field used to track the thread used to create outgoing calls. */ private static Thread createCallThread; /** * Creates an android call. * * @param context the android context * @param callButtonView the button view that generated the call * @param contact the contact address to call */ public static void createAndroidCall(Context context, View callButtonView, String contact) { if (AccountUtils.getRegisteredProviders().size() > 1) showCallViaMenu(context, callButtonView, contact); else createCall(context, contact); } /** * Creates new call to target <tt>destination</tt>. * * @param context the android context * @param destination the target callee name that will be used. */ private static void createCall(Context context, String destination) { Iterator<ProtocolProviderService> allProviders = AccountUtils.getRegisteredProviders().iterator(); if (!allProviders.hasNext()) { logger.error("No registered providers found"); return; } createCall(context, destination, allProviders.next()); } /** * Creates new call to given <tt>destination</tt> using selected <tt>provider</tt>. * * @param context the android context * @param destination target callee name. * @param provider the provider that will be used to make a call. */ public static void createCall( final Context context, final String destination, final ProtocolProviderService provider) { if (createCallThread != null) { logger.warn("Another call is already being created"); return; } else if (CallManager.getActiveCallsCount() > 0) { logger.warn("Another call is in progress"); return; } final long dialogId = ProgressDialogFragment.showProgressDialog( JitsiApplication.getResString(R.string.service_gui_OUTGOING_CALL), JitsiApplication.getResString(R.string.service_gui_OUTGOING_CALL_MSG, destination)); createCallThread = new Thread("Create call thread") { public void run() { try { CallManager.createCall(provider, destination); } catch (Throwable t) { logger.error("Error creating the call: " + t.getMessage(), t); AndroidUtils.showAlertDialog( context, context.getString(R.string.service_gui_ERROR), t.getMessage()); } finally { if (DialogActivity.waitForDialogOpened(dialogId)) { DialogActivity.closeDialog(JitsiApplication.getGlobalContext(), dialogId); } else { logger.error("Failed to wait for the dialog: " + dialogId); } createCallThread = null; } } }; createCallThread.start(); } /** * Shows "call via" menu allowing user to selected from multiple providers. * * @param context the android context * @param v the View that will contain the popup menu. * @param destination target callee name. */ private static void showCallViaMenu(final Context context, View v, final String destination) { PopupMenu popup = new PopupMenu(context, v); Menu menu = popup.getMenu(); Iterator<ProtocolProviderService> registeredProviders = AccountUtils.getRegisteredProviders().iterator(); while (registeredProviders.hasNext()) { final ProtocolProviderService provider = registeredProviders.next(); String accountAddress = provider.getAccountID().getAccountAddress(); MenuItem menuItem = menu.add(Menu.NONE, Menu.NONE, Menu.NONE, accountAddress); menuItem.setOnMenuItemClickListener( new MenuItem.OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { createCall(context, destination, provider); return false; } }); } popup.show(); } /** * Checks if there is a call in progress. If true then shows a warning toast and finishes the * activity. * * @param activity activity doing a check. * @return <tt>true</tt> if there is call in progress and <tt>Activity</tt> was finished. */ public static boolean checkCallInProgress(Activity activity) { if (CallManager.getActiveCallsCount() > 0) { logger.warn("Call is in progress"); Toast t = Toast.makeText(activity, R.string.service_gui_WARN_CALL_IN_PROGRESS, Toast.LENGTH_SHORT); t.show(); activity.finish(); return true; } else { return false; } } }
/** * The <tt>AndroidLoginRenderer</tt> is the Android renderer for login events. * * @author Yana Stamcheva * @author Pawel Domas */ public class AndroidLoginRenderer implements LoginRenderer { /** The logger */ private static final Logger logger = Logger.getLogger(AndroidLoginRenderer.class); /** The <tt>CallListener</tt>. */ private CallListener androidCallListener; /** The android implementation of the provider presence listener. */ private final ProviderPresenceStatusListener androidPresenceListener = new UIProviderPresenceStatusListener(); /** The security authority used by this login renderer. */ private final SecurityAuthority securityAuthority; /** Authorization handler instance. */ private final AuthorizationHandlerImpl authorizationHandler; /** Cached global status value */ private PresenceStatus globalStatus; /** List of global status listeners. */ private EventListenerList<PresenceStatus> globalStatusListeners = new EventListenerList<PresenceStatus>(); /** Caches avatar image to track the changes */ private byte[] localAvatarRaw; /** Local avatar drawable */ private Drawable localAvatar; /** Caches local status to track the changes */ private byte[] localStatusRaw; /** Local status drawable */ private Drawable localStatusDrawable; /** * Creates an instance of <tt>AndroidLoginRenderer</tt> by specifying the current * <tt>Context</tt>. * * @param defaultSecurityAuthority the security authority that will be used by this login renderer */ public AndroidLoginRenderer(SecurityAuthority defaultSecurityAuthority) { androidCallListener = new AndroidCallListener(); securityAuthority = defaultSecurityAuthority; authorizationHandler = new AuthorizationHandlerImpl(); } /** * Adds the user interface related to the given protocol provider. * * @param protocolProvider the protocol provider for which we add the user interface */ public void addProtocolProviderUI(ProtocolProviderService protocolProvider) { OperationSetBasicTelephony<?> telOpSet = protocolProvider.getOperationSet(OperationSetBasicTelephony.class); if (telOpSet != null) { telOpSet.addCallListener(androidCallListener); } OperationSetPresence presenceOpSet = protocolProvider.getOperationSet(OperationSetPresence.class); if (presenceOpSet != null) { presenceOpSet.addProviderPresenceStatusListener(androidPresenceListener); } } /** * Removes the user interface related to the given protocol provider. * * @param protocolProvider the protocol provider to remove */ public void removeProtocolProviderUI(ProtocolProviderService protocolProvider) { OperationSetBasicTelephony<?> telOpSet = protocolProvider.getOperationSet(OperationSetBasicTelephony.class); if (telOpSet != null) { telOpSet.removeCallListener(androidCallListener); } OperationSetPresence presenceOpSet = protocolProvider.getOperationSet(OperationSetPresence.class); if (presenceOpSet != null) { presenceOpSet.removeProviderPresenceStatusListener(androidPresenceListener); } // Removes all chat session for unregistered provider ChatSessionManager.removeAllChatsForProvider(protocolProvider); } /** * Starts the connecting user interface for the given protocol provider. * * @param protocolProvider the protocol provider for which we add the connecting user interface */ public void startConnectingUI(ProtocolProviderService protocolProvider) {} /** * Stops the connecting user interface for the given protocol provider. * * @param protocolProvider the protocol provider for which we remove the connecting user interface */ public void stopConnectingUI(ProtocolProviderService protocolProvider) {} /** * Indicates that the given protocol provider has been connected at the given time. * * @param protocolProvider the <tt>ProtocolProviderService</tt> corresponding to the connected * account * @param date the date/time at which the account has connected */ public void protocolProviderConnected(ProtocolProviderService protocolProvider, long date) { OperationSetPresence presence = AccountStatusUtils.getProtocolPresenceOpSet(protocolProvider); if (presence != null) { presence.setAuthorizationHandler(authorizationHandler); } updateGlobalStatus(); } /** * Indicates that a protocol provider connection has failed. * * @param protocolProvider the <tt>ProtocolProviderService</tt>, which connection failed * @param loginManagerCallback the <tt>LoginManager</tt> implementation, which is managing the * process */ public void protocolProviderConnectionFailed( final ProtocolProviderService protocolProvider, final LoginManager loginManagerCallback) { AccountID accountID = protocolProvider.getAccountID(); AndroidUtils.showAlertConfirmDialog( JitsiApplication.getGlobalContext(), JitsiApplication.getResString(R.string.service_gui_ERROR), JitsiApplication.getResString( R.string.service_gui_CONNECTION_FAILED_MSG, accountID.getUserID(), accountID.getService()), JitsiApplication.getResString(R.string.service_gui_RETRY), new DialogActivity.DialogListener() { public boolean onConfirmClicked(DialogActivity dialog) { loginManagerCallback.login(protocolProvider); return true; } public void onDialogCancelled(DialogActivity dialog) {} }); } /** * Returns the <tt>SecurityAuthority</tt> implementation related to this login renderer. * * @param protocolProvider the specific <tt>ProtocolProviderService</tt>, for which we're * obtaining a security authority * @return the <tt>SecurityAuthority</tt> implementation related to this login renderer */ public SecurityAuthority getSecurityAuthorityImpl(ProtocolProviderService protocolProvider) { return securityAuthority; } /** Updates Jitsi icon notification to reflect current global status. */ public void updateJitsiIconNotification() { String status; if (getGlobalStatus().isOnline()) { // At least one provider is online status = JitsiApplication.getResString(R.string.service_gui_ONLINE); } else { // There are no active providers so we consider to be in // the offline state status = JitsiApplication.getResString(R.string.service_gui_OFFLINE); } int notificationID = OSGiService.getGeneralNotificationId(); if (notificationID == -1) { logger.debug( "Not displaying status notification because" + " there's no global notification icon available."); return; } AndroidUtils.updateGeneralNotification( JitsiApplication.getGlobalContext(), notificationID, JitsiApplication.getResString(R.string.app_name), status, System.currentTimeMillis()); } /** * Adds global status listener. * * @param l the listener to be add. */ public void addGlobalStatusListener(EventListener<PresenceStatus> l) { globalStatusListeners.addEventListener(l); } /** * Removes global status listener. * * @param l the listener to remove. */ public void removeGlobalStatusListener(EventListener<PresenceStatus> l) { globalStatusListeners.removeEventListener(l); } /** * Returns current global status. * * @return current global status. */ public PresenceStatus getGlobalStatus() { if (globalStatus == null) { GlobalStatusService gss = AndroidGUIActivator.getGlobalStatusService(); globalStatus = gss != null ? gss.getGlobalPresenceStatus() : GlobalStatusEnum.OFFLINE; } return globalStatus; } /** AuthorizationHandler instance used by this login renderer. */ public AuthorizationHandlerImpl getAuthorizationHandler() { return authorizationHandler; } /** * Listens for all providerStatusChanged and providerStatusMessageChanged events in order to * refresh the account status panel, when a status is changed. */ private class UIProviderPresenceStatusListener implements ProviderPresenceStatusListener { public void providerStatusChanged(ProviderPresenceStatusChangeEvent evt) { updateGlobalStatus(); } public void providerStatusMessageChanged(PropertyChangeEvent evt) {} } /** * Indicates if the given <tt>protocolProvider</tt> related user interface is already rendered. * * @param protocolProvider the <tt>ProtocolProviderService</tt>, which related user interface * we're looking for * @return <tt>true</tt> if the given <tt>protocolProvider</tt> related user interface is already * rendered */ public boolean containsProtocolProviderUI(ProtocolProviderService protocolProvider) { return false; } /** Updates the global status by picking the most connected protocol provider status. */ private void updateGlobalStatus() { // Only if the GUI is active (bundle context will be null on shutdown) if (AndroidGUIActivator.bundleContext != null) { // Invalidate local status image localStatusRaw = null; // Invalidate global status globalStatus = null; globalStatusListeners.notifyEventListeners(getGlobalStatus()); } updateJitsiIconNotification(); } /** * Returns the local user avatar drawable. * * @return the local user avatar drawable. */ public Drawable getLocalAvatarDrawable() { GlobalDisplayDetailsService displayDetailsService = AndroidGUIActivator.getGlobalDisplayDetailsService(); byte[] avatarImage = displayDetailsService.getGlobalDisplayAvatar(); // Re-create drawable only if avatar has changed if (avatarImage != localAvatarRaw) { localAvatarRaw = avatarImage; localAvatar = AndroidImageUtil.roundedDrawableFromBytes(avatarImage); } return localAvatar; } /** * Returns the local user status drawable. * * @return the local user status drawable */ public synchronized Drawable getLocalStatusDrawable() { byte[] statusImage = StatusUtil.getContactStatusIcon(getGlobalStatus()); if (statusImage != localStatusRaw) { localStatusRaw = statusImage; localStatusDrawable = localStatusRaw != null ? AndroidImageUtil.drawableFromBytes(statusImage) : null; } return localStatusDrawable; } }
/** * This activity allows user to add new contacts. * * @author Pawel Domas */ public class AddContactActivity extends OSGiActivity { /** The logger. */ private static final Logger logger = Logger.getLogger(AddContactActivity.class); /** {@inheritDoc} */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.add_contact); setTitle(R.string.service_gui_ADD_CONTACT); initAccountSpinner(); initContactGroupSpinner(); } /** Initializes "select account" spinner with existing accounts. */ private void initAccountSpinner() { Spinner accountsSpiner = (Spinner) findViewById(R.id.selectAccountSpinner); Iterator<ProtocolProviderService> providers = AccountUtils.getRegisteredProviders().iterator(); List<AccountID> accounts = new ArrayList<AccountID>(); int selectedIdx = -1; int idx = 0; while (providers.hasNext()) { ProtocolProviderService provider = providers.next(); OperationSet opSet = provider.getOperationSet(OperationSetPresence.class); if (opSet == null) continue; AccountID account = provider.getAccountID(); accounts.add(account); idx++; if (account.isPreferredProvider()) { selectedIdx = idx; } } AccountsListAdapter accountsAdapter = new AccountsListAdapter( this, R.layout.select_account_row, R.layout.select_account_dropdown, accounts, true); accountsSpiner.setAdapter(accountsAdapter); // if we have only select account option and only one account // select the available account if (accounts.size() == 1) accountsSpiner.setSelection(0); else accountsSpiner.setSelection(selectedIdx); } /** Initializes select contact group spinner with contact groups. */ private void initContactGroupSpinner() { Spinner groupSpinner = (Spinner) findViewById(R.id.selectGroupSpinner); MetaContactGroupAdapter contactGroupAdapter = new MetaContactGroupAdapter(this, R.id.selectGroupSpinner, true, true); contactGroupAdapter.setItemLayout(R.layout.simple_spinner_item); contactGroupAdapter.setDropDownLayout(R.layout.dropdown_spinner_item); groupSpinner.setAdapter(contactGroupAdapter); } /** * Method fired when "add" button is clicked. * * @param v add button's <tt>View</tt> */ public void onAddClicked(View v) { Spinner accountsSpiner = (Spinner) findViewById(R.id.selectAccountSpinner); Account selectedAcc = (Account) accountsSpiner.getSelectedItem(); if (selectedAcc == null) { logger.error("No account selected"); return; } ProtocolProviderService pps = selectedAcc.getProtocolProvider(); if (pps == null) { logger.error("No provider registered for account " + selectedAcc.getAccountName()); return; } View content = findViewById(android.R.id.content); String contactAddress = ViewUtil.getTextViewValue(content, R.id.editContactName); String displayName = ViewUtil.getTextViewValue(content, R.id.editDisplayName); if (displayName != null && displayName.length() > 0) { addRenameListener(pps, null, contactAddress, displayName); } Spinner groupSpinner = (Spinner) findViewById(R.id.selectGroupSpinner); ContactListUtils.addContact( pps, (MetaContactGroup) groupSpinner.getSelectedItem(), contactAddress); finish(); } /** * Adds a rename listener. * * @param protocolProvider the protocol provider to which the contact was added * @param metaContact the <tt>MetaContact</tt> if the new contact was added to an existing meta * contact * @param contactAddress the address of the newly added contact * @param displayName the new display name */ private void addRenameListener( final ProtocolProviderService protocolProvider, final MetaContact metaContact, final String contactAddress, final String displayName) { AndroidGUIActivator.getContactListService() .addMetaContactListListener( new MetaContactListAdapter() { @Override public void metaContactAdded(MetaContactEvent evt) { if (evt.getSourceMetaContact().getContact(contactAddress, protocolProvider) != null) { renameContact(evt.getSourceMetaContact(), displayName); } } @Override public void protoContactAdded(ProtoContactEvent evt) { if (metaContact != null && evt.getNewParent().equals(metaContact)) { renameContact(metaContact, displayName); } } }); } /** * Renames the given meta contact. * * @param metaContact the <tt>MetaContact</tt> to rename * @param displayName the new display name */ private void renameContact(final MetaContact metaContact, final String displayName) { new Thread() { @Override public void run() { AndroidGUIActivator.getContactListService().renameMetaContact(metaContact, displayName); } }.start(); } }