package com.aptoide.amethyst;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.util.Log;
import android.view.ContextThemeWrapper;
import com.aptoide.amethyst.Aptoide;
import com.aptoide.amethyst.AptoideBaseActivity;
import com.aptoide.amethyst.utils.AptoideUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.ext.DefaultHandler2;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeoutException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class AutoUpdate extends AsyncTask<Void, Void, AutoUpdate.AutoUpdateInfo> {
private final String TMP_UPDATE_FILE = Aptoide.getConfiguration().getPathCache() + "aptoideUpdate.apk";
private final String url = Aptoide.getConfiguration().getAutoUpdateUrl();
private AptoideBaseActivity activity;
public AutoUpdate(AptoideBaseActivity activity){
this.activity=activity;
}
@Override
protected AutoUpdateInfo doInBackground(Void... params) {
try {
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
AutoUpdateHandler autoUpdateHandler = new AutoUpdateHandler();
Log.d("TAG", "Requesting auto-update from " + url);
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
parser.parse(connection.getInputStream(),autoUpdateHandler);
return autoUpdateHandler.getAutoUpdateInfo();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(AutoUpdateInfo autoUpdateInfo) {
super.onPostExecute(autoUpdateInfo);
if(autoUpdateInfo!=null){
String packageName = activity.getPackageName();
int vercode = autoUpdateInfo.vercode;
int minsdk = autoUpdateInfo.minsdk;
int minvercode = autoUpdateInfo.minAptoideVercode;
try {
int localVersionCode = activity.getPackageManager().getPackageInfo(packageName, 0).versionCode;
if(vercode > localVersionCode && localVersionCode > minvercode && Build.VERSION.SDK_INT >= minsdk || Aptoide.getConfiguration().isAlwaysUpdate()){
requestUpdateSelf(autoUpdateInfo);
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
}
private void requestUpdateSelf(final AutoUpdateInfo autoUpdateInfo) {
ContextThemeWrapper wrapper = new ContextThemeWrapper(activity, activity.obtainStyledAttributes(new int[]{R.attr.alertDialog}).getResourceId(0, 0));
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(wrapper);
final AlertDialog updateSelfDialog = dialogBuilder.create();
updateSelfDialog.setTitle(activity.getText(R.string.update_self_title));
updateSelfDialog.setIcon(Aptoide.getConfiguration().getIcon());
updateSelfDialog.setMessage(AptoideUtils.StringUtils.getFormattedString(activity, R.string.update_self_msg, Aptoide.getConfiguration().getMarketName()));
updateSelfDialog.setCancelable(false);
updateSelfDialog.setButton(Dialog.BUTTON_POSITIVE, activity.getString(android.R.string.yes), new Dialog.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
new DownloadSelfUpdate().execute(autoUpdateInfo);
//FlurryAgent.logEvent("Auto_Update_Clicked_On_Yes_Button"); TODO include
}
});
updateSelfDialog.setButton(Dialog.BUTTON_NEGATIVE, activity.getString(android.R.string.no), new Dialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int arg1) {
//FlurryAgent.logEvent("Auto_Update_Clicked_On_No_Button");TODO include
dialog.dismiss();
}
});
if(activity.is_resumed()) {
updateSelfDialog.show();
}
}
private class AutoUpdateHandler extends DefaultHandler2 {
AutoUpdateInfo info = new AutoUpdateInfo();
private AutoUpdateInfo getAutoUpdateInfo() {
return info;
}
private StringBuilder sb = new StringBuilder();
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
sb.setLength(0);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
sb.append(ch,start,length);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
if(localName.equals("versionCode")){
info.vercode = Integer.parseInt(sb.toString());
}else if(localName.equals("uri")){
info.path = sb.toString();
}else if(localName.equals("md5")){
info.md5 = sb.toString();
}else if(localName.equals("minSdk")){
info.minsdk = Integer.parseInt(sb.toString());
}else if(localName.equals("minAptVercode")){
info.minAptoideVercode = Integer.parseInt(sb.toString());
}
}
}
static class AutoUpdateInfo{
String md5;
int vercode;
String path;
int minsdk = 0;
public int minAptoideVercode = 0;
}
private class DownloadSelfUpdate extends AsyncTask<AutoUpdateInfo, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(activity);
String latestVersionUri;
String referenceMd5;
void retrieveUpdateParameters(AutoUpdateInfo autoUpdateInfo) {
try {
latestVersionUri = autoUpdateInfo.path;
referenceMd5 = autoUpdateInfo.md5;
} catch (Exception e) {
e.printStackTrace();
Log.d("Aptoide-Auto-Update", "Update connection failed! Keeping current version.");
}
}
@Override
protected void onPreExecute() {
this.dialog.setMessage(activity.getString(R.string.retrieving_update));
this.dialog.show();
super.onPreExecute();
}
@Override
protected Void doInBackground(AutoUpdateInfo... paramArrayOfParams) {
try {
retrieveUpdateParameters(paramArrayOfParams[0]);
File f_chk = new File(TMP_UPDATE_FILE);
if (f_chk.exists()) {
f_chk.delete();
}
FileOutputStream saveit = new FileOutputStream(TMP_UPDATE_FILE);
DefaultHttpClient mHttpClient = new DefaultHttpClient();
HttpGet mHttpGet = new HttpGet(latestVersionUri);
HttpResponse mHttpResponse = mHttpClient.execute(mHttpGet);
if (mHttpResponse == null) {
Log.d("Aptoide", "Problem in network... retry...");
mHttpResponse = mHttpClient.execute(mHttpGet);
if (mHttpResponse == null) {
Log.d("Aptoide", "Major network exception... Exiting!");
saveit.close();
throw new TimeoutException();
}
}
if (mHttpResponse.getStatusLine().getStatusCode() == 401) {
saveit.close();
throw new TimeoutException();
} else {
InputStream getit = mHttpResponse.getEntity().getContent();
byte data[] = new byte[8096];
int bytesRead;
bytesRead = getit.read(data, 0, 8096);
while (bytesRead != -1) {
saveit.write(data, 0, bytesRead);
bytesRead = getit.read(data, 0, 8096);
}
Log.d("Aptoide", "Download done!");
saveit.flush();
saveit.close();
getit.close();
}
} catch (Exception e) {
e.printStackTrace();
Log.d("Aptoide-Auto-Update", "Update connection failed! Keeping current version.");
}
return null;
}
@Override
protected void onPostExecute(Void result) {
if (activity.is_resumed() && this.dialog.isShowing()) {
this.dialog.dismiss();
}
super.onPostExecute(result);
if (!(referenceMd5 == null)) {
try {
File apk = new File(TMP_UPDATE_FILE);
if (referenceMd5.equalsIgnoreCase(AptoideUtils.Algorithms.md5Calc(apk))) {
doUpdateSelf();
} else {
Log.d("Aptoide", referenceMd5 + " VS " + AptoideUtils.Algorithms.md5Calc(apk));
throw new Exception(referenceMd5 + " VS " + AptoideUtils.Algorithms.md5Calc(apk));
}
} catch (Exception e) {
e.printStackTrace();
Log.d("Aptoide-Auto-Update", "Update package checksum failed! Keeping current version.");
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
super.onPostExecute(result);
}
}
}
}
private void doUpdateSelf() {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://" + TMP_UPDATE_FILE), "application/vnd.android.package-archive");
activity.startActivityForResult(intent, 99);
}
}