package com.xiaomi.xms.sales.xmsf.account.ui;
import java.io.IOException;
import java.net.URLEncoder;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import com.xiaomi.xms.sales.R;
import com.xiaomi.xms.sales.activity.BaseActivity;
import com.xiaomi.xms.sales.activity.ICUMainActivity;
import com.xiaomi.xms.sales.activity.MainActivity;
import com.xiaomi.xms.sales.model.Tags;
import com.xiaomi.xms.sales.model.UserInfo;
import com.xiaomi.xms.sales.request.ExtendedAuthToken;
import com.xiaomi.xms.sales.request.HostManager;
import com.xiaomi.xms.sales.request.Request;
import com.xiaomi.xms.sales.util.Constants;
import com.xiaomi.xms.sales.util.Device;
import com.xiaomi.xms.sales.util.JsonUtil;
import com.xiaomi.xms.sales.util.LogUtil;
import com.xiaomi.xms.sales.util.ToastUtil;
import com.xiaomi.xms.sales.util.Utils;
import com.xiaomi.xms.sales.xmsf.account.LoginManager;
import com.xiaomi.xms.sales.xmsf.account.data.AccountInfo;
import com.xiaomi.xms.sales.xmsf.account.exception.AccessDeniedException;
import com.xiaomi.xms.sales.xmsf.account.exception.InvalidCredentialException;
import com.xiaomi.xms.sales.xmsf.account.exception.InvalidResponseException;
import com.xiaomi.xms.sales.xmsf.account.utils.CloudHelper;
public class LoginActivity extends BaseActivity implements
LoginInputFragment.OnLoginInterface,
LoginProgressFragment.OnLoginProgressInterface,
LoginFailureFragment.OnLoginFailureInterface {
private static final String TAG = "LoginActivity";
private static final int ERROR_PASSWORD = 1;
private static final int ERROR_NETWORK = 2;
private static final int ERROR_SERVER = 3;
private static final int ERROR_FORBIDDEN = 4;
private static final int ERROR_MIHOME_FORBIDDEN = 5;
public static final String KEY_USER_ID = "key_user_id";
public static final String KEY_SERVICE_TOKEN = "key_service_token";
public static final String KEY_SECURITY = "key_security";
private LoginTask mLoginTask;
private String mServiceUrl;
private boolean mActivityStatusSaved;
private LoginResult mLoginResult;
private FragmentManager mFragmentManager;
private LoginInputFragment mLoginInputFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setCustomContentView(R.layout.login_activity);
setTitle(getString(R.string.app_name));
Intent intent = getIntent();
final String serviceUrl = intent.getStringExtra(Constants.Account.EXTRA_SERVICE_URL);
if (TextUtils.isEmpty(serviceUrl)) {
throw new IllegalStateException("empty service id or service url");
}
mServiceUrl = serviceUrl;
mFragmentManager = getSupportFragmentManager();
mLoginInputFragment = new LoginInputFragment();
mLoginInputFragment.setOnLoginInterface(this);
mFragmentManager.beginTransaction().add(R.id.fragment_container, mLoginInputFragment).commit();
setShoppingBarEnable(false);
setHomeButtonEnable(false);
}
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
return false;// 返回为true 则显示系统menu
}
@Override
protected void onResume() {
super.onResume();
mActivityStatusSaved = false;
handleLoginResult(mLoginResult, true);
displayOrHideSoftInput();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mActivityStatusSaved = true;
}
@Override
protected void onDestroy() {
if (mLoginTask != null) {
mLoginTask.cancel(true);
mLoginTask = null;
}
handleLoginResult(mLoginResult, false);
super.onDestroy();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
private void displayOrHideSoftInput() {
if (mFragmentManager.getBackStackEntryCount() > 0) {
hideSoftInput();
}
}
private void hideSoftInput() {
// hide soft keyboard
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
}
private void tryLogin(String username, String pwd) {
// begin login
if (mLoginTask != null) {
mLoginTask.cancel(true);
}
if(username.equals("icu") && pwd.equals("123456")){
Intent intent = new Intent(this, ICUMainActivity.class);
startActivity(intent);
}else{
ToastUtil.show(getApplicationContext(), R.string.login_err);
}
finish();
// mLoginTask = new LoginTask(username, pwd, mServiceUrl);
// mLoginTask.execute();
}
@Override
public void onStartLogin(String userName, String pwd) {
tryLogin(userName, pwd);
}
@Override
public void onLoginCanceled() {
if (mLoginTask != null) {
mLoginTask.cancel(true);
mLoginTask = null;
}
popupFragment();
}
@Override
public void onCancelLoginAfterFailure() {
popupFragment();
}
@Override
public void onRetryLoginAfterFailure(String username, String pwd) {
popupFragment();
tryLogin(username, pwd);
}
public void onLoginSuccess(AccountInfo accountInfo) {
String userId = accountInfo.getUserId();
String serviceToken = accountInfo.getServiceToken();
String passToken = accountInfo.getPassToken();
String security = accountInfo.getSecurity();
Utils.Preference.setStringPref(this, Constants.Account.PREF_UID, userId);
Utils.Preference.setStringPref(this, Constants.Account.PREF_PASS_TOKEN, passToken);
Utils.Preference.setStringPref(this, Constants.Account.PREF_EXTENDED_TOKEN, ExtendedAuthToken
.build(serviceToken, security).toPlain());
}
private void popupFragment() {
mFragmentManager.popBackStack();
}
private void replaceFragment(Fragment f, boolean popupTop, boolean addToBackStack) {
FragmentTransaction transaction = mFragmentManager.beginTransaction();
if (popupTop) {
popupFragment();
}
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.replace(android.R.id.content, f, f.getClass().getSimpleName());
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.commitAllowingStateLoss();
}
/**
* handle login result
*
* @param result contains login and result info
* @param updateUI whether display the successful or failure info
*/
private void handleLoginResult(LoginResult result, boolean updateUI) {
if (result != null && (!mActivityStatusSaved || !updateUI)) {
// getFragmentManager().popBackStack cannot be called after
// onSaveInstanceState
AccountInfo accountInfo = result.accountInfo;
if (accountInfo != null) {
String userId = accountInfo.getUserId();
String serviceToken = accountInfo.getServiceToken();
String security = accountInfo.getSecurity();
onLoginSuccess(accountInfo);
LoginManager.getInstance().onAccountLoginSucceed(userId, serviceToken, security);
MainActivity.launchMain(LoginActivity.this, MainActivity.FRAGMENT_TAG_HOME);
finish();
} else if (updateUI) {
LogUtil.d(TAG, "login failure");
String reason;
switch (result.errorCode) {
case ERROR_NETWORK: {
reason = getString(R.string.error_network);
break;
}
case ERROR_PASSWORD: {
reason = getString(R.string.bad_authentication);
break;
}
case ERROR_SERVER: {
reason = getString(R.string.error_server);
break;
}
case ERROR_FORBIDDEN: {
reason = getString(R.string.access_denied);
break;
}
case ERROR_MIHOME_FORBIDDEN: {
reason = result.errorInfo;
break;
}
default: {
reason = getString(R.string.error_unknown);
break;
}
}
LoginFailureFragment f = new LoginFailureFragment();
f.setOnLoginFailureInterface(LoginActivity.this);
f.setGetUserInputInterface(mLoginInputFragment);
Bundle args = new Bundle();
args.putString("reason", reason);
args.putString("username", result.username);
args.putString("pwd", result.password);
f.setArguments(args);
replaceFragment(f, true, true);
}
mLoginResult = null;
}
}
private class LoginTask extends AsyncTask<String, Void, LoginResult> {
private String username;
private String password;
private String serviceId;
private LoginProgressFragment mLoginProgressFragment;
private LoginTask(String username, String password, String serviceId) {
this.username = username;
this.password = password;
this.serviceId = serviceId;
}
@Override
protected void onPreExecute() {
hideSoftInput();
LoginProgressFragment f = new LoginProgressFragment();
f.setOnLoginProgressInterface(LoginActivity.this);
replaceFragment(f, false, true);
mLoginProgressFragment = f;
}
@Override
protected void onPostExecute(LoginResult result) {
mLoginResult = result;
handleLoginResult(result, true);
}
@Override
protected LoginResult doInBackground(String... args) {
final String name = this.username;
final String pwd = this.password;
// perform login
AccountInfo accountInfo;
try {
accountInfo = CloudHelper
.getServiceTokenByPassword(name, pwd, serviceId);
} catch (InvalidCredentialException e) {
e.printStackTrace();
return new LoginResult(null, ERROR_PASSWORD, "", serviceId,
username, pwd);
} catch (InvalidResponseException e) {
e.printStackTrace();
return new LoginResult(null, ERROR_SERVER, "", serviceId,
username, pwd);
} catch (IOException e) {
e.printStackTrace();
return new LoginResult(null, ERROR_NETWORK, "", serviceId,
username, pwd);
} catch (AccessDeniedException e) {
e.printStackTrace();
return new LoginResult(null, ERROR_FORBIDDEN, "", serviceId,
username, pwd);
}
if (accountInfo != null && !isCancelled()) {
LogUtil.d(TAG, "login success, service token:" + accountInfo.getServiceToken());
// 判断该用户是否有米家的权限
Request request = new Request(HostManager.URL_XMS_SALE_API);
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put(Tags.XMSAPI.USERID, accountInfo.getUserId());
jsonObject.put(Tags.XMSAPI.IMEI, Device.IMEI);
String data = JsonUtil.creatRequestJson(HostManager.Method.METHOD_GETUSERINFO, jsonObject);
if (!TextUtils.isEmpty(data)) {
request.addParam(Tags.RequestKey.DATA, data);
if (request.getStatus() == Request.STATUS_OK) {
JSONObject json = request.requestJSON();
if (Tags.isJSONReturnedOK(json)) {
UserInfo userInfo = UserInfo.fromJSONObject(json);
if (userInfo != null) {
// @HACKME XM_[userId]_UN
// 这个cookie是用来记录用户的用户名,给Web中使用
HostManager.setCookie(LoginActivity.this, "XM_" + userInfo.getUserId()
+ "_UN", URLEncoder.encode(userInfo.getUserName()),
HostManager.DOMAIN_BASE);
}
saveUserName(username);
return new LoginResult(accountInfo, Activity.RESULT_OK, "",
serviceId, username, password);
} else {
return new LoginResult(null, ERROR_MIHOME_FORBIDDEN, json.optJSONObject(Tags.HEADER)
.optString(Tags.DESC), serviceId, username, pwd);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.w(TAG, "login failure");
}
Log.w(TAG, "failed to get service token");
return new LoginResult(null, ERROR_SERVER, "", serviceId,
username, pwd);
}
}
private class LoginResult {
final AccountInfo accountInfo;
final int errorCode;
final String errorInfo;
final String serviceId;
final String username;
final String password;
private LoginResult(AccountInfo accountInfo, int errorCode, String errorInfo,
String serviceId, String username, String pwd) {
this.accountInfo = accountInfo;
this.errorCode = errorCode;
this.errorInfo = errorInfo;
this.serviceId = serviceId;
this.username = username;
this.password = pwd;
}
}
private void saveUserName(String username) {
String userNames = Utils.Preference.getStringPref(LoginActivity.this, Constants.Account.PREF_USER_NAMES, "");
StringBuilder newUserNames = new StringBuilder(userNames);
if (!TextUtils.isEmpty(userNames)) {
// 防止同一账户重复添加
if (newUserNames.indexOf(username) == -1) {
String[] userNamesArray = userNames.split(Constants.Account.USER_NAME_SEPARATOR);
// 使保存的帐号不多于5个
if (userNamesArray.length > 4) {
newUserNames.delete(0, newUserNames.indexOf(Constants.Account.USER_NAME_SEPARATOR) + 1);
}
newUserNames.append(Constants.Account.USER_NAME_SEPARATOR);
newUserNames.append(username);
}
} else {
newUserNames.append(username);
}
Utils.Preference.setStringPref(LoginActivity.this, Constants.Account.PREF_USER_NAMES, newUserNames.toString());
}
}