package openeclairupdaterapp.ui;
import org.openeclair.update.R;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;
import openeclairupdaterapp.customTypes.FullUpdateInfo;
import openeclairupdaterapp.customTypes.UpdateInfo;
import openeclairupdaterapp.customization.Customization;
import openeclairupdaterapp.listadapters.UpdateListAdapter;
import openeclairupdaterapp.tasks.MD5CheckerTask;
import openeclairupdaterapp.tasks.UpdateCheckTask;
import openeclairupdaterapp.utils.Preferences;
import openeclairupdaterapp.utils.StringUtils;
import openeclairupdaterapp.utils.SysUtils;
import openeclairupdaterapp.utils.UpdateFilter;
import openeclairupdaterapp.misc.Constants;
import openeclairupdaterapp.misc.Log;
import openeclairupdaterapp.misc.State;
import openeclairupdaterapp.changelog.*;
import openeclairupdaterapp.changelog.Changelog.ChangelogType;
public class MainActivity extends Activity
{
private static final String TAG = "MainActivity";
private Boolean showDebugOutput = false;
private Spinner mUpdatesSpinner;
private Spinner mThemesSpinner;
private FullUpdateInfo mAvailableUpdates;
private File mUpdateFolder;
private Spinner mExistingUpdatesSpinner;
private ProgressDialog ChangelogProgressDialog;
public static Handler ChangelogProgressHandler;
private Thread ChangelogThread;
private List<Version> ChangelogList = null;
private List<String> mfilenames;
private TextView mdownloadedUpdateText;
private Spinner mspFoundUpdates;
private Button mdeleteOldUpdatesButton;
private Button mapplyUpdateButton;
private TextView mNoExistingUpdatesFound;
private ViewFlipper flipper;
private Preferences prefs;
private Resources res;
private Boolean runningOldVersion = false;
private Button btnAvailableUpdates;
private Button btnExistingUpdates;
private Button btnAvailableThemes;
private TextView experimentalBuildsRomtv;
private TextView showDowngradesRomtv;
private TextView experimentalBuildsThemetv;
private TextView showDowngradesThemetv;
private TextView lastRomUpdateChecktv;
private TextView lastThemeUpdateChecktv;
private Button selectUploadButton;
private TextView DownloadText;
private LinearLayout stableExperimentalInfoUpdates;
private Button changelogButton;
private Button btnDownloadTheme;
private TextView tvThemeDownloadText;
private LinearLayout stableExperimentalInfoThemes;
private Button btnThemechangelogButton;
private Button btnThemeScreenshotButton;
private TextView tvNoThemeUpdateServer;
private Button CheckNowUpdateChooserUpdates;
private TextView CheckNowUpdateChooserTextUpdates;
private Button CheckNowUpdateChooserThemes;
private TextView CheckNowUpdateChooserTextThemes;
private AsyncTask<File, Void, Boolean> md5CheckerTask;
private View.OnClickListener ButtonOnClickListener = new View.OnClickListener()
{
public void onClick(View v)
{
switch (v.getId())
{
case R.id.theme_screenshots_button:
ScreenshotThemesListener();
break;
case R.id.download_update_button:
DownloadUpdateButtonListener();
break;
case R.id.download_theme_button:
DownloadThemeButtonListener();
break;
case R.id.show_changelog_button:
UpdateChangelogButtonListener();
break;
case R.id.show_theme_changelog_button:
ThemeChangelogButtonListener();
break;
case R.id.check_now_button_update_chooser_updates:
checkForUpdates();
break;
case R.id.check_now_button_update_chooser_themes:
checkForUpdates();
break;
case R.id.delete_updates_button:
DeleteUpdatesButtonListener();
break;
case R.id.apply_update_button:
ApplyExistingButtonListener();
break;
}
}
};
private void ScreenshotThemesListener()
{
if (showDebugOutput) Log.d(TAG, "Theme Screenshot Button clicked");
final UpdateInfo ui = (UpdateInfo) mThemesSpinner.getSelectedItem();
Intent i = new Intent(MainActivity.this, ScreenshotActivity.class);
i.putExtra(Constants.SCREENSHOTS_UPDATE, (Serializable)ui);
startActivity(i);
return;
}
private void DownloadUpdateButtonListener()
{
if(!Environment.MEDIA_MOUNTED.equalsIgnoreCase(Environment.getExternalStorageState()))
{
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.sdcard_is_not_present_dialog_title)
.setMessage(R.string.sdcard_is_not_present_dialog_body)
.setPositiveButton(R.string.sdcard_is_not_present_dialog_ok_button, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.show();
return;
}
if (showDebugOutput) Log.d(TAG, "Download Rom Button clicked");
final UpdateInfo ui = (UpdateInfo) mUpdatesSpinner.getSelectedItem();
//Check if the File is present, so prompt the User to overwrite it
final File foo = new File(mUpdateFolder + "/" + ui.getFileName());
if (foo.isFile() && foo.exists())
{
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.overwrite_update_title)
.setMessage(R.string.overwrite_update_summary)
.setNegativeButton(R.string.overwrite_update_negative, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.setPositiveButton(R.string.overwrite_update_positive, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
if (showDebugOutput) Log.d(TAG, "Start downlading Rom update: " + ui.getFileName());
foo.delete();
downloadRequestedUpdate(ui);
}
})
.show();
return;
}
//Otherwise download it
else
{
downloadRequestedUpdate((UpdateInfo) mUpdatesSpinner.getSelectedItem());
}
}
private void DownloadThemeButtonListener()
{
if(!Environment.MEDIA_MOUNTED.equalsIgnoreCase(Environment.getExternalStorageState()))
{
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.sdcard_is_not_present_dialog_title)
.setMessage(R.string.sdcard_is_not_present_dialog_body)
.setPositiveButton(R.string.sdcard_is_not_present_dialog_ok_button, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.show();
return;
}
if (showDebugOutput) Log.d(TAG, "Download Theme Button clicked");
final UpdateInfo ui = (UpdateInfo) mThemesSpinner.getSelectedItem();
//Check if the File is present, so prompt the User to overwrite it
File foo = new File(mUpdateFolder + "/" + ui.getFileName());
if (foo.isFile() && foo.exists())
{
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.overwrite_update_title)
.setMessage(R.string.overwrite_update_summary)
.setNegativeButton(R.string.overwrite_update_negative, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.setPositiveButton(R.string.overwrite_update_positive, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
if (showDebugOutput) Log.d(TAG, "Start downlading Theme update: " + ui.getFileName());
downloadRequestedUpdate((UpdateInfo) mThemesSpinner.getSelectedItem());
}
})
.show();
return;
}
//Otherwise download it
else
{
downloadRequestedUpdate((UpdateInfo) mThemesSpinner.getSelectedItem());
}
}
private void UpdateChangelogButtonListener()
{
if (showDebugOutput) Log.d(TAG, "Rom Changelog Button clicked");
getChangelog(ChangelogType.ROM);
}
private void ThemeChangelogButtonListener()
{
if (showDebugOutput) Log.d(TAG, "Theme Changelog Button clicked");
getChangelog(ChangelogType.THEME);
}
private void DeleteUpdatesButtonListener()
{
if(!Environment.MEDIA_MOUNTED.equalsIgnoreCase(Environment.getExternalStorageState()))
{
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.sdcard_is_not_present_dialog_title)
.setMessage(R.string.sdcard_is_not_present_dialog_body)
.setPositiveButton(R.string.sdcard_is_not_present_dialog_ok_button, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.show();
return;
}
else
{
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.delete_updates_text)
.setMessage(R.string.confirm_delete_update_folder_dialog_message)
//Delete Only Selected Update
.setNeutralButton(R.string.confirm_delete_update_folder_dialog_neutral, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
//Delete Updates here
String f = (String) mExistingUpdatesSpinner.getSelectedItem();
if (showDebugOutput) Log.d(TAG, "Delete single Update selected: " + f);
if(deleteUpdate(f))
mfilenames.remove(f);
switchToUpdateChooserLayout();
}
})
//Delete All Updates
.setPositiveButton(R.string.confirm_delete_update_folder_dialog_yes, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
if (showDebugOutput) Log.d(TAG, "Delete all Updates selected");
//Delete Updates here
//Set the Filenames to null, so the Spinner will be empty
if(deleteOldUpdates())
mfilenames = null;
switchToUpdateChooserLayout();
}
})
//Delete no Update
.setNegativeButton(R.string.confirm_delete_update_folder_dialog_no, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
if (showDebugOutput) Log.d(TAG, "Delete no updates selected");
dialog.dismiss();
}
})
.show();
}
}
private void ApplyExistingButtonListener()
{
ProgressDialog mDialog;
final String filename;
File Update;
if(!Environment.MEDIA_MOUNTED.equalsIgnoreCase(Environment.getExternalStorageState()))
{
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.sdcard_is_not_present_dialog_title)
.setMessage(R.string.sdcard_is_not_present_dialog_body)
.setPositiveButton(R.string.sdcard_is_not_present_dialog_ok_button, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.show();
return;
}
if (runningOldVersion)
{
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.alert_old_version_title)
.setMessage(R.string.alert_old_version_summary)
.setPositiveButton(R.string.alert_old_version_ok, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.setNegativeButton(R.string.alert_old_version_browser, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
//Open the Browser for Instructions
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(Customization.UPDATE_INSTRUCTIONS_URL));
startActivity(i);
dialog.dismiss();
}
})
.show();
}
filename = (String) mExistingUpdatesSpinner.getSelectedItem();
if (showDebugOutput) Log.d(TAG, "Selected to Apply Existing update: " + filename);
Update = new File(mUpdateFolder + "/" +filename);
File MD5 = new File(mUpdateFolder + "/" +filename + ".md5sum");
//IF no MD5 exists, ask the User what to do
if(!MD5.exists() || !MD5.canRead())
{
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.no_md5_found_title)
.setMessage(R.string.no_md5_found_summary)
.setPositiveButton(R.string.no_md5_found_positive, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
//Directly call on Postexecute, cause we need no md5check
new MD5CheckerTask(MainActivity.this, null, filename, showDebugOutput).onPostExecute(true);
dialog.dismiss();
}
})
.setNegativeButton(R.string.no_md5_found_negative, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.show();
}
//If MD5 exists, apply the update normally
else
{
mDialog = ProgressDialog.show(
MainActivity.this,
res.getString(R.string.verify_and_apply_dialog_title),
res.getString(R.string.verify_and_apply_dialog_message),
true,
true,
new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface arg0)
{
if(md5CheckerTask != null)
md5CheckerTask.cancel(true);
}
}
);
md5CheckerTask = new MD5CheckerTask(MainActivity.this, mDialog, filename, showDebugOutput).execute(Update);
}
}
private final Spinner.OnItemSelectedListener mUpdateSpinnerChanged = new Spinner.OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
Button updateChangelogButton = (Button) findViewById(R.id.show_changelog_button);
String changelog = ((UpdateInfo) mUpdatesSpinner.getSelectedItem()).getDescription();
if (changelog == null || changelog == "")
{
updateChangelogButton.setVisibility(View.GONE);
}
else
{
updateChangelogButton.setVisibility(View.VISIBLE);
}
}
public void onNothingSelected(AdapterView<?> arg0)
{
}
};
private final Spinner.OnItemSelectedListener mThemeSpinnerChanged = new Spinner.OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
Button themeChangelogButton = (Button) findViewById(R.id.show_theme_changelog_button);
Button ScreenshotThemeButton = (Button) findViewById(R.id.theme_screenshots_button);
UpdateInfo item = (UpdateInfo) mThemesSpinner.getSelectedItem();
String changelog = item.getDescription();
List<URI> screenshots = item.screenshots;
int ScreenshotCount = item.screenshots.size();
if (changelog == null || changelog == "")
{
themeChangelogButton.setVisibility(View.GONE);
}
else
{
themeChangelogButton.setVisibility(View.VISIBLE);
}
if (screenshots == null || ScreenshotCount < 1)
{
ScreenshotThemeButton.setVisibility(View.GONE);
}
else
{
ScreenshotThemeButton.setVisibility(View.VISIBLE);
}
}
public void onNothingSelected(AdapterView<?> arg0)
{
}
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
prefs = new Preferences(this);
//Debug Output
showDebugOutput = prefs.displayDebugOutput();
res = getResources();
if (showDebugOutput) Log.d(TAG, "onCreate called");
//Sets the Title to Appname + Mod Version
setTitle(res.getString(R.string.app_name) + " " + res.getString(R.string.title_running) + " " + SysUtils.getModVersion());
setContentView(R.layout.main);
//Inflate the Screenshot View if enabled
if (Customization.Screenshotsupport)
{
((ViewStub) findViewById(R.id.main_stub_themes)).setVisibility(View.VISIBLE);
}
flipper = (ViewFlipper)findViewById(R.id.Flipper);
flipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));
flipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out));
btnAvailableUpdates = (Button)findViewById(R.id.button_available_updates);
btnExistingUpdates = (Button)findViewById(R.id.button_existing_updates);
btnAvailableThemes = (Button)findViewById(R.id.button_available_themes);
//Make the ScreenshotButton invisible
if (!Customization.Screenshotsupport)
{
btnAvailableThemes.setVisibility(View.GONE);
}
experimentalBuildsRomtv = (TextView) findViewById(R.id.experimental_rom_updates_textview);
showDowngradesRomtv = (TextView) findViewById(R.id.show_rom_downgrades_textview);
experimentalBuildsThemetv = (TextView) findViewById(R.id.experimental_theme_updates_textview);
lastRomUpdateChecktv = (TextView) findViewById(R.id.last_rom_update_check);
//Existing Updates Layout
mdownloadedUpdateText = (TextView) findViewById(R.id.downloaded_update_found);
mspFoundUpdates = mExistingUpdatesSpinner = (Spinner) findViewById(R.id.found_updates_list);
mdeleteOldUpdatesButton = (Button) findViewById(R.id.delete_updates_button);
mapplyUpdateButton = (Button) findViewById(R.id.apply_update_button);
mNoExistingUpdatesFound = (TextView) findViewById(R.id.no_existing_updates_found_textview);
//Rom Layout
selectUploadButton = (Button) findViewById(R.id.download_update_button);
mUpdatesSpinner = (Spinner) findViewById(R.id.available_updates_list);
DownloadText = (TextView) findViewById(R.id.available_updates_text);
stableExperimentalInfoUpdates = (LinearLayout) findViewById(R.id.stable_experimental_description_container_updates);
changelogButton = (Button) findViewById(R.id.show_changelog_button);
//Theme Layout
if (Customization.Screenshotsupport)
{
showDowngradesThemetv = (TextView) findViewById(R.id.show_theme_downgrades_textview);
lastThemeUpdateChecktv = (TextView) findViewById(R.id.last_theme_update_check);
btnDownloadTheme = (Button) findViewById(R.id.download_theme_button);
mThemesSpinner = (Spinner) findViewById(R.id.available_themes_list);
tvThemeDownloadText = (TextView) findViewById(R.id.available_themes_text);
stableExperimentalInfoThemes = (LinearLayout) findViewById(R.id.stable_experimental_description_container_themes);
btnThemechangelogButton = (Button) findViewById(R.id.show_theme_changelog_button);
btnThemeScreenshotButton = (Button) findViewById(R.id.theme_screenshots_button);
tvNoThemeUpdateServer = (TextView) findViewById(R.id.no_theme_update_server_configured);
}
//No ROM Updates Found Layout
CheckNowUpdateChooserUpdates = (Button) findViewById(R.id.check_now_button_update_chooser_updates);
CheckNowUpdateChooserTextUpdates = (TextView) findViewById(R.id.check_now_update_chooser_text_updates);
CheckNowUpdateChooserTextUpdates.setVisibility(View.GONE);
CheckNowUpdateChooserUpdates.setVisibility(View.GONE);
//No Theme Updates Found Layout
if (Customization.Screenshotsupport)
{
CheckNowUpdateChooserThemes = (Button) findViewById(R.id.check_now_button_update_chooser_themes);
CheckNowUpdateChooserTextThemes = (TextView) findViewById(R.id.check_now_update_chooser_text_themes);
CheckNowUpdateChooserTextThemes.setVisibility(View.GONE);
CheckNowUpdateChooserThemes.setVisibility(View.GONE);
}
//Flipper Buttons
btnAvailableUpdates.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
if(flipper.getDisplayedChild() != Constants.FLIPPER_AVAILABLE_UPDATES)
flipper.setDisplayedChild(Constants.FLIPPER_AVAILABLE_UPDATES);
}
});
btnExistingUpdates.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
if(flipper.getDisplayedChild() != Constants.FLIPPER_EXISTING_UPDATES)
flipper.setDisplayedChild(Constants.FLIPPER_EXISTING_UPDATES);
}
});
if (Customization.Screenshotsupport)
{
btnAvailableThemes.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
if(flipper.getDisplayedChild() != Constants.FLIPPER_AVAILABLE_THEMES)
flipper.setDisplayedChild(Constants.FLIPPER_AVAILABLE_THEMES);
}
});
}
}
@Override
protected void onStart()
{
if (showDebugOutput) Log.d(TAG, "onStart called");
super.onStart();
//Show a Dialog that the User runs an old rom.
String mod = SysUtils.getModVersion();
if (StringUtils.compareVersions(Customization.MIN_SUPPORTED_VERSION_STRING, mod))
{
runningOldVersion = true;
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.alert_old_version_title)
.setMessage(R.string.alert_old_version_summary)
.setPositiveButton(R.string.alert_old_version_ok, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.setNegativeButton(R.string.alert_old_version_browser, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
//Open the Browser for Instructions
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(Customization.UPDATE_INSTRUCTIONS_URL));
startActivity(i);
dialog.dismiss();
}
})
.show();
return;
}
}
@Override
protected void onResume()
{
if (showDebugOutput) Log.d(TAG, "onResume called");
super.onResume();
mfilenames = null;
mUpdateFolder = new File(Environment.getExternalStorageDirectory() + "/" + prefs.getUpdateFolder());
FilenameFilter f = new UpdateFilter(".zip");
File[] files = mUpdateFolder.listFiles(f);
//If Folder Exists and Updates are present(with md5files)
if(mUpdateFolder.exists() && mUpdateFolder.isDirectory() && files != null && files.length>0)
{
//To show only the Filename. Otherwise the whole Path with /sdcard/cm-updates will be shown
mfilenames = new ArrayList<String>();
for (int i=0;i<files.length;i++)
{
mfilenames.add(files[i].getName());
}
//For sorting the Filenames, have to find a way to do natural sorting
mfilenames = Collections.synchronizedList(mfilenames);
Collections.sort(mfilenames, Collections.reverseOrder());
}
files = null;
try
{
if(DownloadActivity.myService != null && DownloadActivity.myService.DownloadRunning())
{
UpdateInfo ui = DownloadActivity.myService.getCurrentUpdate();
Intent i = new Intent(MainActivity.this, DownloadActivity.class);
i.putExtra(Constants.KEY_UPDATE_INFO, (Serializable)ui);
startActivity(i);
}
else
{
switchToUpdateChooserLayout();
}
}
catch (RemoteException e)
{
Log.e(TAG, "Exception on calling DownloadService", e);
}
}
@Override
protected void onStop()
{
if (showDebugOutput) Log.d(TAG, "onStop called");
super.onStop();
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
menu.add(Menu.NONE, Constants.MENU_ID_UPDATE_NOW, Menu.NONE, R.string.menu_check_now)
.setIcon(R.drawable.check_now);
menu.add(Menu.NONE, Constants.MENU_ID_CONFIG, Menu.NONE, R.string.menu_config)
.setIcon(R.drawable.button_config);
menu.add(Menu.NONE, Constants.MENU_ID_ABOUT, Menu.NONE, R.string.menu_about)
.setIcon(R.drawable.button_about);
menu.add(Menu.NONE, Constants.MENU_ID_CHANGELOG, Menu.NONE, R.string.menu_changelog)
.setIcon(R.drawable.button_clog);
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu)
{
boolean superReturn = super.onPrepareOptionsMenu(menu);
try
{
if(DownloadActivity.myService != null && DownloadActivity.myService.DownloadRunning())
{
//Download in progress
menu.findItem(Constants.MENU_ID_UPDATE_NOW).setEnabled(false);
}
}
catch (RemoteException e)
{
Log.e(TAG, "Exception on calling DownloadService", e);
}
return superReturn;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item)
{
switch(item.getItemId())
{
case Constants.MENU_ID_UPDATE_NOW:
checkForUpdates();
return true;
case Constants.MENU_ID_CONFIG:
showConfigActivity();
return true;
case Constants.MENU_ID_ABOUT:
showAboutDialog();
return true;
case Constants.MENU_ID_CHANGELOG:
getChangelog(ChangelogType.APP);
return true;
default:
Log.e(TAG, "Unknown Menu ID:" + item.getItemId());
break;
}
return super.onMenuItemSelected(featureId, item);
}
private void switchToUpdateChooserLayout()
{
try
{
mAvailableUpdates = State.loadState(this, showDebugOutput);
}
catch (IOException e)
{
Log.e(TAG, "Unable to restore activity status", e);
}
//Reset all Visibilities
if (Customization.Screenshotsupport)
{
CheckNowUpdateChooserTextThemes.setVisibility(View.GONE);
CheckNowUpdateChooserThemes.setVisibility(View.GONE);
}
CheckNowUpdateChooserTextUpdates.setVisibility(View.GONE);
CheckNowUpdateChooserUpdates.setVisibility(View.GONE);
selectUploadButton.setVisibility(View.VISIBLE);
mUpdatesSpinner.setVisibility(View.VISIBLE);
DownloadText.setVisibility(View.VISIBLE);
stableExperimentalInfoUpdates.setVisibility(View.VISIBLE);
changelogButton.setVisibility(View.VISIBLE);
if (Customization.Screenshotsupport)
{
btnDownloadTheme.setVisibility(View.VISIBLE);
mThemesSpinner.setVisibility(View.VISIBLE);
tvThemeDownloadText.setVisibility(View.VISIBLE);
stableExperimentalInfoThemes.setVisibility(View.VISIBLE);
btnThemechangelogButton.setVisibility(View.VISIBLE);
btnThemeScreenshotButton.setVisibility(View.VISIBLE);
}
//Theme Update File URL Set?
boolean ThemeUpdateUrlSet = prefs.ThemeUpdateUrlSet();
((NotificationManager)getSystemService(NOTIFICATION_SERVICE)).cancel(R.string.not_new_updates_found_title);
//Experimental and All
String showExperimentalRomUpdates;
String showAllRomUpdates;
String showExperimentalThemeUpdates = "";
String showAllThemeUpdates = "";
String trueString = res.getString(R.string.true_string);
String falseString = res.getString(R.string.false_string);
if(prefs.showExperimentalRomUpdates())
showExperimentalRomUpdates = trueString;
else
showExperimentalRomUpdates = falseString;
if(prefs.showAllRomUpdates())
showAllRomUpdates = trueString;
else
showAllRomUpdates = falseString;
if (Customization.Screenshotsupport)
{
if(prefs.showExperimentalThemeUpdates())
showExperimentalThemeUpdates = trueString;
else
showExperimentalThemeUpdates = falseString;
if(prefs.showAllThemeUpdates())
showAllThemeUpdates = trueString;
else
showAllThemeUpdates = falseString;
}
experimentalBuildsRomtv.setText(MessageFormat.format(res.getString(R.string.p_allow_experimental_rom_versions_title)+": {0}", showExperimentalRomUpdates));
showDowngradesRomtv.setText(MessageFormat.format(res.getString(R.string.p_display_older_rom_versions_title)+": {0}", showAllRomUpdates));
if (Customization.Screenshotsupport)
{
experimentalBuildsThemetv.setText(MessageFormat.format(res.getString(R.string.p_allow_experimental_theme_versions_title)+": {0}", showExperimentalThemeUpdates));
showDowngradesThemetv.setText(MessageFormat.format(res.getString(R.string.p_display_older_theme_versions_title)+": {0}", showAllThemeUpdates));
lastThemeUpdateChecktv.setText(res.getString(R.string.last_update_check_text) + ": " + prefs.getLastUpdateCheckString());
}
lastRomUpdateChecktv.setText(res.getString(R.string.last_update_check_text) + ": " + prefs.getLastUpdateCheckString());
//Sets the Theme and Rom Variables
List<UpdateInfo> availableRoms = null;
List<UpdateInfo> availableThemes = null;
if (mAvailableUpdates != null)
{
if (mAvailableUpdates.roms != null)
availableRoms = mAvailableUpdates.roms;
if (Customization.Screenshotsupport && mAvailableUpdates.themes != null)
availableThemes = mAvailableUpdates.themes;
//Add the incrementalUpdates
if (mAvailableUpdates.incrementalRoms != null)
availableRoms.addAll(mAvailableUpdates.incrementalRoms);
}
//Rom Layout
if(availableRoms != null && availableRoms.size() > 0)
{
selectUploadButton.setOnClickListener(ButtonOnClickListener);
changelogButton.setOnClickListener(ButtonOnClickListener);
mUpdatesSpinner.setOnItemSelectedListener(mUpdateSpinnerChanged);
UpdateListAdapter<UpdateInfo> spAdapterRoms = new UpdateListAdapter<UpdateInfo>(
this,
android.R.layout.simple_spinner_item,
availableRoms);
spAdapterRoms.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mUpdatesSpinner.setAdapter(spAdapterRoms);
}
else
{
selectUploadButton.setVisibility(View.GONE);
mUpdatesSpinner.setVisibility(View.GONE);
DownloadText.setVisibility(View.GONE);
stableExperimentalInfoUpdates.setVisibility(View.GONE);
changelogButton.setVisibility(View.GONE);
CheckNowUpdateChooserTextUpdates.setVisibility(View.VISIBLE);
CheckNowUpdateChooserUpdates.setVisibility(View.VISIBLE);
CheckNowUpdateChooserUpdates.setOnClickListener(ButtonOnClickListener);
}
//Disable the download Button when running an old ROM
if (runningOldVersion)
selectUploadButton.setEnabled(false);
//Theme Layout
//Update URL Set?
if (Customization.Screenshotsupport)
{
if (!ThemeUpdateUrlSet)
{
tvNoThemeUpdateServer.setVisibility(View.VISIBLE);
btnDownloadTheme.setVisibility(View.GONE);
mThemesSpinner.setVisibility(View.GONE);
tvThemeDownloadText.setVisibility(View.GONE);
stableExperimentalInfoThemes.setVisibility(View.GONE);
btnThemechangelogButton.setVisibility(View.GONE);
btnThemeScreenshotButton.setVisibility(View.GONE);
CheckNowUpdateChooserTextThemes.setVisibility(View.GONE);
CheckNowUpdateChooserThemes.setVisibility(View.GONE);
}
//Themes
else if(availableThemes != null && availableThemes.size() > 0)
{
btnDownloadTheme.setOnClickListener(ButtonOnClickListener);
btnThemechangelogButton.setOnClickListener(ButtonOnClickListener);
btnThemeScreenshotButton.setOnClickListener(ButtonOnClickListener);
mThemesSpinner.setOnItemSelectedListener(mThemeSpinnerChanged);
UpdateListAdapter<UpdateInfo> spAdapterThemes = new UpdateListAdapter<UpdateInfo>(
this,
android.R.layout.simple_spinner_item,
availableThemes);
spAdapterThemes.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mThemesSpinner.setAdapter(spAdapterThemes);
}
//No Updates Found
else
{
btnDownloadTheme.setVisibility(View.GONE);
mThemesSpinner.setVisibility(View.GONE);
tvThemeDownloadText.setVisibility(View.GONE);
stableExperimentalInfoThemes.setVisibility(View.GONE);
btnThemechangelogButton.setVisibility(View.GONE);
btnThemeScreenshotButton.setVisibility(View.GONE);
CheckNowUpdateChooserTextThemes.setVisibility(View.VISIBLE);
CheckNowUpdateChooserThemes.setVisibility(View.VISIBLE);
CheckNowUpdateChooserThemes.setOnClickListener(ButtonOnClickListener);
}
}
//Existing Updates Layout
if (mfilenames != null && mfilenames.size() > 0)
{
ArrayAdapter<String> localUpdates = new ArrayAdapter<String>(
this,
android.R.layout.simple_spinner_item,
mfilenames);
localUpdates.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mspFoundUpdates.setAdapter(localUpdates);
mapplyUpdateButton.setOnClickListener(ButtonOnClickListener);
mdeleteOldUpdatesButton.setOnClickListener(ButtonOnClickListener);
}
else
{
mNoExistingUpdatesFound.setVisibility(View.VISIBLE);
mspFoundUpdates.setVisibility(View.GONE);
mapplyUpdateButton.setVisibility(View.GONE);
mdownloadedUpdateText.setVisibility(View.GONE);
mdeleteOldUpdatesButton.setVisibility(View.GONE);
}
}
private void getChangelog(ChangelogType changelogType)
{
//Handler for the ThreadClass, that downloads the AppChangelog
ChangelogProgressHandler = new Handler()
{
@SuppressWarnings("unchecked")
public void handleMessage(Message msg)
{
if (ChangelogProgressDialog != null)
ChangelogProgressDialog.dismiss();
if (msg.obj instanceof String)
{
Toast.makeText(MainActivity.this, (CharSequence) msg.obj, Toast.LENGTH_LONG).show();
ChangelogList = null;
MainActivity.this.ChangelogThread.interrupt();
ChangelogProgressDialog.dismiss();
displayChangelog(ChangelogType.APP);
}
else if (msg.obj instanceof List<?>)
{
ChangelogList = (List<Version>) msg.obj;
MainActivity.this.ChangelogThread.interrupt();
ChangelogProgressDialog.dismiss();
displayChangelog(ChangelogType.APP);
}
}
};
switch (changelogType)
{
case ROM:
//Get the ROM Changelog and Display the Changelog
ChangelogList = Changelog.getRomChangelog((UpdateInfo) mUpdatesSpinner.getSelectedItem());
displayChangelog(ChangelogType.ROM);
break;
case THEME:
//Get the THEME Changelog and Display the Changelog
ChangelogList = Changelog.getRomChangelog((UpdateInfo) mThemesSpinner.getSelectedItem());
displayChangelog(ChangelogType.THEME);
break;
case APP:
//Show a ProgressDialog and start the Thread. The Dialog is shown in the Handler Function
ChangelogProgressDialog = ProgressDialog.show(this, res.getString(R.string.changelog_progress_title), res.getString(R.string.changelog_progress_body), true);
ChangelogThread = new Thread(new Changelog(this));
ChangelogThread.start();
break;
default:
return;
}
}
private void displayChangelog(ChangelogType changelogtype)
{
if (ChangelogList == null)
return;
boolean ChangelogEmpty = true;
Dialog dialog = new Dialog(this);
String dialogTitle;
switch (changelogtype)
{
case ROM:
dialogTitle = res.getString(R.string.changelog_title_rom);
break;
case THEME:
dialogTitle = res.getString(R.string.changelog_title_theme);
break;
case APP:
dialogTitle = res.getString(R.string.changelog_title_app);
break;
default:
return;
}
dialog.setTitle(dialogTitle);
dialog.setContentView(R.layout.changelog);
LinearLayout main = (LinearLayout) dialog.findViewById(R.id.ChangelogLinearMain);
LayoutParams lp1 = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
LayoutParams lp2 = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
LayoutParams lp3 = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//Foreach Version
for (Version v:ChangelogList)
{
if (v.ChangeLogText.isEmpty())
{
continue;
}
ChangelogEmpty = false;
TextView versiontext = new TextView(this);
versiontext.setLayoutParams(lp1);
versiontext.setGravity(Gravity.CENTER);
versiontext.setTextColor(Color.RED);
versiontext.setText("Version " + v.Version);
versiontext.setTypeface(null, Typeface.BOLD);
versiontext.setTextSize((versiontext.getTextSize() * (float)1.5));
main.addView(versiontext);
//Foreach Changelogtext
for(String Change:v.ChangeLogText)
{
LinearLayout l = new LinearLayout(this);
l.setLayoutParams(lp2);
l.setGravity(Gravity.CENTER_VERTICAL);
ImageView i = new ImageView(this);
i.setLayoutParams(lp3);
i.setImageResource(R.drawable.icon);
l.addView(i);
TextView ChangeText = new TextView(this);
ChangeText.setLayoutParams(lp3);
ChangeText.setText(Change);
l.addView(ChangeText);
main.addView(l);
//Horizontal Line
View ruler = new View(this);
ruler.setBackgroundColor(Color.WHITE);
main.addView(ruler, new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, 1));
}
}
if(!ChangelogEmpty)
dialog.show();
else
Toast.makeText(this, res.getString(R.string.no_changelog_found), Toast.LENGTH_LONG).show();
System.gc();
}
private void showConfigActivity()
{
Intent i = new Intent(this, ConfigActivity.class);
startActivity(i);
}
private void checkForUpdates()
{
ProgressDialog pg = ProgressDialog.show(this, res.getString(R.string.checking_for_updates), res.getString(R.string.checking_for_updates), true, true);
//Refresh the Layout when UpdateCheck finished
pg.setOnDismissListener(new DialogInterface.OnDismissListener()
{
public void onDismiss (DialogInterface dialog)
{
switchToUpdateChooserLayout();
}
});
new UpdateCheckTask(this, pg, showDebugOutput).execute((Void) null);
}
private void showAboutDialog()
{
Dialog dialog = new Dialog(this);
dialog.setTitle(res.getString(R.string.about_dialog_title));
dialog.setContentView(R.layout.about);
TextView mVersionName = (TextView) dialog.findViewById(R.id.version_name_about_text_view);
try
{
PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0);
mVersionName.setText("v " + pi.versionName);
}
catch (NameNotFoundException e)
{
Log.e(TAG, "Can't find version name", e);
mVersionName.setText("v unknown");
}
dialog.show();
}
private void downloadRequestedUpdate(UpdateInfo ui)
{
Intent i = new Intent(MainActivity.this, DownloadActivity.class);
i.putExtra(Constants.KEY_UPDATE_INFO, (Serializable)ui);
startActivity(i);
Toast.makeText(this, R.string.downloading_update, Toast.LENGTH_LONG).show();
}
private boolean deleteOldUpdates()
{
boolean success = false;
//updateFolder: Foldername
//mUpdateFolder: Foldername with fullpath of SDCARD
String updateFolder = prefs.getUpdateFolder();
if (mUpdateFolder.exists() && mUpdateFolder.isDirectory() && updateFolder.trim() != "" && updateFolder.trim() != "/")
{
deleteDir(mUpdateFolder);
mUpdateFolder.mkdir();
if (showDebugOutput) Log.d(TAG, "Updates deleted and UpdateFolder created again");
success=true;
Toast.makeText(this, R.string.delete_updates_success_message, Toast.LENGTH_LONG).show();
}
else if (!mUpdateFolder.exists())
{
success = false;
Toast.makeText(this, R.string.delete_updates_noFolder_message, Toast.LENGTH_LONG).show();
}
else if(updateFolder.trim() == "" || updateFolder.trim() == "/")
{
success = false;
Toast.makeText(this, R.string.delete_updates_root_folder_message, Toast.LENGTH_LONG).show();
}
else
{
success = false;
Toast.makeText(this, R.string.delete_updates_failure_message, Toast.LENGTH_LONG).show();
}
return success;
}
private boolean deleteUpdate(String filename)
{
boolean success = false;
if (mUpdateFolder.exists() && mUpdateFolder.isDirectory())
{
File ZIPfiletodelete = new File(mUpdateFolder + "/" + filename);
File MD5filetodelete = new File(mUpdateFolder + "/" + filename + ".md5sum");
if (ZIPfiletodelete.exists())
{
ZIPfiletodelete.delete();
}
else
{
if (showDebugOutput) Log.d(TAG, "Update to delete not found");
if (showDebugOutput) Log.d(TAG, "Zip File: "+ZIPfiletodelete.getAbsolutePath());
return false;
}
if (MD5filetodelete.exists())
{
MD5filetodelete.delete();
}
else
{
if (showDebugOutput) Log.d(TAG, "MD5 to delete not found. No Problem here.");
if (showDebugOutput) Log.d(TAG, "MD5 File: "+MD5filetodelete.getAbsolutePath());
}
ZIPfiletodelete = null;
MD5filetodelete = null;
success=true;
Toast.makeText(this, MessageFormat.format(res.getString(R.string.delete_single_update_success_message), filename), Toast.LENGTH_LONG).show();
}
else if (!mUpdateFolder.exists())
{
Toast.makeText(this, R.string.delete_updates_noFolder_message, Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(this, R.string.delete_updates_failure_message, Toast.LENGTH_LONG).show();
}
return success;
}
private static boolean deleteDir(File dir)
{
if (dir.isDirectory())
{
String[] children = dir.list();
for (int i=0; i<children.length; i++)
{
boolean success = deleteDir(new File(dir, children[i]));
if (!success)
{
return false;
}
}
}
// The directory is now empty so delete it
return dir.delete();
}
}