/** * Android implementation of <tt>VerifyCertificateDialogService</tt>. * * @author Pawel Domas */ class CertificateDialogServiceImpl implements VerifyCertificateDialogService { /** The logger. */ private static final Logger logger = Logger.getLogger(CertificateDialogServiceImpl.class); /** * Maps request ids to <tt>VerifyCertDialog</tt> so that they can be retrieved by Android * <tt>Activity</tt> or <tt>Fragments</tt>. */ private Map<Long, VerifyCertDialog> requestMap = new HashMap<Long, VerifyCertDialog>(); /** {@inheritDoc} */ @Override public VerifyCertificateDialog createDialog(Certificate[] certs, String title, String message) { if (title == null) title = JitsiApplication.getResString(R.string.service_gui_CERT_DIALOG_TITLE); Long requestId = System.currentTimeMillis(); VerifyCertDialog verifyCertDialog = new VerifyCertDialog(requestId, certs[0], title, message); requestMap.put(requestId, verifyCertDialog); logger.debug(hashCode() + " creating dialog: " + requestId); return verifyCertDialog; } /** * Retrieves the dialog for given <tt>requestId</tt>. * * @param requestId dialog's request identifier assigned during dialog creation. * @return the dialog for given <tt>requestId</tt>. */ public VerifyCertDialog retrieveDialog(Long requestId) { logger.debug(hashCode() + " getting dialog: " + requestId); return requestMap.get(requestId); } }
/** * @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; } }