package org.edx.mobile.social;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import com.google.inject.Inject;
import org.edx.mobile.R;
import org.edx.mobile.authentication.AuthResponse;
import org.edx.mobile.authentication.LoginAPI;
import org.edx.mobile.exception.LoginErrorMessage;
import org.edx.mobile.exception.LoginException;
import org.edx.mobile.logger.Logger;
import org.edx.mobile.model.api.ProfileModel;
import org.edx.mobile.module.prefs.LoginPrefs;
import org.edx.mobile.module.prefs.PrefManager;
import org.edx.mobile.social.facebook.FacebookProvider;
import org.edx.mobile.social.google.GoogleOauth2;
import org.edx.mobile.social.google.GoogleProvider;
import org.edx.mobile.task.Task;
import org.edx.mobile.util.Config;
import org.edx.mobile.util.NetworkUtil;
import org.edx.mobile.util.ResourceUtil;
import org.edx.mobile.view.ICommonUI;
import java.util.HashMap;
/**
* Code refactored from Login Activity, for the logic of login to social site are the same
* for both login and registration.
*/
public class SocialLoginDelegate {
protected final Logger logger = new Logger(getClass().getName());
private Activity activity;
private MobileLoginCallback callback;
private ISocial google, facebook;
private final LoginPrefs loginPrefs;
private String userEmail;
private ISocial.Callback googleCallback = new ISocial.Callback() {
@Override
public void onLogin(String accessToken) {
logger.debug("Google logged in; token= " + accessToken);
onSocialLoginSuccess(accessToken, PrefManager.Value.BACKEND_GOOGLE);
}
};
private ISocial.Callback facebookCallback = new ISocial.Callback() {
@Override
public void onLogin(String accessToken) {
logger.debug("Facebook logged in; token= " + accessToken);
onSocialLoginSuccess(accessToken, PrefManager.Value.BACKEND_FACEBOOK);
}
};
public SocialLoginDelegate(Activity activity, Bundle savedInstanceState, MobileLoginCallback callback, Config config, LoginPrefs loginPrefs) {
this.activity = activity;
this.callback = callback;
this.loginPrefs = loginPrefs;
google = SocialFactory.getInstance(activity, SocialFactory.SOCIAL_SOURCE_TYPE.TYPE_GOOGLE, config);
google.setCallback(googleCallback);
facebook = SocialFactory.getInstance(activity, SocialFactory.SOCIAL_SOURCE_TYPE.TYPE_FACEBOOK, config);
facebook.setCallback(facebookCallback);
google.onActivityCreated(activity, savedInstanceState);
facebook.onActivityCreated(activity, savedInstanceState);
}
public void onActivityDestroyed() {
google.onActivityDestroyed(activity);
facebook.onActivityDestroyed(activity);
}
public void onActivitySaveInstanceState(Bundle outState) {
google.onActivitySaveInstanceState(activity, outState);
facebook.onActivitySaveInstanceState(activity, outState);
}
public void onActivityStarted() {
google.onActivityStarted(activity);
facebook.onActivityStarted(activity);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
google.onActivityResult(requestCode, resultCode, data);
facebook.onActivityResult(requestCode, resultCode, data);
}
public void onActivityStopped() {
google.onActivityStopped(activity);
facebook.onActivityStopped(activity);
}
public void socialLogin(SocialFactory.SOCIAL_SOURCE_TYPE socialType) {
if (socialType == SocialFactory.SOCIAL_SOURCE_TYPE.TYPE_FACEBOOK)
facebook.login();
else if (socialType == SocialFactory.SOCIAL_SOURCE_TYPE.TYPE_GOOGLE)
google.login();
}
public void socialLogout(SocialFactory.SOCIAL_SOURCE_TYPE socialType) {
if (socialType == SocialFactory.SOCIAL_SOURCE_TYPE.TYPE_FACEBOOK)
facebook.logout();
else if (socialType == SocialFactory.SOCIAL_SOURCE_TYPE.TYPE_GOOGLE)
google.logout();
}
/**
* called with you to use social login
*
* @param accessToken
* @param backend
*/
public void onSocialLoginSuccess(String accessToken, String backend) {
loginPrefs.saveSocialLoginToken(accessToken, backend);
Task<?> task = new ProfileTask(activity, accessToken, backend);
callback.onSocialLoginSuccess(accessToken, backend, task);
task.execute();
}
public void setUserEmail(String email) {
this.userEmail = email;
}
public String getUserEmail() {
return this.userEmail;
}
public void getUserInfo(SocialFactory.SOCIAL_SOURCE_TYPE socialType, String accessToken, final SocialUserInfoCallback userInfoCallback) {
SocialProvider socialProvider = null;
if (socialType == SocialFactory.SOCIAL_SOURCE_TYPE.TYPE_FACEBOOK) {
socialProvider = new FacebookProvider();
} else if (socialType == SocialFactory.SOCIAL_SOURCE_TYPE.TYPE_GOOGLE) {
socialProvider = new GoogleProvider((GoogleOauth2) google);
}
if (socialProvider != null) {
socialProvider.getUserInfo(activity, socialType, accessToken, userInfoCallback);
}
}
private class ProfileTask extends Task<ProfileModel> {
private String accessToken;
private String backend;
@Inject
LoginAPI loginAPI;
public ProfileTask(Context context, String accessToken, String backend) {
super(context);
this.accessToken = accessToken;
this.backend = backend;
}
@Override
public void onSuccess(ProfileModel result) {
callback.onUserLoginSuccess(result);
}
@Override
public void onException(Exception ex) {
super.onException(ex);
callback.onUserLoginFailure(ex, this.accessToken, this.backend);
}
@Override
public ProfileModel call() throws Exception {
final AuthResponse auth;
final HashMap<String, CharSequence> descParams = new HashMap<>();
descParams.put("platform_name", environment.getConfig().getPlatformName());
descParams.put("platform_destination", environment.getConfig().getPlatformDestinationName());
if (backend.equalsIgnoreCase(PrefManager.Value.BACKEND_FACEBOOK)) {
try {
auth = loginAPI.logInUsingFacebook(accessToken);
} catch (LoginAPI.AccountNotLinkedException e) {
CharSequence title = ResourceUtil.getFormattedString(context.getResources(), R.string.error_account_not_linked_title_fb, descParams);
CharSequence desc = ResourceUtil.getFormattedString(context.getResources(), R.string.error_account_not_linked_desc_fb, descParams);
throw new LoginException(new LoginErrorMessage(title.toString(), desc.toString()));
}
} else if (backend.equalsIgnoreCase(PrefManager.Value.BACKEND_GOOGLE)) {
try {
auth = loginAPI.logInUsingGoogle(accessToken);
} catch (LoginAPI.AccountNotLinkedException e) {
CharSequence title = ResourceUtil.getFormattedString(context.getResources(), R.string.error_account_not_linked_title_google, descParams);
CharSequence desc = ResourceUtil.getFormattedString(context.getResources(), R.string.error_account_not_linked_desc_google, descParams);
throw new LoginException(new LoginErrorMessage(title.toString(), desc.toString()));
}
} else {
throw new IllegalArgumentException("Unknown backend: " + backend);
}
return auth.profile;
}
}
public SocialButtonClickHandler createSocialButtonClickHandler(SocialFactory.SOCIAL_SOURCE_TYPE socialType) {
return new SocialButtonClickHandler(socialType);
}
public class SocialButtonClickHandler implements View.OnClickListener {
private SocialFactory.SOCIAL_SOURCE_TYPE socialType;
private SocialButtonClickHandler(SocialFactory.SOCIAL_SOURCE_TYPE socialType) {
this.socialType = socialType;
}
@Override
public void onClick(View v) {
if (!NetworkUtil.isConnected(activity)) {
callback.showAlertDialog(activity.getString(R.string.no_connectivity),
activity.getString(R.string.network_not_connected));
} else {
Task<Void> logout = new Task<Void>(activity) {
@Override
public Void call() {
socialLogout(socialType);
return null;
}
@Override
public void onSuccess(Void result) {
socialLogin(socialType);
}
@Override
public void onException(Exception ex) {
super.onException(ex);
if (activity instanceof ICommonUI)
((ICommonUI) activity).tryToSetUIInteraction(true);
}
};
if (activity instanceof ICommonUI)
((ICommonUI) activity).tryToSetUIInteraction(false);
logout.execute();
}
}
}
public interface MobileLoginCallback {
void onSocialLoginSuccess(String accessToken, String backend, Task task);
void onUserLoginFailure(Exception ex, String accessToken, String backend);
void onUserLoginSuccess(ProfileModel profile);
void showAlertDialog(String header, String message);
}
public interface SocialUserInfoCallback {
void setSocialUserInfo(String email, String name);
}
}