// Copyright (C) 2012 LMIT Limited // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.lmit.jenkins.android.activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.preference.EditTextPreference; import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.PreferenceActivity; import android.text.Editable; import android.view.Menu; import android.view.MenuItem; import android.view.MenuItem.OnMenuItemClickListener; import android.view.View; import android.webkit.WebView; import android.widget.Button; import android.widget.EditText; import com.lmit.jenkins.android.addon.ImageCache; import com.lmit.jenkins.android.addon.LocalStorage; import com.lmit.jenkins.android.configuration.Configuration; import com.lmit.jenkins.android.logger.Logger; import com.lmit.jenkins.android.networking.TwoPhaseAuthenticationRequiredException; public class Configurator2Activity extends PreferenceActivity { private static final long SLEEP_BETWEEN_PROGRESS_MESSAGES = 500L; private class PreferenceChangeListener implements OnPreferenceChangeListener { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { if (!((EditTextPreference) preference).getText().equals(newValue)) { configurationChanged = true; } setPreferenceSummary(preference, newValue); return true; } } private boolean configurationChanged = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTitle(R.string.configurator_view_title); addPreferencesFromResource(R.layout.preferences_layout); loadFromConfiguration(); } private void loadFromConfiguration() { Configuration conf = Configuration.getInstance(); loadPreference(Configuration.KEY_JENKINS_URL, R.string.conf_entry_hostname_hint, conf.jenkinsUrl); loadPreference(Configuration.KEY_JENKINS_USERNAME, R.string.conf_entry_username_hint, conf.jenkinsUsername); loadPreference(Configuration.KEY_JENKINS_PASSWORD, R.string.conf_entry_password_hint, conf.jenkinsPassword); } private void loadPreference(String prefKey, int summaryStringKey, String value) { EditTextPreference editTextPref; editTextPref = (EditTextPreference) findPreference(prefKey); editTextPref.getEditText().setHint(summaryStringKey); setPreferenceSummary(editTextPref, value); editTextPref.setText(value); editTextPref.setOnPreferenceChangeListener(new PreferenceChangeListener()); } private void setPreferenceSummary(Preference preference, Object newValue) { if (preference.getTitle().toString().toLowerCase().indexOf("password") >= 0) { preference.setSummary("***********"); } else { preference.setSummary(newValue != null ? newValue.toString() : ""); } } private String getPreference(String prefKey) { return ((EditTextPreference) findPreference(prefKey)).getText(); } private void doSave(final String otp) { final ProgressDialog saveProgress = new ProgressDialog(Configurator2Activity.this); AsyncTask<Void, String, Boolean> saveTask = new AsyncTask<Void, String, Boolean>() { String validationResult = ""; TwoPhaseAuthenticationRequiredException otpRequest; @Override protected void onPreExecute() { super.onPreExecute(); saveProgress.setMessage(getString(R.string.conf_save_progress)); saveProgress.setProgressStyle(ProgressDialog.STYLE_SPINNER); saveProgress.show(); } @Override protected Boolean doInBackground(Void... params) { Configuration conf = Configuration.getInstance(); conf.jenkinsUrl = getPreference(Configuration.KEY_JENKINS_URL); conf.jenkinsUsername = getPreference(Configuration.KEY_JENKINS_USERNAME); conf.jenkinsPassword = getPreference(Configuration.KEY_JENKINS_PASSWORD); sleep(); publishProgress(getString(R.string.conf_save_validation)); try { validationResult = conf.validate(otp); } catch (TwoPhaseAuthenticationRequiredException e) { otpRequest = e; return false; } sleep(); if (validationResult != null && validationResult.equals(conf.VALIDATION_SUCCEDED)) { publishProgress(getString(R.string.conf_save_to_profile)); conf.save(); LocalStorage.getInstance().cleanAll(); ImageCache.clean(); sleep(); return true; } else { return false; } } private void sleep() { try { Thread.sleep(SLEEP_BETWEEN_PROGRESS_MESSAGES); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override protected void onProgressUpdate(String... progressMessage) { super.onProgressUpdate(progressMessage); saveProgress.setMessage(progressMessage[0]); } @Override protected void onPostExecute(Boolean validationSucceded) { saveProgress.dismiss(); if (validationSucceded) { restartHomeActivity(); } else { if (otpRequest != null) { final EditText input = new EditText(Configurator2Activity.this); Builder otpAlert = new AlertDialog.Builder(Configurator2Activity.this) .setMessage(otpRequest.getLocalizedMessage()).setView( input); final String appId = otpRequest.getAuthAppId(); if (appId == null) { otpAlert.setNeutralButton("Verify", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int whichButton) { Editable value = input.getText(); doSave(value.toString()); } }); } else { otpAlert.setPositiveButton("Verify", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int whichButton) { Editable value = input.getText(); doSave(value.toString()); } }).setNegativeButton("Auth App", null); AlertDialog dialog = otpAlert.show(); Button theButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE); theButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent i = new Intent(); PackageManager manager = getPackageManager(); i = manager.getLaunchIntentForPackage(appId); i.addCategory(Intent.CATEGORY_LAUNCHER); startActivity(i); } }); } } else { AlertDialog.Builder alertbox = new AlertDialog.Builder(Configurator2Activity.this) .setMessage(getString(R.string.conf_save_validation_failed, validationResult)) .setNeutralButton("OK", null); alertbox.show(); } } } }; saveTask.execute(null); } private void restartHomeActivity() { finish(); Configuration.getInstance().setConnected(true, true); Intent intent = new Intent(this, HudsonDroidHomeActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuItem menuItem; menuItem = menu.add("Send feedback"); menuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem paramMenuItem) { showMailerToSendCrashReport(); return true; } }); return super.onCreateOptionsMenu(menu); } private void showMailerToSendCrashReport() { /* Create the Intent */ final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); /* Fill it with Data */ emailIntent.setType("plain/text"); emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] {Configuration.SUPPORT_MAIL_ADDRESS}); emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "JenkinsMobi log"); emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "JenkinsMobi log attached to this message"); emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, Uri.fromFile(Logger.getInstance().getLogFile())); /* Send it off to the Activity-Chooser */ startActivity(Intent.createChooser(emailIntent, getText(R.string.crash_email_subject).toString())); } @Override public void onBackPressed() { if (configurationChanged) { askConfirmationAndSaveChanges(); } else { super.onBackPressed(); } } public void askConfirmationAndSaveChanges() { AlertDialog alert = new AlertDialog.Builder(this).create(); alert.setTitle(R.string.conf_save_question); alert.setButton(Dialog.BUTTON_POSITIVE, getText(R.string.yes).toString(), new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { doSave(null); } }); alert.setButton(Dialog.BUTTON_NEGATIVE, getText(R.string.no).toString(), new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }); alert.setCanceledOnTouchOutside(false); alert.show(); } protected void resetLocalStorage() { LocalStorage.getInstance().cleanAll(); ImageCache.clean(); } private void createAccountWebView() { Dialog dialog = new Dialog(this); dialog.setContentView(R.layout.create_account); WebView wb = (WebView) dialog.findViewById(R.id.webview); wb.getSettings().setJavaScriptEnabled(true); wb.setWebViewClient(new CreateAccountWebViewClient(dialog, this)); wb.loadUrl(getCreateServiceAccountURL()); dialog.setCancelable(true); dialog.setTitle("Create Account"); dialog.show(); } private String getCreateServiceAccountURL() { String baseUrl = ((EditTextPreference) findPreference(Configuration.KEY_SERVICE_HOSTNAME)) .getText(); if (!baseUrl.endsWith("/")) { baseUrl += "/"; } return baseUrl + "signup.jsp"; } }