From 47e3bd6d6556fde0ba2683d5e2e079eb992d6c7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 18 Jan 2014 18:44:34 +0100 Subject: [PATCH] Externalize secret key selection into fragment for reuse in different activities --- .../res/layout/api_app_settings_fragment.xml | 46 +----- .../res/layout/key_server_export.xml | 2 +- .../res/layout/key_server_query.xml | 2 +- .../select_secret_key_layout_fragment.xml | 46 ++++++ .../res/layout/sign_key_activity.xml | 37 +++-- .../service/remote/AppSettingsActivity.java | 8 +- .../service/remote/AppSettingsFragment.java | 101 +++----------- .../keychain/ui/KeyServerQueryActivity.java | 2 +- .../keychain/ui/KeyServerUploadActivity.java | 2 +- .../ui/SelectSecretKeyLayoutFragment.java | 131 ++++++++++++++++++ .../keychain/ui/SignKeyActivity.java | 37 ++--- 11 files changed, 244 insertions(+), 170 deletions(-) create mode 100644 OpenPGP-Keychain/res/layout/select_secret_key_layout_fragment.xml create mode 100644 OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java diff --git a/OpenPGP-Keychain/res/layout/api_app_settings_fragment.xml b/OpenPGP-Keychain/res/layout/api_app_settings_fragment.xml index a88d7afd2..cecb2f93d 100644 --- a/OpenPGP-Keychain/res/layout/api_app_settings_fragment.xml +++ b/OpenPGP-Keychain/res/layout/api_app_settings_fragment.xml @@ -1,6 +1,7 @@ @@ -37,49 +38,12 @@ android:textAppearance="?android:attr/textAppearanceMedium" /> - - - - - - - - - - - + tools:layout="@layout/select_secret_key_layout_fragment" /> diff --git a/OpenPGP-Keychain/res/layout/key_server_query.xml b/OpenPGP-Keychain/res/layout/key_server_query.xml index 20f260a95..ab76d3aed 100644 --- a/OpenPGP-Keychain/res/layout/key_server_query.xml +++ b/OpenPGP-Keychain/res/layout/key_server_query.xml @@ -5,7 +5,7 @@ android:orientation="vertical" > diff --git a/OpenPGP-Keychain/res/layout/select_secret_key_layout_fragment.xml b/OpenPGP-Keychain/res/layout/select_secret_key_layout_fragment.xml new file mode 100644 index 000000000..7557a2830 --- /dev/null +++ b/OpenPGP-Keychain/res/layout/select_secret_key_layout_fragment.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenPGP-Keychain/res/layout/sign_key_activity.xml b/OpenPGP-Keychain/res/layout/sign_key_activity.xml index b9f66db7f..ada4572ca 100644 --- a/OpenPGP-Keychain/res/layout/sign_key_activity.xml +++ b/OpenPGP-Keychain/res/layout/sign_key_activity.xml @@ -1,14 +1,12 @@ + android:orientation="vertical" + android:padding="10dp" > - - + - + android:textAppearance="?android:attr/textAppearanceMedium" /> - + android:text="" /> - + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java index 4f1bedb6f..8d56fc593 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java @@ -35,7 +35,7 @@ import com.actionbarsherlock.view.MenuItem; public class AppSettingsActivity extends SherlockFragmentActivity { private Uri mAppUri; - private AppSettingsFragment settingsFragment; + private AppSettingsFragment mSettingsFragment; @Override protected void onCreate(Bundle savedInstanceState) { @@ -53,7 +53,7 @@ public class AppSettingsActivity extends SherlockFragmentActivity { setContentView(R.layout.api_app_settings_activity); - settingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( + mSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( R.id.api_app_settings_fragment); Intent intent = getIntent(); @@ -90,7 +90,7 @@ public class AppSettingsActivity extends SherlockFragmentActivity { private void loadData(Uri appUri) { AppSettings settings = ProviderHelper.getApiAppSettings(this, appUri); - settingsFragment.setAppSettings(settings); + mSettingsFragment.setAppSettings(settings); } private void revokeAccess() { @@ -101,7 +101,7 @@ public class AppSettingsActivity extends SherlockFragmentActivity { } private void save() { - ProviderHelper.updateApiApp(this, settingsFragment.getAppSettings(), mAppUri); + ProviderHelper.updateApiApp(this, mSettingsFragment.getAppSettings(), mAppUri); finish(); } diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java index bb6e427a4..025929cfa 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Dominik Schürmann + * Copyright (C) 2013-2014 Dominik Schürmann * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,21 +20,14 @@ package org.sufficientlysecure.keychain.service.remote; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.ui.SelectSecretKeyActivity; +import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter; import org.sufficientlysecure.keychain.util.AlgorithmNames; import org.sufficientlysecure.keychain.util.Log; -import android.app.Activity; -import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -56,7 +49,8 @@ import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; -public class AppSettingsFragment extends Fragment { +public class AppSettingsFragment extends Fragment implements + SelectSecretKeyLayoutFragment.SelectSecretKeyCallback { // model private AppSettings appSettings; @@ -66,15 +60,14 @@ public class AppSettingsFragment extends Fragment { private BootstrapButton mAdvancedSettingsButton; private TextView mAppNameView; private ImageView mAppIconView; - private TextView mKeyUserId; - private TextView mKeyUserIdRest; - private BootstrapButton mSelectKeyButton; private Spinner mEncryptionAlgorithm; private Spinner mHashAlgorithm; private Spinner mCompression; private TextView mPackageName; private TextView mPackageSignature; + private SelectSecretKeyLayoutFragment mSelectKeyFragment; + KeyValueSpinnerAdapter encryptionAdapter; KeyValueSpinnerAdapter hashAdapter; KeyValueSpinnerAdapter compressionAdapter; @@ -99,7 +92,7 @@ public class AppSettingsFragment extends Fragment { Log.e(Constants.TAG, "Should not happen!", e); } - updateSelectedKeyView(appSettings.getKeyId()); + mSelectKeyFragment.selectKey(appSettings.getKeyId()); mEncryptionAlgorithm.setSelection(encryptionAdapter.getPosition(appSettings .getEncryptionAlgorithm())); mHashAlgorithm.setSelection(hashAdapter.getPosition(appSettings.getHashAlgorithm())); @@ -117,6 +110,10 @@ public class AppSettingsFragment extends Fragment { } private void initView(View view) { + mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getFragmentManager().findFragmentById( + R.id.api_app_settings_select_key_fragment); + mSelectKeyFragment.setCallback(this); + mAdvancedSettingsButton = (BootstrapButton) view .findViewById(R.id.api_app_settings_advanced_button); mAdvancedSettingsContainer = (LinearLayout) view @@ -124,10 +121,6 @@ public class AppSettingsFragment extends Fragment { mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name); mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon); - mKeyUserId = (TextView) view.findViewById(R.id.api_app_settings_user_id); - mKeyUserIdRest = (TextView) view.findViewById(R.id.api_app_settings_user_id_rest); - mSelectKeyButton = (BootstrapButton) view - .findViewById(R.id.api_app_settings_select_key_button); mEncryptionAlgorithm = (Spinner) view .findViewById(R.id.api_app_settings_encryption_algorithm); mHashAlgorithm = (Spinner) view.findViewById(R.id.api_app_settings_hash_algorithm); @@ -181,14 +174,6 @@ public class AppSettingsFragment extends Fragment { } }); - mSelectKeyButton.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - selectSecretKey(); - } - }); - final Animation visibleAnimation = new AlphaAnimation(0.0f, 1.0f); visibleAnimation.setDuration(250); final Animation invisibleAnimation = new AlphaAnimation(1.0f, 0.0f); @@ -219,16 +204,6 @@ public class AppSettingsFragment extends Fragment { }); } - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - } - - private void selectSecretKey() { - Intent intent = new Intent(getActivity(), SelectSecretKeyActivity.class); - startActivityForResult(intent, Id.request.secret_keys); - } - private void setPackage(String packageName) { PackageManager pm = getActivity().getApplicationContext().getPackageManager(); @@ -248,56 +223,12 @@ public class AppSettingsFragment extends Fragment { mAppIconView.setImageDrawable(appIcon); } - private void updateSelectedKeyView(long secretKeyId) { - if (secretKeyId == Id.key.none) { - mKeyUserId.setText(R.string.api_settings_no_key); - mKeyUserIdRest.setText(""); - } else { - String uid = getResources().getString(R.string.unknown_user_id); - String uidExtra = ""; - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId( - getActivity(), secretKeyId); - if (keyRing != null) { - PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing); - if (key != null) { - String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key); - String chunks[] = userId.split(" <", 2); - uid = chunks[0]; - if (chunks.length > 1) { - uidExtra = "<" + chunks[1]; - } - } - } - mKeyUserId.setText(uid); - mKeyUserIdRest.setText(uidExtra); - } - } - + /** + * callback from select secret key fragment + */ @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - Log.d(Constants.TAG, "onactivityresult " + requestCode + " " + resultCode); - switch (requestCode) { - - case Id.request.secret_keys: { - long secretKeyId; - if (resultCode == Activity.RESULT_OK) { - Bundle bundle = data.getExtras(); - secretKeyId = bundle.getLong(SelectSecretKeyActivity.RESULT_EXTRA_MASTER_KEY_ID); - - } else { - secretKeyId = Id.key.none; - } - appSettings.setKeyId(secretKeyId); - updateSelectedKeyView(secretKeyId); - break; - } - - default: { - break; - } - } - - super.onActivityResult(requestCode, resultCode, data); + public void onKeySelected(long secretKeyId) { + appSettings.setKeyId(secretKeyId); } } diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerQueryActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerQueryActivity.java index 6073e6b80..c3ec7b9c3 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerQueryActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerQueryActivity.java @@ -119,7 +119,7 @@ public class KeyServerQueryActivity extends SherlockFragmentActivity { mAdapter = new KeyInfoListAdapter(this); mList.setAdapter(mAdapter); - mKeyServer = (Spinner)findViewById(R.id.keyServer); + mKeyServer = (Spinner)findViewById(R.id.sign_key_keyserver); ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, Preferences.getPreferences(this) .getKeyServers()); diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerUploadActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerUploadActivity.java index 8a32ea513..2bf19ab92 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerUploadActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerUploadActivity.java @@ -79,7 +79,7 @@ public class KeyServerUploadActivity extends SherlockFragmentActivity { setContentView(R.layout.key_server_export); export = (Button) findViewById(R.id.btn_export_to_server); - keyServer = (Spinner) findViewById(R.id.keyServer); + keyServer = (Spinner) findViewById(R.id.sign_key_keyserver); ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, Preferences.getPreferences(this) diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java new file mode 100644 index 000000000..996071a31 --- /dev/null +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.ui; + +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.sufficientlysecure.keychain.Id; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.provider.ProviderHelper; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.beardedhen.androidbootstrap.BootstrapButton; + +public class SelectSecretKeyLayoutFragment extends Fragment { + + private TextView mKeyUserId; + private TextView mKeyUserIdRest; + private BootstrapButton mSelectKeyButton; + + private SelectSecretKeyCallback mCallback; + + private static final int REQUEST_CODE_SELECT_KEY = 8882; + + public interface SelectSecretKeyCallback { + void onKeySelected(long secretKeyId); + } + + public void setCallback(SelectSecretKeyCallback callback) { + mCallback = callback; + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.select_secret_key_layout_fragment, container, false); + + mKeyUserId = (TextView) view.findViewById(R.id.select_secret_key_user_id); + mKeyUserIdRest = (TextView) view.findViewById(R.id.select_secret_key_user_id_rest); + mSelectKeyButton = (BootstrapButton) view + .findViewById(R.id.select_secret_key_select_key_button); + mSelectKeyButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + selectSecretKey(); + } + }); + + return view; + } + + private void selectSecretKey() { + Intent intent = new Intent(getActivity(), SelectSecretKeyActivity.class); + startActivityForResult(intent, REQUEST_CODE_SELECT_KEY); + } + + public void selectKey(long secretKeyId) { + if (secretKeyId == Id.key.none) { + mKeyUserId.setText(R.string.api_settings_no_key); + mKeyUserIdRest.setText(""); + } else { + String uid = getResources().getString(R.string.unknown_user_id); + String uidExtra = ""; + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId( + getActivity(), secretKeyId); + if (keyRing != null) { + PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing); + if (key != null) { + String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key); + String chunks[] = userId.split(" <", 2); + uid = chunks[0]; + if (chunks.length > 1) { + uidExtra = "<" + chunks[1]; + } + } + } + mKeyUserId.setText(uid); + mKeyUserIdRest.setText(uidExtra); + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode & 0xFFFF) { + case REQUEST_CODE_SELECT_KEY: { + long secretKeyId; + if (resultCode == Activity.RESULT_OK) { + Bundle bundle = data.getExtras(); + secretKeyId = bundle.getLong(SelectSecretKeyActivity.RESULT_EXTRA_MASTER_KEY_ID); + + selectKey(secretKeyId); + + // give value back to callback + mCallback.onKeySelected(secretKeyId); + } + break; + } + + default: + super.onActivityResult(requestCode, resultCode, data); + + break; + } + } +} diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SignKeyActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SignKeyActivity.java index 6abdddee6..a6390f9c9 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SignKeyActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SignKeyActivity.java @@ -50,6 +50,7 @@ import android.widget.Toast; import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.SherlockFragmentActivity; +import com.beardedhen.androidbootstrap.BootstrapButton; /** * gpg --sign-key @@ -63,11 +64,15 @@ public class SignKeyActivity extends SherlockFragmentActivity { private long mPubKeyId = 0; private long mMasterKeyId = 0; + private BootstrapButton mSignButton; + private CheckBox mUploadKeyCheckbox; + private Spinner mSelectKeyserverSpinner; + private BootstrapButton mSelectKeyButton; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // check we havent already signed it setContentView(R.layout.sign_key_activity); final ActionBar actionBar = getSupportActionBar(); @@ -75,35 +80,35 @@ public class SignKeyActivity extends SherlockFragmentActivity { actionBar.setDisplayHomeAsUpEnabled(false); actionBar.setHomeButtonEnabled(false); - final Spinner keyServer = (Spinner) findViewById(R.id.keyServer); + mSelectKeyserverSpinner = (Spinner) findViewById(R.id.sign_key_keyserver); ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, Preferences.getPreferences(this) .getKeyServers()); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - keyServer.setAdapter(adapter); + mSelectKeyserverSpinner.setAdapter(adapter); - final CheckBox sendKey = (CheckBox) findViewById(R.id.sendKey); - if (!sendKey.isChecked()) { - keyServer.setEnabled(false); + mUploadKeyCheckbox = (CheckBox) findViewById(R.id.sign_key_upload_checkbox); + if (!mUploadKeyCheckbox.isChecked()) { + mSelectKeyserverSpinner.setEnabled(false); } else { - keyServer.setEnabled(true); + mSelectKeyserverSpinner.setEnabled(true); } - sendKey.setOnCheckedChangeListener(new OnCheckedChangeListener() { + mUploadKeyCheckbox.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (!isChecked) { - keyServer.setEnabled(false); + mSelectKeyserverSpinner.setEnabled(false); } else { - keyServer.setEnabled(true); + mSelectKeyserverSpinner.setEnabled(true); } } }); - Button sign = (Button) findViewById(R.id.sign); - sign.setEnabled(false); // disabled until the user selects a key to sign with - sign.setOnClickListener(new OnClickListener() { + mSignButton = (BootstrapButton) findViewById(R.id.sign_key_sign_button); + mSignButton.setEnabled(false); // disabled until the user selects a key to sign with + mSignButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -221,7 +226,7 @@ public class SignKeyActivity extends SherlockFragmentActivity { Toast.LENGTH_SHORT).show(); // check if we need to send the key to the server or not - CheckBox sendKey = (CheckBox) findViewById(R.id.sendKey); + CheckBox sendKey = (CheckBox) findViewById(R.id.sign_key_upload_checkbox); if (sendKey.isChecked()) { /* * upload the newly signed key to the key server @@ -256,7 +261,7 @@ public class SignKeyActivity extends SherlockFragmentActivity { data.putLong(KeychainIntentService.UPLOAD_KEY_KEYRING_ROW_ID, mPubKeyId); - Spinner keyServer = (Spinner) findViewById(R.id.keyServer); + Spinner keyServer = (Spinner) findViewById(R.id.sign_key_keyserver); String server = (String) keyServer.getSelectedItem(); data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, server); @@ -299,7 +304,7 @@ public class SignKeyActivity extends SherlockFragmentActivity { mMasterKeyId = bundle.getLong(SelectSecretKeyActivity.RESULT_EXTRA_MASTER_KEY_ID); // re-enable the sign button so the user can initiate the sign process - Button sign = (Button) findViewById(R.id.sign); + Button sign = (Button) findViewById(R.id.sign_key_sign_button); sign.setEnabled(true); }