package org.awesomeapp.messenger.ui.legacy;
import org.awesomeapp.messenger.service.IImConnection;
import im.zom.messenger.R;
import org.awesomeapp.messenger.ui.legacy.adapter.ConnectionListenerAdapter;
import org.awesomeapp.messenger.model.ImConnection;
import org.awesomeapp.messenger.model.ImErrorInfo;
import org.awesomeapp.messenger.ImApp;
import org.awesomeapp.messenger.provider.Imps;
import org.awesomeapp.messenger.MainActivity;
import org.awesomeapp.messenger.service.ImServiceConstants;
import org.awesomeapp.messenger.util.LogCleaner;
import java.util.Collection;
import java.util.HashSet;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
/**
* Handle sign-in process for activities.
*
* @author devrandom
*
* <p>Users of this helper must call {@link SignInHelper#stop()} to clean up callbacks
* in their onDestroy() or onPause() lifecycle methods.
*
* <p>The helper listens to connection events. It automatically stops listening when the
* connection state is logged-in or disconnected (failed).
*/
public class SignInHelper {
Activity mContext;
private Handler mHandler;
private ImApp mApp;
private MyConnectionListener mListener;
private Collection<IImConnection> connections;
private SignInListener mSignInListener;
// This can be used to be informed of signin events
public interface SignInListener {
void connectedToService();
void stateChanged(int state, long accountId);
}
public SignInHelper(Activity context, Handler handler, SignInListener listener) {
this.mContext = context;
mHandler = handler;
mListener = new MyConnectionListener(mHandler);
mSignInListener = listener;
if (mApp == null) {
mApp = (ImApp)mContext.getApplication();
}
connections = new HashSet<IImConnection>();
}
public SignInHelper(Activity context, Handler handler) {
this(context, handler, null);
}
public void setSignInListener(SignInListener listener) {
mSignInListener = listener;
}
public void stop() {
for (IImConnection connection : connections) {
try {
connection.unregisterConnectionListener(mListener);
} catch (RemoteException e) {
// Ignore
}
}
connections.clear();
}
private final class MyConnectionListener extends ConnectionListenerAdapter {
MyConnectionListener(Handler handler) {
super(handler);
}
@Override
public void onConnectionStateChange(IImConnection connection, int state, ImErrorInfo error) {
handleConnectionEvent(connection, state, error);
}
}
private void handleConnectionEvent(IImConnection connection, int state, ImErrorInfo error) {
long accountId;
long providerId;
try {
accountId = connection.getAccountId();
providerId = connection.getProviderId();
} catch (RemoteException e) {
// Ouch! Service died! We'll just disappear.
Log.w(ImApp.LOG_TAG, "<SigningInActivity> Connection disappeared while signing in!");
return;
}
if (mSignInListener != null)
mSignInListener.stateChanged(state, accountId);
// Stop listening if we get into a resting state
if (state == ImConnection.LOGGED_IN || state == ImConnection.DISCONNECTED) {
connections.remove(connection);
try {
connection.unregisterConnectionListener(mListener);
} catch (RemoteException e) {
//mHandler.showServiceErrorAlert(e.getLocalizedMessage());
LogCleaner.error(ImApp.LOG_TAG, "handle connection error",e);
}
}
if (state == ImConnection.DISCONNECTED) {
// sign in failed
final ProviderDef provider = mApp.getProvider(providerId);
if (provider != null) //a provider might have been deleted
{
String providerName = provider.mName;
Resources r = mContext.getResources();
String errMsg = r.getString(R.string.login_service_failed, providerName, // FIXME
error == null ? "" : ErrorResUtils.getErrorRes(r, error.getCode()));
// Toast.makeText(mContext, errMsg, Toast.LENGTH_LONG).show();
/*
new AlertDialog.Builder(mContext).setTitle(R.string.error)
.setMessage()
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// FIXME
}
}).setCancelable(false).show();
*/
}
}
}
public void goToAccount(long accountId) {
Intent intent;
intent = new Intent(mContext, MainActivity.class);
// clear the back stack of the account setup
intent.putExtra(ImServiceConstants.EXTRA_INTENT_ACCOUNT_ID, accountId);
mContext.startActivity(intent);
// sign in successfully, finish and switch to contact list
// mContext.finish();
}
public void signIn(final String password, final long providerId, final long accountId,
final boolean isActive) {
final ProviderDef provider = mApp.getProvider(providerId);
if (provider != null) //provider may be null if deleted, or db not updated yet
{
final String providerName = provider.mName;
if (mApp.serviceConnected()) {
if (mSignInListener != null)
mSignInListener.connectedToService();
if (!isActive) {
activateAccount(providerId, accountId);
}
signInAccount(password, providerId, providerName, accountId);
}
else
{
mApp.callWhenServiceConnected(mHandler, new Runnable() {
public void run() {
if (mApp.serviceConnected()) {
if (mSignInListener != null)
mSignInListener.connectedToService();
if (!isActive) {
activateAccount(providerId, accountId);
}
signInAccount(password, providerId, providerName, accountId);
}
}
});
}
}
}
private void signInAccount(final String password, final long providerId, final String providerName, final long accountId) {
try {
signInAccountAsync(password, providerId, providerName, accountId);
} catch (RemoteException e) {
Log.d(ImApp.LOG_TAG,"error signing in",e);
}
}
private void signInAccountAsync(String password, long providerId, String providerName, long accountId) throws RemoteException {
boolean autoLoadContacts = true;
boolean autoRetryLogin = true;
IImConnection conn = null;
conn = mApp.getConnection(providerId,accountId);
if (conn != null) {
connections.add(conn);
conn.registerConnectionListener(mListener);
int state = conn.getState();
if (mSignInListener != null)
mSignInListener.stateChanged(state, accountId);
if (state != ImConnection.DISCONNECTED) {
// already signed in or in the process
if (state == ImConnection.LOGGED_IN) {
connections.remove(conn);
conn.unregisterConnectionListener(mListener);
}
handleConnectionEvent(conn, state, null);
return;
}
} else {
conn = mApp.createConnection(providerId, accountId);
if (conn == null) {
// This can happen when service did not come up for any reason
return;
}
connections.add(conn);
conn.registerConnectionListener(mListener);
}
conn.login(password, autoLoadContacts, autoRetryLogin);
/*
if (mApp.isNetworkAvailableAndConnected()) {
} else {
// promptForBackgroundDataSetting(providerName);
return;
}*/
}
/**
* Popup a dialog to ask the user whether he/she wants to enable background
* connection to continue. If yes, enable the setting and broadcast the
* change. Otherwise, quit the signing in window immediately.
*/
private void promptForBackgroundDataSetting(String providerName) {
Toast.makeText(mContext, mContext.getString(R.string.bg_data_prompt_message, providerName), Toast.LENGTH_LONG).show();
}
public void activateAccount(long providerId, long accountId) {
// Update the active value. We restrict to only one active
// account per provider right now, so update all accounts of
// this provider to inactive first and then update this
// account to active.
ContentValues values = new ContentValues(1);
values.put(Imps.Account.ACTIVE, 0);
ContentResolver cr = mContext.getContentResolver();
cr.update(Imps.Account.CONTENT_URI, values, Imps.Account.PROVIDER + "=" + providerId, null);
values.put(Imps.Account.ACTIVE, 1);
cr.update(ContentUris.withAppendedId(Imps.Account.CONTENT_URI, accountId), values, null,
null);
}
}