/* * Copyright (c) 2010-2016, openHAB.org and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.habdroid.ui; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.PreferenceActivity; import android.security.KeyChain; import android.security.KeyChainAliasCallback; import android.security.KeyChainException; import android.util.Log; import com.google.android.gms.analytics.GoogleAnalytics; import org.openhab.habdroid.R; import org.openhab.habdroid.util.Constants; import org.openhab.habdroid.util.Util; import java.net.MalformedURLException; import java.net.URL; import java.security.cert.X509Certificate; /** * This is a class to provide preferences activity for application. */ public class OpenHABPreferencesActivity extends PreferenceActivity { @SuppressWarnings("deprecation") @Override public void onStart() { super.onStart(); GoogleAnalytics.getInstance(this).reportActivityStart(this); } @Override public void onStop() { super.onStop(); GoogleAnalytics.getInstance(this).reportActivityStop(this); } @Override public void onCreate(Bundle savedInstanceState) { Util.setActivityTheme(this); super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); Preference urlPreference = getPreferenceScreen().findPreference(Constants.PREFERENCE_URL); final Preference altUrlPreference = getPreferenceScreen().findPreference(Constants.PREFERENCE_ALTURL); Preference usernamePreference = getPreferenceScreen().findPreference(Constants.PREFERENCE_USERNAME); Preference passwordPreference = getPreferenceScreen().findPreference(Constants.PREFERENCE_PASSWORD); Preference versionPreference = getPreferenceScreen().findPreference(Constants.PREFERENCE_APPVERSION); final Preference sslClientCert = getPreferenceScreen().findPreference(Constants.PREFERENCE_SSLCLIENTCERT); final Preference sslClientCertHowTo = getPreferenceScreen().findPreference(Constants.PREFERENCE_SSLCLIENTCERT_HOWTO); urlPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { Log.d("PreferencesActivity", "Validating new url = " + (String) newValue); String newUrl = (String) newValue; if (newUrl.length() == 0 || urlIsValid(newUrl)) { updateTextPreferenceSummary(preference, (String) newValue); return true; } showAlertDialog(getString(R.string.erorr_invalid_url)); return false; } }); updateTextPreferenceSummary(urlPreference, null); altUrlPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { String newUrl = (String) newValue; if (newUrl.length() == 0 || urlIsValid(newUrl)) { updateTextPreferenceSummary(preference, (String) newValue); return true; } showAlertDialog(getString(R.string.erorr_invalid_url)); return false; } }); updateTextPreferenceSummary(altUrlPreference, null); usernamePreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { updateTextPreferenceSummary(preference, (String) newValue); return true; } }); updateTextPreferenceSummary(usernamePreference, null); passwordPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { updatePasswordPreferenceSummary(preference, (String) newValue); return true; } }); updatePasswordPreferenceSummary(passwordPreference, null); updateTextPreferenceSummary(versionPreference, null); updateSslCleintCertSumary(sslClientCert); final KeyChainAliasCallback keyChainAliasCallback = new KeyChainAliasCallback() { @Override public void alias(String alias) { sslClientCert.getSharedPreferences().edit().putString(sslClientCert.getKey(), alias).apply(); updateSslCleintCertSumary(sslClientCert); } }; sslClientCert.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { sslClientCert.getSharedPreferences().edit().putString(sslClientCert.getKey(), null).apply(); KeyChain.choosePrivateKeyAlias(OpenHABPreferencesActivity.this, keyChainAliasCallback, new String[]{"RSA", "DSA"}, null, getPreferenceString(altUrlPreference, null), -1, null); return true; } }); sslClientCertHowTo.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { Uri hotToUri = Uri.parse(getString(R.string.settings_openhab_sslclientcert_howto_url)); Intent intent = new Intent(Intent.ACTION_VIEW, hotToUri); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } return true; } }); //fullscreen is not supoorted in builds < 4.4 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { getPreferenceScreen().removePreference(getPreferenceScreen().findPreference(Constants.PREFERENCE_FULLSCREEN)); } setResult(RESULT_OK); } private String getPreferenceString(Preference preference, String defValue) { return preference.getSharedPreferences().getString(preference.getKey(), defValue); } private void updateTextPreferenceSummary(Preference textPreference, String newValue) { if (newValue == null) { if (textPreference.getSharedPreferences().getString(textPreference.getKey(), "").length() > 0) textPreference.setSummary(textPreference.getSharedPreferences().getString(textPreference.getKey(), "")); else textPreference.setSummary(this.getResources().getString(R.string.info_not_set)); } else { if (newValue.length() > 0) textPreference.setSummary(newValue); else textPreference.setSummary(this.getResources().getString(R.string.info_not_set)); } } private void updatePasswordPreferenceSummary(Preference passwordPreference, String newValue) { if (newValue == null) { if (passwordPreference.getSharedPreferences().getString(passwordPreference.getKey(), "").length() > 0) passwordPreference.setSummary("******"); else passwordPreference.setSummary(this.getResources().getString(R.string.info_not_set)); } else { if (newValue.length() > 0) passwordPreference.setSummary("******"); else passwordPreference.setSummary(this.getResources().getString(R.string.info_not_set)); } } private void updateSslCleintCertSumary(final Preference sslClientCert) { final String certAlias = getPreferenceString(sslClientCert, null); new AsyncTask<Preference, Void, X509Certificate>() { @Override protected X509Certificate doInBackground(Preference... preferences) { try { if (certAlias != null) { X509Certificate[] certificates = KeyChain.getCertificateChain( OpenHABPreferencesActivity.this, certAlias); if (certificates != null && certificates.length > 0) { return certificates[0]; } } return null; } catch (KeyChainException | InterruptedException e) { e.printStackTrace(); return null; } } @Override protected void onPostExecute(X509Certificate x509Certificate) { if (x509Certificate != null) { sslClientCert.setSummary(x509Certificate.getSubjectDN().toString()); } else { sslClientCert.setSummary(getString(R.string.settings_openhab_none)); } } }.execute(sslClientCert); } private boolean urlIsValid(String url) { // As we accept an empty URL, which means it is not configured, length==0 is ok if (url.length() == 0) return true; if (url.contains("\n") || url.contains(" ")) return false; try { URL testURL = new URL(url); } catch (MalformedURLException e) { return false; } return true; } private void showAlertDialog(String alertMessage) { AlertDialog.Builder builder = new AlertDialog.Builder(OpenHABPreferencesActivity.this); builder.setMessage(alertMessage) .setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { } }); AlertDialog alert = builder.create(); alert.show(); } @Override public void finish() { super.finish(); Util.overridePendingTransition(this, true); } }