package net.hockeyapp.android.tasks;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.widget.Toast;
import net.hockeyapp.android.R;
import net.hockeyapp.android.UpdateActivity;
import net.hockeyapp.android.UpdateFragment;
import net.hockeyapp.android.UpdateManagerListener;
import net.hockeyapp.android.utils.HockeyLog;
import net.hockeyapp.android.utils.Util;
import net.hockeyapp.android.utils.VersionCache;
import org.json.JSONArray;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
/**
* <h3>Description</h3>
*
* Internal helper class. Checks if a new update is available by
* fetching version data from Hockeyapp.
*
**/
public class CheckUpdateTaskWithUI extends CheckUpdateTask {
private Activity mActivity = null;
private AlertDialog mDialog = null;
protected boolean mIsDialogRequired = false;
public CheckUpdateTaskWithUI(WeakReference<Activity> weakActivity, String urlString, String appIdentifier, UpdateManagerListener listener, boolean isDialogRequired) {
super(weakActivity, urlString, appIdentifier, listener);
if (weakActivity != null) {
mActivity = weakActivity.get();
}
this.mIsDialogRequired = isDialogRequired;
}
@Override
public void detach() {
super.detach();
mActivity = null;
if (mDialog != null) {
mDialog.dismiss();
mDialog = null;
}
}
@Override
protected void onPostExecute(JSONArray updateInfo) {
super.onPostExecute(updateInfo);
if ((updateInfo != null) && (mIsDialogRequired)) {
showDialog(updateInfo);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void showDialog(final JSONArray updateInfo) {
//Reason for enabled Caching
//we want to prevent users from being able to weasle around mandatory updates by going offline.
if (getCachingEnabled()) {
HockeyLog.verbose("HockeyUpdate", "Caching is enabled. Setting version to cached one.");
VersionCache.setVersionInfo(mActivity, updateInfo.toString());
}
if ((mActivity == null) || (mActivity.isFinishing())) {
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(R.string.hockeyapp_update_dialog_title);
if (!mandatory) {
builder.setMessage(R.string.hockeyapp_update_dialog_message);
builder.setNegativeButton(R.string.hockeyapp_update_dialog_negative_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
cleanUp();
if (null != listener) {
listener.onCancel();
}
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
cleanUp();
if (null != listener) {
listener.onCancel();
}
}
});
builder.setPositiveButton(R.string.hockeyapp_update_dialog_positive_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (getCachingEnabled()) {
VersionCache.setVersionInfo(mActivity, "[]");
}
WeakReference<Activity> weakActivity = new WeakReference<Activity>(mActivity);
if ((Util.fragmentsSupported()) && (Util.runsOnTablet(weakActivity))) {
showUpdateFragment(updateInfo);
} else {
startUpdateIntent(updateInfo, false);
}
}
});
mDialog = builder.create();
mDialog.show();
} else {
String appName = Util.getAppName(mActivity);
String toast = String.format(mActivity.getString(R.string.hockeyapp_update_mandatory_toast),
appName);
Toast.makeText(mActivity, toast, Toast.LENGTH_LONG).show();
startUpdateIntent(updateInfo, true);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void showUpdateFragment(final JSONArray updateInfo) {
if (mActivity != null) {
FragmentTransaction fragmentTransaction = mActivity.getFragmentManager().beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
Fragment existingFragment = mActivity.getFragmentManager().findFragmentByTag("hockey_update_dialog");
if (existingFragment != null) {
fragmentTransaction.remove(existingFragment);
}
fragmentTransaction.addToBackStack(null);
// Create and show the dialog
Class<? extends UpdateFragment> fragmentClass = UpdateFragment.class;
if (listener != null) {
fragmentClass = listener.getUpdateFragmentClass();
}
try {
Method method = fragmentClass.getMethod("newInstance", JSONArray.class, String.class);
DialogFragment updateFragment = (DialogFragment) method.invoke(null, updateInfo, getURLString("apk"));
updateFragment.show(fragmentTransaction, "hockey_update_dialog");
} catch (Exception e) { // can't catch ReflectiveOperationException here because not targeting API level 19 or later
HockeyLog.error("An exception happened while showing the update fragment:");
e.printStackTrace();
HockeyLog.error("Showing update activity instead.");
startUpdateIntent(updateInfo, false);
}
}
}
private void startUpdateIntent(final JSONArray updateInfo, Boolean finish) {
Class<?> activityClass = null;
if (listener != null) {
activityClass = listener.getUpdateActivityClass();
}
if (activityClass == null) {
activityClass = UpdateActivity.class;
}
if (mActivity != null) {
Intent intent = new Intent();
intent.setClass(mActivity, activityClass);
intent.putExtra(UpdateActivity.EXTRA_JSON, updateInfo.toString());
intent.putExtra(UpdateActivity.EXTRA_URL, getURLString(APK));
mActivity.startActivity(intent);
if (finish) {
mActivity.finish();
}
}
cleanUp();
}
@Override
protected void cleanUp() {
super.cleanUp();
mActivity = null;
mDialog = null;
}
}