package com.steamcommunity.siplus.steamscreenshots;
import android.os.Bundle;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Base64;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
public final class LoginAddActivity extends Activity {
static final String EXTRASTATE_FROM_APP = Utility.PACKAGE + ".LoginAddActivity.EXTRASTATE_FROM_APP";
static final String STATE_ERROR = Utility.PACKAGE + ".LoginAddActivity.STATE_ERROR";
static final String STATE_GUARD_EMAIL = Utility.PACKAGE + ".LoginAddActivity.STATE_GUARD_EMAIL";
static final String STATE_OLD_ACCOUNT = Utility.PACKAGE + ".LoginAddActivity.STATE_OLD_ACCOUNT";
static final String STATE_TASK = Utility.PACKAGE + ".LoginAddActivity.STATE_TASK";
AccountManager mAccountManager;
ProgressDialog mCancelling;
int mError;
boolean mFromApp;
String mGuardEmail;
String mOldAccount;
ProgressDialog mProgress;
LoginAddTask mTask;
EditText widgetAccount;
Button widgetAddButton;
TextView widgetError;
LinearLayout widgetErrorFrame;
LinearLayout widgetGuard;
EditText widgetGuardCode;
TextView widgetGuardInfo;
EditText widgetGuardName;
EditText widgetPassword;
void doneLoggingIn() {
hideLoginProgress();
LoginAddTask task = mTask;
mTask = null;
ClientLogonResponseIncoming logonResponse = task.mLogonResponse;
if (logonResponse == null) {
setErrorText(R.string.error_connection);
return;
}
if (logonResponse.mEResult == EResult.OK) {
if (task.mLoginKey == null) {
setErrorText(R.string.error_connection);
return;
}
}
switch (logonResponse.mEResult) {
case EResult.OK:
if (task.mLoginKey == null) {
setErrorText(R.string.error_connection);
return;
}
Bundle userdata = new Bundle();
if (task.mGuardHash != null) {
userdata.putString(SteamshotsAccount.DATA_GUARD_HASH, Base64.encodeToString(task.mGuardHash, Base64.NO_WRAP));
}
userdata.putString(SteamshotsAccount.DATA_LOGIN_KEY, task.mLoginKey);
userdata.putString(SteamshotsAccount.DATA_STEAM_ID, Long.toString(logonResponse.mHeader.mSteamID));
mAccountManager.addAccountExplicitly(new Account(task.mName, Utility.PACKAGE), null, userdata);
finish();
return;
case EResult.INVALID_PASSWORD:
case EResult.ILLEGAL_PASSWORD:
case EResult.CANNOT_USE_OLD_PASSWORD:
setErrorText(R.string.login_add_error_password);
return;
case EResult.LOGGED_IN_ELSEWHERE:
case EResult.ALREADY_LOGGED_IN_ELSEWHERE:
setErrorText(R.string.error_elsewhere);
return;
case EResult.ACCOUNT_DISABLED:
setErrorText(R.string.login_add_error_disabled);
return;
case EResult.ACCOUNT_LOGON_DENIED:
mGuardEmail = logonResponse.mEmailDomain;
if (mGuardEmail == null) {
mGuardEmail = "[unknown]";
}
refreshGuardInfo();
return;
case EResult.INVALID_LOGIN_AUTH_CODE:
case EResult.EXPIRED_LOGIN_AUTH_CODE:
setErrorText(R.string.login_add_error_guard_code);
return;
}
setErrorText(R.string.login_add_error);
}
void hideLoginProgress() {
if (mProgress == null) {
return;
}
mProgress.dismiss();
mProgress = null;
}
public void listenerAddOnClick(View view) {
if (AsyncTaskWithRunID.isRunning(mTask)) {
mCancelling = Utility.showCancellingProgress(this, new LoginAddCancellingOnCancel(this));
return;
}
if (!Utility.isConnected(this)) {
setErrorText(R.string.error_unconnected);
return;
}
String name = widgetAccount.getText().toString().toLowerCase();
Account[] accounts = mAccountManager.getAccountsByType(Utility.PACKAGE);
int i;
for (i = 0; i < accounts.length; ++i) {
if (name.equals(accounts[i].name)) {
setErrorText(R.string.login_add_error_exists);
return;
}
}
setErrorText(0);
String guardCode;
String guardName;
if (mGuardEmail != null) {
guardCode = widgetGuardCode.getText().toString();
guardName = widgetGuardName.getText().toString();
} else {
guardCode = guardName = null;
}
mTask = new LoginAddTask(this, name,
widgetPassword.getText().toString(),
guardCode, guardName);
mTask.execute((Void)(null));
showLoginProgress();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAccountManager = AccountManager.get(this);
setContentView(R.layout.view_login_add);
widgetAccount = (EditText)(findViewById(R.id.view_login_add_account));
widgetAddButton = (Button)(findViewById(R.id.view_login_add_button));
widgetError = (TextView)(findViewById(R.id.view_login_add_error));
widgetErrorFrame = (LinearLayout)(findViewById(R.id.view_login_add_error_frame));
widgetGuard = (LinearLayout)(findViewById(R.id.view_login_add_guard));
widgetGuardCode = (EditText)(findViewById(R.id.view_login_add_guard_code));
widgetGuardInfo = (TextView)(findViewById(R.id.view_login_add_guard_info));
widgetGuardName = (EditText)(findViewById(R.id.view_login_add_guard_name));
widgetPassword = (EditText)(findViewById(R.id.view_login_add_password));
if (savedInstanceState != null) {
setErrorText(savedInstanceState.getInt(STATE_ERROR));
mFromApp = savedInstanceState.getBoolean(EXTRASTATE_FROM_APP);
mGuardEmail = savedInstanceState.getString(STATE_GUARD_EMAIL);
mOldAccount = savedInstanceState.getString(STATE_OLD_ACCOUNT, "");
mTask = (LoginAddTask)(AsyncTaskWithRunID.findRun(savedInstanceState.getInt(STATE_TASK)));
if (mTask != null) {
mTask.mActivity = this;
if (!mTask.isCancelled()) {
showLoginProgress();
}
}
} else {
setErrorText(0);
Bundle extras = getIntent().getExtras();
if (extras != null) {
mFromApp = extras.getBoolean(EXTRASTATE_FROM_APP);
}
mOldAccount = "";
}
if (mFromApp) {
Utility.enableActionBarBack(this);
}
refreshGuardInfo();
widgetAccount.addTextChangedListener(new LoginAddAccountWatcher(this));
LoginAddTextWatcher textWatcher = new LoginAddTextWatcher(this);
widgetGuardCode.addTextChangedListener(textWatcher);
widgetPassword.addTextChangedListener(textWatcher);
}
@Override
protected void onDestroy() {
super.onDestroy();
hideLoginProgress();
if (isChangingConfigurations()) {
return;
}
if (AsyncTaskWithRunID.isRunning(mTask)) {
mTask.mActivity = null;
mTask.cancel(false);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() != android.R.id.home) {
return super.onOptionsItemSelected(item);
}
finish();
return true;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_ERROR, mError);
outState.putBoolean(EXTRASTATE_FROM_APP, mFromApp);
outState.putString(STATE_GUARD_EMAIL, mGuardEmail);
outState.putString(STATE_OLD_ACCOUNT, widgetAccount.getText().toString());
if (AsyncTaskWithRunID.isRunning(mTask)) {
outState.putInt(STATE_TASK, mTask.mRun);
}
}
void refreshGuardInfo() {
toggleButtonEnabled();
if (mGuardEmail == null) {
widgetGuard.setVisibility(View.GONE);
return;
}
widgetGuardInfo.setText(getResources().getString(R.string.login_add_guard_info, mGuardEmail));
widgetGuard.setVisibility(View.VISIBLE);
}
void setErrorText(int resid) {
mError = resid;
if (resid == 0) {
widgetErrorFrame.setVisibility(View.GONE);
return;
}
widgetError.setText(resid);
widgetErrorFrame.setVisibility(View.VISIBLE);
}
void showLoginProgress() {
ProgressDialog dialog = new ProgressDialog(this);
mProgress = dialog;
dialog.setOnCancelListener(new LoginAddProgressOnCancel(this));
dialog.setMax(mTask.mNeedGuard ? 7 : 5);
dialog.setProgress(mTask.mStages);
dialog.setProgressNumberFormat(null);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setTitle(R.string.login_add_progress);
dialog.show();
}
void toggleButtonEnabled() {
if ((widgetAccount.length() == 0) || (widgetPassword.length() == 0)) {
widgetAddButton.setEnabled(false);
return;
}
if (mGuardEmail != null) {
if (widgetGuardCode.length() != 5) {
widgetAddButton.setEnabled(false);
return;
}
}
widgetAddButton.setEnabled(true);
}
void updateLoginProgress(int progress) {
if ((mProgress != null) && AsyncTaskWithRunID.isRunning(mTask)) {
mProgress.setProgress(progress);
}
}
}
class LoginAddAccountWatcher implements TextWatcher {
LoginAddActivity mActivity;
LoginAddAccountWatcher(LoginAddActivity activity) {
mActivity = activity;
}
@Override
public void afterTextChanged(Editable s) {
String account = s.toString();
LoginAddActivity activity = mActivity;
if (activity.mOldAccount.equals(account)) {
return;
}
mActivity.mGuardEmail = null;
mActivity.mOldAccount = account;
mActivity.refreshGuardInfo();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
}
class LoginAddCancellingOnCancel implements DialogInterface.OnCancelListener {
LoginAddActivity mActivity;
LoginAddCancellingOnCancel(LoginAddActivity activity) {
mActivity = activity;
}
@Override
public void onCancel(DialogInterface dialog) {
mActivity.mCancelling = null;
}
}
class LoginAddProgressOnCancel implements DialogInterface.OnCancelListener {
LoginAddActivity mActivity;
LoginAddProgressOnCancel(LoginAddActivity activity) {
mActivity = activity;
}
@Override
public void onCancel(DialogInterface dialog) {
mActivity.mProgress = null;
LoginAddTask task = mActivity.mTask;
if (AsyncTaskWithRunID.isRunning(task)) {
task.cancel(false);
}
}
}
class LoginAddTask extends AsyncTaskWithRunID {
LoginAddActivity mActivity;
Connection mConnection;
byte[] mGuardHash;
boolean mLoggedOn;
String mLoginKey;
ClientLogonOutgoing mLogonOutgoing;
ClientLogonResponseIncoming mLogonResponse;
String mName;
boolean mNeedGuard;
int mStages;
LoginAddTask(LoginAddActivity activity, String name, String password, String guardCode, String guardName) {
mActivity = activity;
ClientLogonOutgoing.initializeMachineID(activity);
mLogonOutgoing = new ClientLogonOutgoing(name, password, guardCode, guardName);
mName = name;
mNeedGuard = guardCode != null;
}
void disconnect() {
Connection connection = mConnection;
if (connection == null) {
return;
}
if (mLoggedOn) {
try {
connection.sendMessage(new ClientLogOffOutgoing());
} catch (OutgoingException e) {}
}
connection.disconnect();
}
@Override
protected Boolean doInBackground(Void... params) {
if (isCancelled()) {return false;}
Connection connection = new Connection();
mConnection = connection;
try {
connection.connect(Connection.CM_ADDRESS, Connection.CM_PORT);
} catch (ConnectionException e) {
return false;
}
publishProgress(++mStages);
if (isCancelled()) {return false;}
try {
connection.sendMessage(mLogonOutgoing);
publishProgress(++mStages);
if (isCancelled()) {return false;}
mLogonResponse = new ClientLogonResponseIncoming(
connection.waitForMessage(ClientLogonResponseIncoming.MESSAGE));
if ((mLogonResponse.mEResult != EResult.OK) || isCancelled()) {
return false;
}
publishProgress(++mStages);
MessageHeader header = mLogonResponse.mHeader;
connection.mSessionID = header.mSessionID;
connection.mSteamID = header.mSteamID;
connection.mHeartbeatWhenWaiting = true;
if (mNeedGuard) {
if (isCancelled()) {return false;}
ClientUpdateMachineAuthIncoming updateMachineAuthIncoming = new ClientUpdateMachineAuthIncoming(
connection.waitForMessage(ClientUpdateMachineAuthIncoming.MESSAGE));
publishProgress(++mStages);
mGuardHash = updateMachineAuthIncoming.mGuardHash;
if (isCancelled()) {return false;}
connection.sendMessage(new ClientUpdateMachineAuthResponseOutgoing(updateMachineAuthIncoming));
publishProgress(++mStages);
}
if (isCancelled()) {return false;}
ClientNewLoginKeyIncoming loginKeyIncoming = new ClientNewLoginKeyIncoming(
connection.waitForMessage(ClientNewLoginKeyIncoming.MESSAGE));
publishProgress(++mStages);
mLoginKey = loginKeyIncoming.mLoginKey;
if (isCancelled()) {return false;}
connection.sendMessage(new ClientNewLoginKeyAcceptedOutgoing(loginKeyIncoming.mUniqueID));
} catch (IncomingException e) {
return false;
} catch (OutgoingException e) {
return false;
}
return true;
}
@Override
void onCancelledWithRunID(boolean result) {
disconnect();
LoginAddActivity activity = mActivity;
if ((activity == null) || (activity.mCancelling == null)) {
return;
}
activity.mCancelling.dismiss();
activity.mCancelling = null;
activity.listenerAddOnClick(null);
}
@Override
void onPostExecuteWithRunID(boolean result) {
disconnect();
if (mActivity != null) {
mActivity.doneLoggingIn();
}
}
@Override
void onPreExecuteWithRunID() {}
@Override
protected void onProgressUpdate(Integer... progress) {
if (mActivity != null) {
mActivity.updateLoginProgress(progress[0]);
}
}
}
class LoginAddTextWatcher implements TextWatcher {
LoginAddActivity mActivity;
LoginAddTextWatcher(LoginAddActivity activity) {
mActivity = activity;
}
@Override
public void afterTextChanged(Editable s) {
mActivity.toggleButtonEnabled();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
}