/**
* Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
* This file is part of CSipSimple.
*
* CSipSimple is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* If you own a pjsip commercial license you can also redistribute it
* and/or modify it under the terms of the GNU Lesser General Public License
* as an android library.
*
* CSipSimple is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CSipSimple. If not, see <http://www.gnu.org/licenses/>.
*/
package com.csipsimple.wizards.impl;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import com.csipsimple.R;
import com.csipsimple.api.SipProfile;
import com.csipsimple.utils.Log;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.net.Socket;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MondotalkCreate extends Activity implements OnClickListener, TextWatcher {
private final static String API_KEY = "{7EB11554-7BAD-D25D-1D17-B070D4AC459F}";
private static final String THIS_FILE = "MondotalkCreate";
private ImageView captchaImg;
private View captchaProgress;
private EditText firstName;
private EditText lastName;
private EditText emailAddr;
private EditText countryCode;
private EditText phone;
private EditText captcha;
private ProgressDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.w_mondotalk_create);
findViewById(R.id.cancel_bt).setOnClickListener(this);
findViewById(R.id.save_bt).setOnClickListener(this);
captchaImg = (ImageView) findViewById(R.id.cw_captcha_img);
captchaProgress = findViewById(R.id.cw_captcha_progress);
firstName = (EditText) findViewById(R.id.cw_first_name);
lastName = (EditText) findViewById(R.id.cw_last_name);
emailAddr = (EditText) findViewById(R.id.cw_email);
countryCode = (EditText) findViewById(R.id.cw_country_code);
phone = (EditText) findViewById(R.id.cw_phone);
captcha = (EditText) findViewById(R.id.cw_captcha);
firstName.addTextChangedListener(this);
emailAddr.addTextChangedListener(this);
captcha.addTextChangedListener(this);
// Ok, crappy thread creation to retrieve captcha in bg
Thread t = new Thread() {
public void run() {
retrieveCaptcha();
};
};
t.start();
canSave();
}
@Override
protected void onDestroy() {
super.onDestroy();
if(captchaBitmap != null) {
captchaBitmap.recycle();
}
}
@Override
public void onClick(View v) {
int id = v.getId();
if(id == R.id.cancel_bt) {
setResult(RESULT_CANCELED);
finish();
}else if(id == R.id.save_bt) {
if(canSave()) {
progressDialog = ProgressDialog.show(this, getResources().getText(R.string.create_account),
getResources().getText(R.string.loading), true);
Thread t = new Thread() {
public void run() {
saveOnline(getEditTextValue(firstName), getEditTextValue(lastName),
getEditTextValue(emailAddr), getEditTextValue(phone),
getEditTextValue(countryCode), getEditTextValue(captcha));
};
};
t.start();
}
}
}
private final static int MSG_CAPTCHA_LOADED = 0;
private final static int MSG_SAVE_DONE = 1;
private final static int MSG_SAVE_ERROR = 2;
private Handler mHander = new MondotalkHandler(this);
private static class MondotalkHandler extends Handler {
WeakReference<MondotalkCreate> w;
MondotalkHandler(MondotalkCreate wizard){
w = new WeakReference<MondotalkCreate>(wizard);
}
public void dispatchMessage(Message msg) {
MondotalkCreate wizard = w.get();
if(wizard == null) {
return;
}
switch (msg.what) {
case MSG_CAPTCHA_LOADED:
if(wizard.captchaBitmap != null && wizard.captchaImg != null) {
wizard.captchaImg.setImageBitmap(wizard.captchaBitmap);
wizard.captchaImg.setVisibility(View.VISIBLE);
wizard.captchaProgress.setVisibility(View.GONE);
}
break;
case MSG_SAVE_DONE:
if(wizard.progressDialog != null) {
wizard.progressDialog.dismiss();
}
AccountCreationResult res = (AccountCreationResult) msg.obj;
Intent it = wizard.getIntent();
it.putExtra(SipProfile.FIELD_USERNAME, res.username);
it.putExtra(SipProfile.FIELD_DATA, res.password);
wizard.setResult(RESULT_OK, it);
wizard.finish();
break;
case MSG_SAVE_ERROR:
if(wizard.progressDialog != null) {
wizard.progressDialog.dismiss();
}
Toast toast = Toast.makeText(wizard, (String)msg.obj, Toast.LENGTH_LONG);
toast.show();
break;
}
};
};
private String captchaKey = "";
private String captchaUrl = "";
private Bitmap captchaBitmap = null;
private Pattern soapResultPattern = Pattern.compile("^.*<result xsi:type=\"xsd:string\">(.*)</result>.*$");
private boolean retrieveCaptcha() {
String ip;
try {
Socket socket = new Socket("api001.mondotalk.com", 80);
ip = socket.getLocalAddress().toString();
} catch (Exception e) {
Log.e(THIS_FILE,"Can't get local ip address", e);
ip = "127.0.0.1";
}
try {
// No SOAP lib.... bourrinage !
String requestURL = "https://api001.mondotalk.com/webservices/captcha.php";
HttpPost httpPost = new HttpPost(requestURL);
httpPost.addHeader("SOAPAction", "\"Captcha\"");
httpPost.addHeader("Content-Type", "text/xml");
// prepare POST body
String body = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<SOAP-ENV:Envelope " +
" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" " +
" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"" +
" xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\" " +
" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"" +
" xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\" >" +
"<SOAP-ENV:Body>" +
"<Captcha SOAP-ENC:root=\"1\">" +
"<v1 xsi:type=\"xsd:string\">" + API_KEY + "</v1>" +
"<v2 xsi:type=\"xsd:string\">" + ip + "</v2>" +
"<v3 xsi:type=\"xsd:string\">520</v3>" +
"<v4 xsi:type=\"xsd:string\">200</v4>" +
"</Captcha>" +
"</SOAP-ENV:Body>" +
"</SOAP-ENV:Envelope>";
// set POST body
HttpEntity entity;
entity = new StringEntity(body);
httpPost.setEntity(entity);
HttpClient httpClient = new DefaultHttpClient();
// Create a response handler
HttpResponse httpResponse = httpClient.execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode() == 200) {
InputStreamReader isr = new InputStreamReader(httpResponse.getEntity().getContent());
BufferedReader br = new BufferedReader(isr);
String line = null;
while( (line = br.readLine() ) != null ) {
if(!TextUtils.isEmpty(line)) {
Matcher matcher = soapResultPattern.matcher(line);
if(matcher.matches()) {
String strValue = matcher.group(1).trim();
if(!TextUtils.isEmpty(strValue)) {
String[] strValues = strValue.split("\\|");
if(strValues.length > 1) {
captchaUrl = strValues[0];
captchaKey = strValues[1];
}
}
break;
}
}
}
if(TextUtils.isEmpty(captchaKey)) {
return false;
}
Log.d(THIS_FILE, "Captcha retrieved " + captchaKey + " and " + captchaUrl);
captchaBitmap = BitmapFactory.decodeStream((new URL(captchaUrl)).openConnection() .getInputStream());
mHander.sendEmptyMessage(MSG_CAPTCHA_LOADED);
}else {
Log.e(THIS_FILE, "Something went wrong while retrieving the captcha webservice ");
}
} catch (Exception e) {
Log.e(THIS_FILE, "Something went wrong while retrieving the captcha", e);
}
return false;
}
/**
* Client side form validation.
*
* @return true if the form is valid for save
*/
private boolean canSave() {
boolean isValid = true;
isValid &= checkEmptyText(firstName);
isValid &= checkEmptyText(emailAddr);
isValid &= checkEmptyText(captcha);
// Update the status of the save button
findViewById(R.id.save_bt).setEnabled(isValid);
return isValid;
}
/**
* Get the value of an edit text a safe way
* @param txt The edit text to get value of
* @return the Text value of the edit text
*/
private String getEditTextValue(EditText txt) {
if(txt == null) {
return "";
}
String res = txt.getText().toString();
if(TextUtils.isEmpty(res)) {
return "";
}
return res;
}
private boolean checkEmptyText(EditText txt) {
if(TextUtils.isEmpty(txt.getText().toString())) {
txt.setError("Empty");
return false;
}
txt.setError(null);
return true;
}
private class AccountCreationResult {
final String username;
final String password;
AccountCreationResult(String uname, String pwd){
username = uname;
password = pwd;
}
}
private boolean saveOnline(String firstName, String lastName, String contactEmail, String contactPhone, String countryCode, String captcha) {
try {
// No SOAP lib.... bourrinage !
String requestURL = "https://api001.mondotalk.com/webservices/createaccount.php";
HttpPost httpPost = new HttpPost(requestURL);
httpPost.addHeader("SOAPAction", "\"CreateAccount\"");
httpPost.addHeader("Content-Type", "text/xml");
// prepare POST body
String body = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<SOAP-ENV:Envelope " +
" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" " +
" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"" +
" xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\" " +
" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"" +
" xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\" >" +
"<SOAP-ENV:Body>" +
"<CreateAccount SOAP-ENC:root=\"1\">" +
"<v1 xsi:type=\"xsd:string\">" + API_KEY + "</v1>" +
"<v2 xsi:type=\"xsd:string\">" + firstName + "</v2>" +
"<v3 xsi:type=\"xsd:string\">" + lastName + "</v3>" +
"<v4 xsi:type=\"xsd:string\">" + contactEmail + "</v4>" +
"<v5 xsi:type=\"xsd:string\">" + contactPhone + "</v5>" +
"<v6 xsi:type=\"xsd:string\">" + countryCode + "</v6>" +
"<v7 xsi:type=\"xsd:string\">" + captcha + "</v7>" +
"<v8 xsi:type=\"xsd:string\">" + captchaKey + "</v8>" +
"</CreateAccount>" +
"</SOAP-ENV:Body>" +
"</SOAP-ENV:Envelope>";
// set POST body
HttpEntity entity;
entity = new StringEntity(body);
httpPost.setEntity(entity);
HttpClient httpClient = new DefaultHttpClient();
// Create a response handler
HttpResponse httpResponse = httpClient.execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode() == 200) {
InputStreamReader isr = new InputStreamReader(httpResponse.getEntity().getContent());
BufferedReader br = new BufferedReader(isr);
String line = null;
String username = "";
String password = "";
while( (line = br.readLine() ) != null ) {
if(!TextUtils.isEmpty(line)) {
Matcher matcher = soapResultPattern.matcher(line);
if(matcher.matches()) {
String strValue = matcher.group(1).trim();
if(!TextUtils.isEmpty(strValue)) {
String[] strValues = strValue.split("\\|");
if(strValues.length > 1) {
username = strValues[0];
password = strValues[1];
}
}
break;
}
}
}
Log.d(THIS_FILE, "Account created " + username);
if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) {
mHander.sendMessage(mHander.obtainMessage(MSG_SAVE_ERROR, "Invalid datas to create the account"));
return false;
}
AccountCreationResult res = new AccountCreationResult(username, password);
mHander.sendMessage(mHander.obtainMessage(MSG_SAVE_DONE, res));
return true;
}else {
Log.e(THIS_FILE, "Something went wrong while retrieving the captcha webservice ");
}
} catch (Exception e) {
Log.e(THIS_FILE, "Can't create account", e);
}
mHander.sendMessage(mHander.obtainMessage(MSG_SAVE_ERROR, "Error while creating the account"));
return false;
}
@Override
public void afterTextChanged(Editable s) {
canSave();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Nothing to do
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Nothing to do
}
}