aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src
diff options
context:
space:
mode:
Diffstat (limited to 'OpenPGP-Keychain/src')
-rw-r--r--OpenPGP-Keychain/src/main/AndroidManifest.xml8
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java8
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java77
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java109
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java39
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java45
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java144
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java99
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettings.java)31
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java54
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java)54
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java)74
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java)2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java)152
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java176
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java)35
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java119
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListActivity.java)4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListFragment.java)85
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java)87
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java92
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsAdapter.java75
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java14
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java17
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java37
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java55
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java22
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java164
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java21
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java55
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java114
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java34
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java200
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java203
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java131
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java4
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/api_account_create_activity.xml21
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/api_account_settings_fragment.xml115
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml16
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml68
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/api_apps_list_content.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml116
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/encrypt_content_adv_settings.xml63
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/foldable_linearlayout.xml41
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/import_keys_list_entry.xml30
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/key_list_fragment.xml5
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/view_key_delete_fragment.xml38
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml10
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml30
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_about.html48
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_changelog.html108
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_nfc_beam.html12
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_start.html19
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-cs-rCZ/nfc_beam_share.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-de/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html12
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-de/help_start.html6
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-el/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-el/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-es/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-es/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-fr/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-fr/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-ja/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-ja/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-pl/help_about.html48
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-pl/help_changelog.html108
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-pl/help_nfc_beam.html12
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-pl/help_start.html19
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-pl/nfc_beam_share.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-ru/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-ru/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-tr/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-tr/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-uk/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-uk/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_about.html48
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_changelog.html108
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_nfc_beam.html12
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_start.html19
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-zh-rTW/nfc_beam_share.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-zh/help_about.html17
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-zh/help_nfc_beam.html10
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-zh/help_start.html12
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-zh/nfc_beam_share.html8
-rw-r--r--OpenPGP-Keychain/src/main/res/raw/help_about.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw/help_start.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/values-cs-rCZ/strings.xml27
-rw-r--r--OpenPGP-Keychain/src/main/res/values-de/strings.xml107
-rw-r--r--OpenPGP-Keychain/src/main/res/values-el/strings.xml1
-rw-r--r--OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml1
-rw-r--r--OpenPGP-Keychain/src/main/res/values-es/strings.xml46
-rw-r--r--OpenPGP-Keychain/src/main/res/values-fa-rIR/strings.xml1
-rw-r--r--OpenPGP-Keychain/src/main/res/values-fr/strings.xml35
-rw-r--r--OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml35
-rw-r--r--OpenPGP-Keychain/src/main/res/values-ja/strings.xml35
-rw-r--r--OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/values-pl/strings.xml450
-rw-r--r--OpenPGP-Keychain/src/main/res/values-pt-rBR/strings.xml1
-rw-r--r--OpenPGP-Keychain/src/main/res/values-ru/strings.xml26
-rw-r--r--OpenPGP-Keychain/src/main/res/values-sl-rSI/strings.xml1
-rw-r--r--OpenPGP-Keychain/src/main/res/values-tr/strings.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/values-uk/strings.xml37
-rw-r--r--OpenPGP-Keychain/src/main/res/values-zh-rTW/strings.xml27
-rw-r--r--OpenPGP-Keychain/src/main/res/values-zh/strings.xml4
-rw-r--r--OpenPGP-Keychain/src/main/res/values/attr.xml11
-rw-r--r--OpenPGP-Keychain/src/main/res/values/strings.xml9
129 files changed, 3679 insertions, 1258 deletions
diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml
index b1fbcf555..3ab39280e 100644
--- a/OpenPGP-Keychain/src/main/AndroidManifest.xml
+++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml
@@ -384,24 +384,24 @@
<!-- Internal classes of the remote APIs (not exported) -->
<activity
- android:name="org.sufficientlysecure.keychain.service.remote.RemoteServiceActivity"
+ android:name="org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity"
android:exported="false"
android:label="@string/app_name" />
<!--android:launchMode="singleTop"-->
<!--android:process=":remote_api"-->
<activity
- android:name="org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity"
+ android:name=".remote.ui.AppsListActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:exported="false"
android:label="@string/title_api_registered_apps" />
<activity
- android:name="org.sufficientlysecure.keychain.service.remote.AppSettingsActivity"
+ android:name="org.sufficientlysecure.keychain.remote.ui.AppSettingsActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:exported="false" />
<!-- OpenPGP Remote API -->
<service
- android:name="org.sufficientlysecure.keychain.service.remote.OpenPgpService"
+ android:name="org.sufficientlysecure.keychain.remote.OpenPgpService"
android:enabled="true"
android:exported="true"
android:process=":remote_api">
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
index ff4abe56a..f9a7962ec 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
@@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain;
import android.os.Environment;
import org.spongycastle.jce.provider.BouncyCastleProvider;
-import org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity;
+import org.sufficientlysecure.keychain.remote.ui.AppsListActivity;
import org.sufficientlysecure.keychain.ui.DecryptActivity;
import org.sufficientlysecure.keychain.ui.EncryptActivity;
import org.sufficientlysecure.keychain.ui.ImportKeysActivity;
@@ -73,7 +73,7 @@ public final class Constants {
public static final Class ENCRYPT = EncryptActivity.class;
public static final Class DECRYPT = DecryptActivity.class;
public static final Class IMPORT_KEYS = ImportKeysActivity.class;
- public static final Class REGISTERED_APPS_LIST = RegisteredAppsListActivity.class;
+ public static final Class REGISTERED_APPS_LIST = AppsListActivity.class;
public static final Class[] ARRAY = new Class[]{KEY_LIST, ENCRYPT, DECRYPT,
IMPORT_KEYS, REGISTERED_APPS_LIST};
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java
index 03cf936ee..cc240a67b 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java
@@ -53,14 +53,14 @@ public class ExportHelper {
this.mActivity = activity;
}
- public void deleteKey(Uri dataUri, final int keyType, Handler deleteHandler) {
+ public void deleteKey(Uri dataUri, Handler deleteHandler) {
long keyRingRowId = Long.valueOf(dataUri.getLastPathSegment());
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(deleteHandler);
DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
- new long[]{keyRingRowId}, keyType);
+ new long[]{keyRingRowId});
deleteKeyDialog.show(mActivity.getSupportFragmentManager(), "deleteKeyDialog");
}
@@ -139,7 +139,7 @@ public class ExportHelper {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
- // Message is received after exporting is done in ApgService
+ // Message is received after exporting is done in KeychainIntentService
KeychainIntentServiceHandler exportHandler = new KeychainIntentServiceHandler(mActivity,
mActivity.getString(R.string.progress_exporting),
ProgressDialog.STYLE_HORIZONTAL,
@@ -151,7 +151,7 @@ public class ExportHelper {
}
}) {
public void handleMessage(Message message) {
- // handle messages by standard ApgHandler first
+ // handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java
index 736bff02d..d0ba20ea6 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java
@@ -65,81 +65,4 @@ public class OtherHelper {
}
}
- public static SpannableStringBuilder colorizeFingerprint(String fingerprint) {
- SpannableStringBuilder sb = new SpannableStringBuilder(fingerprint);
- try {
- // for each 4 characters of the fingerprint + 1 space
- for (int i = 0; i < fingerprint.length(); i += 5) {
- int spanEnd = Math.min(i + 4, fingerprint.length());
- String fourChars = fingerprint.substring(i, spanEnd);
-
- int raw = Integer.parseInt(fourChars, 16);
- byte[] bytes = {(byte) ((raw >> 8) & 0xff - 128), (byte) (raw & 0xff - 128)};
- int[] color = OtherHelper.getRgbForData(bytes);
- int r = color[0];
- int g = color[1];
- int b = color[2];
-
- // we cannot change black by multiplication, so adjust it to an almost-black grey,
- // which will then be brightened to the minimal brightness level
- if (r == 0 && g == 0 && b == 0) {
- r = 1;
- g = 1;
- b = 1;
- }
-
- // Convert rgb to brightness
- double brightness = 0.2126 * r + 0.7152 * g + 0.0722 * b;
-
- // If a color is too dark to be seen on black,
- // then brighten it up to a minimal brightness.
- if (brightness < 80) {
- double factor = 80.0 / brightness;
- r = Math.min(255, (int) (r * factor));
- g = Math.min(255, (int) (g * factor));
- b = Math.min(255, (int) (b * factor));
-
- // If it is too light, then darken it to a respective maximal brightness.
- } else if (brightness > 180) {
- double factor = 180.0 / brightness;
- r = (int) (r * factor);
- g = (int) (g * factor);
- b = (int) (b * factor);
- }
-
- // Create a foreground color with the 3 digest integers as RGB
- // and then converting that int to hex to use as a color
- sb.setSpan(new ForegroundColorSpan(Color.rgb(r, g, b)),
- i, spanEnd, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
- }
- } catch (Exception e) {
- Log.e(Constants.TAG, "Colorization failed", e);
- // if anything goes wrong, then just display the fingerprint without colour,
- // instead of partially correct colour or wrong colours
- return new SpannableStringBuilder(fingerprint);
- }
-
- return sb;
- }
-
- /**
- * Converts the given bytes to a unique RGB color using SHA1 algorithm
- *
- * @param bytes
- * @return an integer array containing 3 numeric color representations (Red, Green, Black)
- * @throws NoSuchAlgorithmException
- * @throws DigestException
- */
- public static int[] getRgbForData(byte[] bytes) throws NoSuchAlgorithmException, DigestException {
- MessageDigest md = MessageDigest.getInstance("SHA1");
-
- md.update(bytes);
- byte[] digest = md.digest();
-
- int[] result = {((int) digest[0] + 256) % 256,
- ((int) digest[1] + 256) % 256,
- ((int) digest[2] + 256) % 256};
- return result;
- }
-
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java
index 5b00d163a..b7db92b9b 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java
@@ -18,6 +18,11 @@
package org.sufficientlysecure.keychain.pgp;
import android.content.Context;
+import android.graphics.Color;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.style.ForegroundColorSpan;
+
import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.openpgp.*;
import org.spongycastle.util.encoders.Hex;
@@ -27,6 +32,9 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
+import java.security.DigestException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -444,7 +452,7 @@ public class PgpKeyHelper {
key = secretKey.getPublicKey();
}
- return convertFingerprintToHex(key.getFingerprint(), true);
+ return convertFingerprintToHex(key.getFingerprint());
}
/**
@@ -457,11 +465,8 @@ public class PgpKeyHelper {
* @param split split into 4 character chunks
* @return
*/
- public static String convertFingerprintToHex(byte[] fingerprint, boolean split) {
+ public static String convertFingerprintToHex(byte[] fingerprint) {
String hexString = Hex.toHexString(fingerprint);
- if (split) {
- hexString = hexString.replaceAll("(.{4})(?!$)", "$1 ");
- }
return hexString;
}
@@ -477,6 +482,11 @@ public class PgpKeyHelper {
* @return
*/
public static String convertKeyIdToHex(long keyId) {
+ long upper = keyId >> 32;
+ if (upper == 0) {
+ // this is a short key id
+ return convertKeyIdToHexShort(keyId);
+ }
return "0x" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId);
}
@@ -492,17 +502,90 @@ public class PgpKeyHelper {
return hexString;
}
+
+ public static SpannableStringBuilder colorizeFingerprint(String fingerprint) {
+ // split by 4 characters
+ fingerprint = fingerprint.replaceAll("(.{4})(?!$)", "$1 ");
+
+ // add line breaks to have a consistent "image" that can be recognized
+ char[] chars = fingerprint.toCharArray();
+ chars[24] = '\n';
+ fingerprint = String.valueOf(chars);
+
+ SpannableStringBuilder sb = new SpannableStringBuilder(fingerprint);
+ try {
+ // for each 4 characters of the fingerprint + 1 space
+ for (int i = 0; i < fingerprint.length(); i += 5) {
+ int spanEnd = Math.min(i + 4, fingerprint.length());
+ String fourChars = fingerprint.substring(i, spanEnd);
+
+ int raw = Integer.parseInt(fourChars, 16);
+ byte[] bytes = {(byte) ((raw >> 8) & 0xff - 128), (byte) (raw & 0xff - 128)};
+ int[] color = getRgbForData(bytes);
+ int r = color[0];
+ int g = color[1];
+ int b = color[2];
+
+ // we cannot change black by multiplication, so adjust it to an almost-black grey,
+ // which will then be brightened to the minimal brightness level
+ if (r == 0 && g == 0 && b == 0) {
+ r = 1;
+ g = 1;
+ b = 1;
+ }
+
+ // Convert rgb to brightness
+ double brightness = 0.2126 * r + 0.7152 * g + 0.0722 * b;
+
+ // If a color is too dark to be seen on black,
+ // then brighten it up to a minimal brightness.
+ if (brightness < 80) {
+ double factor = 80.0 / brightness;
+ r = Math.min(255, (int) (r * factor));
+ g = Math.min(255, (int) (g * factor));
+ b = Math.min(255, (int) (b * factor));
+
+ // If it is too light, then darken it to a respective maximal brightness.
+ } else if (brightness > 180) {
+ double factor = 180.0 / brightness;
+ r = (int) (r * factor);
+ g = (int) (g * factor);
+ b = (int) (b * factor);
+ }
+
+ // Create a foreground color with the 3 digest integers as RGB
+ // and then converting that int to hex to use as a color
+ sb.setSpan(new ForegroundColorSpan(Color.rgb(r, g, b)),
+ i, spanEnd, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+ }
+ } catch (Exception e) {
+ Log.e(Constants.TAG, "Colorization failed", e);
+ // if anything goes wrong, then just display the fingerprint without colour,
+ // instead of partially correct colour or wrong colours
+ return new SpannableStringBuilder(fingerprint);
+ }
+
+ return sb;
+ }
+
/**
- * Used in HkpKeyServer to convert hex encoded key ids back to long.
+ * Converts the given bytes to a unique RGB color using SHA1 algorithm
*
- * @param hexString
- * @return
+ * @param bytes
+ * @return an integer array containing 3 numeric color representations (Red, Green, Black)
+ * @throws java.security.NoSuchAlgorithmException
+ * @throws java.security.DigestException
*/
- public static long convertHexToKeyId(String hexString) {
- int len = hexString.length();
- String s2 = hexString.substring(len - 8);
- String s1 = hexString.substring(0, len - 8);
- return ((!s1.isEmpty() ? Long.parseLong(s1, 16) << 32 : 0) | Long.parseLong(s2, 16));
+ private static int[] getRgbForData(byte[] bytes) throws NoSuchAlgorithmException, DigestException {
+ MessageDigest md = MessageDigest.getInstance("SHA1");
+
+ md.update(bytes);
+ byte[] digest = md.digest();
+
+ int[] result = {((int) digest[0] + 256) % 256,
+ ((int) digest[1] + 256) % 256,
+ ((int) digest[2] + 256) % 256};
+ return result;
}
/**
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
index 5f2354c24..6e4899fc2 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
@@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.provider;
import android.net.Uri;
import android.provider.BaseColumns;
+
import org.sufficientlysecure.keychain.Constants;
public class KeychainContract {
@@ -56,10 +57,15 @@ public class KeychainContract {
interface ApiAppsColumns {
String PACKAGE_NAME = "package_name";
String PACKAGE_SIGNATURE = "package_signature";
+ }
+
+ interface ApiAppsAccountsColumns {
+ String ACCOUNT_NAME = "account_name";
String KEY_ID = "key_id"; // not a database id
String ENCRYPTION_ALGORITHM = "encryption_algorithm";
String HASH_ALORITHM = "hash_algorithm";
String COMPRESSION = "compression";
+ String PACKAGE_NAME_FK = "package_name"; // foreign key to api_apps.package_name
}
public static final class KeyTypes {
@@ -87,7 +93,7 @@ public class KeychainContract {
public static final String PATH_KEYS = "keys";
public static final String BASE_API_APPS = "api_apps";
- public static final String PATH_BY_PACKAGE_NAME = "package_name";
+ public static final String PATH_ACCOUNTS = "accounts";
public static class KeyRings implements KeyRingsColumns, BaseColumns {
public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
@@ -154,6 +160,7 @@ public class KeychainContract {
}
public static Uri buildSecretKeyRingsByEmailsUri(String emails) {
+ // TODO: encoded?
return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(PATH_BY_EMAILS)
.appendPath(emails).build();
}
@@ -262,16 +269,36 @@ public class KeychainContract {
/**
* Use if a single item is returned
*/
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_apps";
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_app";
- public static Uri buildIdUri(String rowId) {
- return CONTENT_URI.buildUpon().appendPath(rowId).build();
+ public static Uri buildByPackageNameUri(String packageName) {
+ return CONTENT_URI.buildUpon().appendEncodedPath(packageName).build();
}
+ }
- public static Uri buildByPackageNameUri(String packageName) {
- return CONTENT_URI.buildUpon().appendPath(PATH_BY_PACKAGE_NAME).appendPath(packageName)
+ public static class ApiAccounts implements ApiAppsAccountsColumns, BaseColumns {
+ public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
+ .appendPath(BASE_API_APPS).build();
+
+ /**
+ * Use if multiple items get returned
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api_app.accounts";
+
+ /**
+ * Use if a single item is returned
+ */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_app.account";
+
+ public static Uri buildBaseUri(String packageName) {
+ return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS)
.build();
}
+
+ public static Uri buildByPackageAndAccountUri(String packageName, String accountName) {
+ return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS)
+ .appendEncodedPath(accountName).build();
+ }
}
public static class DataStream {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
index 031a7d5ae..4abcec435 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
@@ -21,8 +21,10 @@ import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
+
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns;
+import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns;
@@ -30,13 +32,14 @@ import org.sufficientlysecure.keychain.util.Log;
public class KeychainDatabase extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "apg.db";
- private static final int DATABASE_VERSION = 7;
+ private static final int DATABASE_VERSION = 8;
public interface Tables {
String KEY_RINGS = "key_rings";
String KEYS = "keys";
String USER_IDS = "user_ids";
String API_APPS = "api_apps";
+ String API_ACCOUNTS = "api_accounts";
}
private static final String CREATE_KEY_RINGS = "CREATE TABLE IF NOT EXISTS " + Tables.KEY_RINGS
@@ -61,26 +64,35 @@ public class KeychainDatabase extends SQLiteOpenHelper {
+ KeysColumns.KEY_DATA + " BLOB,"
+ KeysColumns.RANK + " INTEGER, "
+ KeysColumns.FINGERPRINT + " BLOB, "
- + KeysColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, FOREIGN KEY("
- + KeysColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "("
- + BaseColumns._ID + ") ON DELETE CASCADE)";
+ + KeysColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, "
+ + "FOREIGN KEY(" + KeysColumns.KEY_RING_ROW_ID + ") REFERENCES "
+ + Tables.KEY_RINGS + "(" + BaseColumns._ID + ") ON DELETE CASCADE)";
private static final String CREATE_USER_IDS = "CREATE TABLE IF NOT EXISTS " + Tables.USER_IDS
+ " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ UserIdsColumns.USER_ID + " TEXT, "
+ UserIdsColumns.RANK + " INTEGER, "
- + UserIdsColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, FOREIGN KEY("
- + UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "("
- + BaseColumns._ID + ") ON DELETE CASCADE)";
+ + UserIdsColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, "
+ + "FOREIGN KEY(" + UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES "
+ + Tables.KEY_RINGS + "(" + BaseColumns._ID + ") ON DELETE CASCADE)";
private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS
+ " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
- + ApiAppsColumns.PACKAGE_NAME + " TEXT UNIQUE, "
- + ApiAppsColumns.PACKAGE_SIGNATURE + " BLOB, "
- + ApiAppsColumns.KEY_ID + " INT64, "
- + ApiAppsColumns.ENCRYPTION_ALGORITHM + " INTEGER, "
- + ApiAppsColumns.HASH_ALORITHM + " INTEGER, "
- + ApiAppsColumns.COMPRESSION + " INTEGER)";
+ + ApiAppsColumns.PACKAGE_NAME + " TEXT NOT NULL UNIQUE, "
+ + ApiAppsColumns.PACKAGE_SIGNATURE + " BLOB)";
+
+ private static final String CREATE_API_APPS_ACCOUNTS = "CREATE TABLE IF NOT EXISTS " + Tables.API_ACCOUNTS
+ + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + ApiAppsAccountsColumns.ACCOUNT_NAME + " TEXT NOT NULL, "
+ + ApiAppsAccountsColumns.KEY_ID + " INT64, "
+ + ApiAppsAccountsColumns.ENCRYPTION_ALGORITHM + " INTEGER, "
+ + ApiAppsAccountsColumns.HASH_ALORITHM + " INTEGER, "
+ + ApiAppsAccountsColumns.COMPRESSION + " INTEGER, "
+ + ApiAppsAccountsColumns.PACKAGE_NAME_FK + " TEXT NOT NULL, "
+ + "UNIQUE(" + ApiAppsAccountsColumns.ACCOUNT_NAME + ", "
+ + ApiAppsAccountsColumns.PACKAGE_NAME_FK + "), "
+ + "FOREIGN KEY(" + ApiAppsAccountsColumns.PACKAGE_NAME_FK + ") REFERENCES "
+ + Tables.API_APPS + "(" + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE)";
KeychainDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
@@ -94,6 +106,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
db.execSQL(CREATE_KEYS);
db.execSQL(CREATE_USER_IDS);
db.execSQL(CREATE_API_APPS);
+ db.execSQL(CREATE_API_APPS_ACCOUNTS);
}
@Override
@@ -133,6 +146,12 @@ public class KeychainDatabase extends SQLiteOpenHelper {
db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.FINGERPRINT
+ " BLOB;");
break;
+ case 7:
+ // new db layout for api apps
+ db.execSQL("DROP TABLE IF EXISTS " + Tables.API_APPS);
+ db.execSQL(CREATE_API_APPS);
+ db.execSQL(CREATE_API_APPS_ACCOUNTS);
+ break;
default:
break;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
index b963ceb39..6469da978 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,8 +28,17 @@ import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;
+
import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.provider.KeychainContract.*;
+import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts;
+import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeyTypes;
+import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.util.Log;
@@ -71,8 +80,9 @@ public class KeychainProvider extends ContentProvider {
private static final int SECRET_KEY_RING_USER_ID_BY_ROW_ID = 222;
private static final int API_APPS = 301;
- private static final int API_APPS_BY_ROW_ID = 302;
private static final int API_APPS_BY_PACKAGE_NAME = 303;
+ private static final int API_ACCOUNTS = 304;
+ private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 306;
private static final int UNIFIED_KEY_RING = 401;
@@ -229,11 +239,22 @@ public class KeychainProvider extends ContentProvider {
/**
* API apps
+ *
+ * <pre>
+ * api_apps
+ * api_apps/_ (package name)
+ *
+ * api_apps/_/accounts
+ * api_apps/_/accounts/_ (account name)
+ * </pre>
*/
matcher.addURI(authority, KeychainContract.BASE_API_APPS, API_APPS);
- matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/#", API_APPS_BY_ROW_ID);
- matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/"
- + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_APPS_BY_PACKAGE_NAME);
+ matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*", API_APPS_BY_PACKAGE_NAME);
+
+ matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/"
+ + KeychainContract.PATH_ACCOUNTS, API_ACCOUNTS);
+ matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/"
+ + KeychainContract.PATH_ACCOUNTS + "/*", API_ACCOUNTS_BY_ACCOUNT_NAME);
/**
* data stream
@@ -247,7 +268,7 @@ public class KeychainProvider extends ContentProvider {
return matcher;
}
- private KeychainDatabase mApgDatabase;
+ private KeychainDatabase mKeychainDatabase;
/**
* {@inheritDoc}
@@ -255,7 +276,7 @@ public class KeychainProvider extends ContentProvider {
@Override
public boolean onCreate() {
mUriMatcher = buildUriMatcher();
- mApgDatabase = new KeychainDatabase(getContext());
+ mKeychainDatabase = new KeychainDatabase(getContext());
return true;
}
@@ -302,10 +323,15 @@ public class KeychainProvider extends ContentProvider {
case API_APPS:
return ApiApps.CONTENT_TYPE;
- case API_APPS_BY_ROW_ID:
case API_APPS_BY_PACKAGE_NAME:
return ApiApps.CONTENT_ITEM_TYPE;
+ case API_ACCOUNTS:
+ return ApiAccounts.CONTENT_TYPE;
+
+ case API_ACCOUNTS_BY_ACCOUNT_NAME:
+ return ApiAccounts.CONTENT_ITEM_TYPE;
+
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
@@ -486,7 +512,7 @@ public class KeychainProvider extends ContentProvider {
Log.v(Constants.TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")");
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
- SQLiteDatabase db = mApgDatabase.getReadableDatabase();
+ SQLiteDatabase db = mKeychainDatabase.getReadableDatabase();
int match = mUriMatcher.match(uri);
@@ -506,7 +532,6 @@ public class KeychainProvider extends ContentProvider {
}
break;
-
case PUBLIC_KEY_RING:
case SECRET_KEY_RING:
qb = buildKeyRingQuery(qb, match);
@@ -516,7 +541,6 @@ public class KeychainProvider extends ContentProvider {
}
break;
-
case PUBLIC_KEY_RING_BY_ROW_ID:
case SECRET_KEY_RING_BY_ROW_ID:
qb = buildKeyRingQuery(qb, match);
@@ -529,7 +553,6 @@ public class KeychainProvider extends ContentProvider {
}
break;
-
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID:
case SECRET_KEY_RING_BY_MASTER_KEY_ID:
qb = buildKeyRingQuery(qb, match);
@@ -542,7 +565,6 @@ public class KeychainProvider extends ContentProvider {
}
break;
-
case SECRET_KEY_RING_BY_KEY_ID:
case PUBLIC_KEY_RING_BY_KEY_ID:
qb = buildKeyRingQueryWithSpecificKey(qb, match);
@@ -555,7 +577,6 @@ public class KeychainProvider extends ContentProvider {
}
break;
-
case SECRET_KEY_RING_BY_EMAILS:
case PUBLIC_KEY_RING_BY_EMAILS:
qb = buildKeyRingQuery(qb, match);
@@ -585,7 +606,6 @@ public class KeychainProvider extends ContentProvider {
}
break;
-
case SECRET_KEY_RING_BY_LIKE_EMAIL:
case PUBLIC_KEY_RING_BY_LIKE_EMAIL:
qb = buildKeyRingQuery(qb, match);
@@ -601,7 +621,6 @@ public class KeychainProvider extends ContentProvider {
+ "))");
break;
-
case PUBLIC_KEY_RING_KEY:
case SECRET_KEY_RING_KEY:
qb.setTables(Tables.KEYS);
@@ -614,7 +633,6 @@ public class KeychainProvider extends ContentProvider {
qb.setProjectionMap(getProjectionMapForKeys());
break;
-
case PUBLIC_KEY_RING_KEY_BY_ROW_ID:
case SECRET_KEY_RING_KEY_BY_ROW_ID:
qb.setTables(Tables.KEYS);
@@ -630,7 +648,6 @@ public class KeychainProvider extends ContentProvider {
qb.setProjectionMap(getProjectionMapForKeys());
break;
-
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID_USER_ID:
qb.setTables(Tables.USER_IDS + " INNER JOIN " + Tables.KEY_RINGS + " ON " + "("
+ Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "."
@@ -641,7 +658,6 @@ public class KeychainProvider extends ContentProvider {
qb.setProjectionMap(getProjectionMapForUserIds());
break;
-
case PUBLIC_KEY_RING_USER_ID:
case SECRET_KEY_RING_USER_ID:
qb.setTables(Tables.USER_IDS);
@@ -649,7 +665,6 @@ public class KeychainProvider extends ContentProvider {
qb.appendWhereEscapeString(uri.getPathSegments().get(2));
break;
-
case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID:
case SECRET_KEY_RING_USER_ID_BY_ROW_ID:
qb.setTables(Tables.USER_IDS);
@@ -660,25 +675,31 @@ public class KeychainProvider extends ContentProvider {
qb.appendWhereEscapeString(uri.getLastPathSegment());
break;
-
case API_APPS:
qb.setTables(Tables.API_APPS);
break;
- case API_APPS_BY_ROW_ID:
+ case API_APPS_BY_PACKAGE_NAME:
qb.setTables(Tables.API_APPS);
-
- qb.appendWhere(BaseColumns._ID + " = ");
+ qb.appendWhere(ApiApps.PACKAGE_NAME + " = ");
qb.appendWhereEscapeString(uri.getLastPathSegment());
break;
- case API_APPS_BY_PACKAGE_NAME:
- qb.setTables(Tables.API_APPS);
- qb.appendWhere(ApiApps.PACKAGE_NAME + " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(2));
+ case API_ACCOUNTS:
+ qb.setTables(Tables.API_ACCOUNTS);
break;
+ case API_ACCOUNTS_BY_ACCOUNT_NAME:
+ qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "("
+ + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "."
+ + ApiAccounts.PACKAGE_NAME_FK + " )");
+ qb.appendWhere(Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = ");
+ qb.appendWhereEscapeString(uri.getPathSegments().get(1));
+
+ qb.appendWhere(" AND " + Tables.API_ACCOUNTS + "." + ApiAccounts.ACCOUNT_NAME + " = ");
+ qb.appendWhereEscapeString(uri.getLastPathSegment());
+ break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
@@ -715,7 +736,7 @@ public class KeychainProvider extends ContentProvider {
public Uri insert(Uri uri, ContentValues values) {
Log.d(Constants.TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")");
- final SQLiteDatabase db = mApgDatabase.getWritableDatabase();
+ final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase();
Uri rowUri = null;
long rowId = -1;
@@ -735,12 +756,14 @@ public class KeychainProvider extends ContentProvider {
values.put(Keys.TYPE, KeyTypes.PUBLIC);
rowId = db.insertOrThrow(Tables.KEYS, null, values);
+ // TODO: this is wrong:
rowUri = Keys.buildPublicKeysUri(Long.toString(rowId));
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
break;
case PUBLIC_KEY_RING_USER_ID:
rowId = db.insertOrThrow(Tables.USER_IDS, null, values);
+ // TODO: this is wrong:
rowUri = UserIds.buildPublicUserIdsUri(Long.toString(rowId));
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
@@ -757,18 +780,33 @@ public class KeychainProvider extends ContentProvider {
values.put(Keys.TYPE, KeyTypes.SECRET);
rowId = db.insertOrThrow(Tables.KEYS, null, values);
+ // TODO: this is wrong:
rowUri = Keys.buildSecretKeysUri(Long.toString(rowId));
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
break;
case SECRET_KEY_RING_USER_ID:
rowId = db.insertOrThrow(Tables.USER_IDS, null, values);
+ // TODO: this is wrong:
rowUri = UserIds.buildSecretUserIdsUri(Long.toString(rowId));
break;
case API_APPS:
rowId = db.insertOrThrow(Tables.API_APPS, null, values);
- rowUri = ApiApps.buildIdUri(Long.toString(rowId));
+// rowUri = ApiApps.buildIdUri(Long.toString(rowId));
+
+ break;
+ case API_ACCOUNTS:
+ // set foreign key automatically based on given uri
+ // e.g., api_apps/com.example.app/accounts/
+ String packageName = uri.getPathSegments().get(1);
+ values.put(ApiAccounts.PACKAGE_NAME_FK, packageName);
+
+ Log.d(Constants.TAG, "provider packageName: " + packageName);
+
+ rowId = db.insertOrThrow(Tables.API_ACCOUNTS, null, values);
+ // TODO: this is wrong:
+// rowUri = ApiAccounts.buildIdUri(Long.toString(rowId));
break;
default:
@@ -792,7 +830,7 @@ public class KeychainProvider extends ContentProvider {
public int delete(Uri uri, String selection, String[] selectionArgs) {
Log.v(Constants.TAG, "delete(uri=" + uri + ")");
- final SQLiteDatabase db = mApgDatabase.getWritableDatabase();
+ final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase();
int count;
final int match = mUriMatcher.match(uri);
@@ -828,12 +866,12 @@ public class KeychainProvider extends ContentProvider {
count = db.delete(Tables.KEYS, buildDefaultUserIdsSelection(uri, selection),
selectionArgs);
break;
- case API_APPS_BY_ROW_ID:
- count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, false, selection),
+ case API_APPS_BY_PACKAGE_NAME:
+ count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, selection),
selectionArgs);
break;
- case API_APPS_BY_PACKAGE_NAME:
- count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, true, selection),
+ case API_ACCOUNTS_BY_ACCOUNT_NAME:
+ count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, selection),
selectionArgs);
break;
default:
@@ -853,7 +891,7 @@ public class KeychainProvider extends ContentProvider {
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
Log.v(Constants.TAG, "update(uri=" + uri + ", values=" + values.toString() + ")");
- final SQLiteDatabase db = mApgDatabase.getWritableDatabase();
+ final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase();
String defaultSelection = null;
int count = 0;
@@ -898,13 +936,13 @@ public class KeychainProvider extends ContentProvider {
count = db.update(Tables.USER_IDS, values,
buildDefaultUserIdsSelection(uri, selection), selectionArgs);
break;
- case API_APPS_BY_ROW_ID:
- count = db.update(Tables.API_APPS, values,
- buildDefaultApiAppsSelection(uri, false, selection), selectionArgs);
- break;
case API_APPS_BY_PACKAGE_NAME:
count = db.update(Tables.API_APPS, values,
- buildDefaultApiAppsSelection(uri, true, selection), selectionArgs);
+ buildDefaultApiAppsSelection(uri, selection), selectionArgs);
+ break;
+ case API_ACCOUNTS_BY_ACCOUNT_NAME:
+ count = db.update(Tables.API_ACCOUNTS, values,
+ buildDefaultApiAccountsSelection(uri, selection), selectionArgs);
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
@@ -1003,19 +1041,29 @@ public class KeychainProvider extends ContentProvider {
* @param selection
* @return
*/
- private String buildDefaultApiAppsSelection(Uri uri, boolean packageSelection, String selection) {
- String lastPathSegment = uri.getLastPathSegment();
+ private String buildDefaultApiAppsSelection(Uri uri, String selection) {
+ String packageName = DatabaseUtils.sqlEscapeString(uri.getLastPathSegment());
String andSelection = "";
if (!TextUtils.isEmpty(selection)) {
andSelection = " AND (" + selection + ")";
}
- if (packageSelection) {
- return ApiApps.PACKAGE_NAME + "=" + lastPathSegment + andSelection;
- } else {
- return BaseColumns._ID + "=" + lastPathSegment + andSelection;
+ return ApiApps.PACKAGE_NAME + "=" + packageName + andSelection;
+ }
+
+ private String buildDefaultApiAccountsSelection(Uri uri, String selection) {
+ String packageName = DatabaseUtils.sqlEscapeString(uri.getPathSegments().get(1));
+ String accountName = DatabaseUtils.sqlEscapeString(uri.getLastPathSegment());
+
+ String andSelection = "";
+ if (!TextUtils.isEmpty(selection)) {
+ andSelection = " AND (" + selection + ")";
}
+
+ return ApiAccounts.PACKAGE_NAME_FK + "=" + packageName + " AND "
+ + ApiAccounts.ACCOUNT_NAME + "=" + accountName
+ + andSelection;
}
// @Override
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java
index 6ac61e157..aa30e845d 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java
@@ -38,7 +38,7 @@ import java.util.List;
import java.util.UUID;
public class KeychainServiceBlobProvider extends ContentProvider {
- private static final String STORE_PATH = Constants.Path.APP_DIR + "/ApgBlobs";
+ private static final String STORE_PATH = Constants.Path.APP_DIR + "/KeychainBlobs";
private KeychainServiceBlobDatabase mBlobDatabase = null;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
index db2c57207..71f74b8d8 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -22,6 +22,7 @@ import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
import android.os.RemoteException;
+
import org.spongycastle.bcpg.ArmoredOutputStream;
import org.spongycastle.openpgp.*;
import org.sufficientlysecure.keychain.Constants;
@@ -33,7 +34,8 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
-import org.sufficientlysecure.keychain.service.remote.AppSettings;
+import org.sufficientlysecure.keychain.remote.AccountSettings;
+import org.sufficientlysecure.keychain.remote.AppSettings;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
@@ -230,7 +232,7 @@ public class ProviderHelper {
// get current _ID of key
long currentRowId = -1;
Cursor oldQuery = context.getContentResolver()
- .query(deleteUri, new String[]{KeyRings._ID}, null, null, null);
+ .query(deleteUri, new String[]{KeyRings._ID}, null, null, null);
if (oldQuery != null && oldQuery.moveToFirst()) {
currentRowId = oldQuery.getLong(0);
} else {
@@ -288,7 +290,7 @@ public class ProviderHelper {
* Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing
*/
private static ContentProviderOperation buildPublicKeyOperations(Context context,
- long keyRingRowId, PGPPublicKey key, int rank) throws IOException {
+ long keyRingRowId, PGPPublicKey key, int rank) throws IOException {
ContentValues values = new ContentValues();
values.put(Keys.KEY_ID, key.getKeyID());
values.put(Keys.IS_MASTER_KEY, key.isMasterKey());
@@ -316,7 +318,7 @@ public class ProviderHelper {
* Build ContentProviderOperation to add PublicUserIds to database corresponding to a keyRing
*/
private static ContentProviderOperation buildPublicUserIdOperations(Context context,
- long keyRingRowId, String userId, int rank) {
+ long keyRingRowId, String userId, int rank) {
ContentValues values = new ContentValues();
values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId);
values.put(UserIds.USER_ID, userId);
@@ -331,7 +333,7 @@ public class ProviderHelper {
* Build ContentProviderOperation to add PGPSecretKey to database corresponding to a keyRing
*/
private static ContentProviderOperation buildSecretKeyOperations(Context context,
- long keyRingRowId, PGPSecretKey key, int rank) throws IOException {
+ long keyRingRowId, PGPSecretKey key, int rank) throws IOException {
ContentValues values = new ContentValues();
boolean hasPrivate = true;
@@ -368,7 +370,7 @@ public class ProviderHelper {
* Build ContentProviderOperation to add SecretUserIds to database corresponding to a keyRing
*/
private static ContentProviderOperation buildSecretUserIdOperations(Context context,
- long keyRingRowId, String userId, int rank) {
+ long keyRingRowId, String userId, int rank) {
ContentValues values = new ContentValues();
values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId);
values.put(UserIds.USER_ID, userId);
@@ -469,6 +471,15 @@ public class ProviderHelper {
cr.delete(KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)), null, null);
}
+ public static void deleteUnifiedKeyRing(Context context, String masterKeyId, boolean isSecretKey) {
+ ContentResolver cr = context.getContentResolver();
+ cr.delete(KeyRings.buildPublicKeyRingsByMasterKeyIdUri(masterKeyId), null, null);
+ if (isSecretKey) {
+ cr.delete(KeyRings.buildSecretKeyRingsByMasterKeyIdUri(masterKeyId), null, null);
+ }
+
+ }
+
/**
* Get master key id of keyring by its row id
*/
@@ -495,7 +506,7 @@ public class ProviderHelper {
+ " AS sign_keys WHERE sign_keys." + Keys.KEY_RING_ROW_ID + " = "
+ KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID
+ " AND sign_keys." + Keys.CAN_SIGN + " = '1' AND " + Keys.IS_MASTER_KEY
- + " = 1) AS sign", };
+ + " = 1) AS sign",};
ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(queryUri, projection, null, null, null);
@@ -792,19 +803,28 @@ public class ProviderHelper {
ContentValues values = new ContentValues();
values.put(ApiApps.PACKAGE_NAME, appSettings.getPackageName());
values.put(ApiApps.PACKAGE_SIGNATURE, appSettings.getPackageSignature());
- values.put(ApiApps.KEY_ID, appSettings.getKeyId());
- values.put(ApiApps.COMPRESSION, appSettings.getCompression());
- values.put(ApiApps.ENCRYPTION_ALGORITHM, appSettings.getEncryptionAlgorithm());
- values.put(ApiApps.HASH_ALORITHM, appSettings.getHashAlgorithm());
+ return values;
+ }
+ private static ContentValues contentValueForApiAccounts(AccountSettings accSettings) {
+ ContentValues values = new ContentValues();
+ values.put(KeychainContract.ApiAccounts.ACCOUNT_NAME, accSettings.getAccountName());
+ values.put(KeychainContract.ApiAccounts.KEY_ID, accSettings.getKeyId());
+ values.put(KeychainContract.ApiAccounts.COMPRESSION, accSettings.getCompression());
+ values.put(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM, accSettings.getEncryptionAlgorithm());
+ values.put(KeychainContract.ApiAccounts.HASH_ALORITHM, accSettings.getHashAlgorithm());
return values;
}
public static void insertApiApp(Context context, AppSettings appSettings) {
- context.getContentResolver().insert(ApiApps.CONTENT_URI,
+ context.getContentResolver().insert(KeychainContract.ApiApps.CONTENT_URI,
contentValueForApiApps(appSettings));
}
+ public static void insertApiAccount(Context context, Uri uri, AccountSettings accSettings) {
+ context.getContentResolver().insert(uri, contentValueForApiAccounts(accSettings));
+ }
+
public static void updateApiApp(Context context, AppSettings appSettings, Uri uri) {
if (context.getContentResolver().update(uri, contentValueForApiApps(appSettings), null,
null) <= 0) {
@@ -812,30 +832,59 @@ public class ProviderHelper {
}
}
+ public static void updateApiAccount(Context context, AccountSettings accSettings, Uri uri) {
+ if (context.getContentResolver().update(uri, contentValueForApiAccounts(accSettings), null,
+ null) <= 0) {
+ throw new RuntimeException();
+ }
+ }
+
+ /**
+ * Must be an uri pointing to an account
+ *
+ * @param context
+ * @param uri
+ * @return
+ */
public static AppSettings getApiAppSettings(Context context, Uri uri) {
AppSettings settings = null;
Cursor cur = context.getContentResolver().query(uri, null, null, null, null);
if (cur != null && cur.moveToFirst()) {
settings = new AppSettings();
- settings.setPackageName(cur.getString(cur
- .getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME)));
- settings.setPackageSignature(cur.getBlob(cur
- .getColumnIndex(KeychainContract.ApiApps.PACKAGE_SIGNATURE)));
- settings.setKeyId(cur.getLong(cur.getColumnIndex(KeychainContract.ApiApps.KEY_ID)));
- settings.setCompression(cur.getInt(cur
- .getColumnIndexOrThrow(KeychainContract.ApiApps.COMPRESSION)));
- settings.setHashAlgorithm(cur.getInt(cur
- .getColumnIndexOrThrow(KeychainContract.ApiApps.HASH_ALORITHM)));
- settings.setEncryptionAlgorithm(cur.getInt(cur
- .getColumnIndexOrThrow(KeychainContract.ApiApps.ENCRYPTION_ALGORITHM)));
+ settings.setPackageName(cur.getString(
+ cur.getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME)));
+ settings.setPackageSignature(cur.getBlob(
+ cur.getColumnIndex(KeychainContract.ApiApps.PACKAGE_SIGNATURE)));
+ }
+
+ return settings;
+ }
+
+ public static AccountSettings getApiAccountSettings(Context context, Uri uri) {
+ AccountSettings settings = null;
+
+ Cursor cur = context.getContentResolver().query(uri, null, null, null, null);
+ if (cur != null && cur.moveToFirst()) {
+ settings = new AccountSettings();
+
+ settings.setAccountName(cur.getString(
+ cur.getColumnIndex(KeychainContract.ApiAccounts.ACCOUNT_NAME)));
+ settings.setKeyId(cur.getLong(
+ cur.getColumnIndex(KeychainContract.ApiAccounts.KEY_ID)));
+ settings.setCompression(cur.getInt(
+ cur.getColumnIndexOrThrow(KeychainContract.ApiAccounts.COMPRESSION)));
+ settings.setHashAlgorithm(cur.getInt(
+ cur.getColumnIndexOrThrow(KeychainContract.ApiAccounts.HASH_ALORITHM)));
+ settings.setEncryptionAlgorithm(cur.getInt(
+ cur.getColumnIndexOrThrow(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM)));
}
return settings;
}
public static byte[] getApiAppSignature(Context context, String packageName) {
- Uri queryUri = KeychainContract.ApiApps.buildByPackageNameUri(packageName);
+ Uri queryUri = ApiApps.buildByPackageNameUri(packageName);
String[] projection = new String[]{ApiApps.PACKAGE_SIGNATURE};
@@ -855,4 +904,4 @@ public class ProviderHelper {
return signature;
}
-}
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java
index 6f2d67efb..832cbc752 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettings.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java
@@ -15,48 +15,39 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package org.sufficientlysecure.keychain.service.remote;
+package org.sufficientlysecure.keychain.remote;
import org.spongycastle.bcpg.HashAlgorithmTags;
import org.spongycastle.openpgp.PGPEncryptedData;
import org.sufficientlysecure.keychain.Id;
-public class AppSettings {
- private String mPackageName;
- private byte[] mPackageSignature;
+public class AccountSettings {
+ private String mAccountName;
private long mKeyId = Id.key.none;
private int mEncryptionAlgorithm;
private int mHashAlgorithm;
private int mCompression;
- public AppSettings() {
+ public AccountSettings() {
}
- public AppSettings(String packageName, byte[] packageSignature) {
+ public AccountSettings(String accountName) {
super();
- this.mPackageName = packageName;
- this.mPackageSignature = packageSignature;
+ this.mAccountName = accountName;
+
// defaults:
this.mEncryptionAlgorithm = PGPEncryptedData.AES_256;
this.mHashAlgorithm = HashAlgorithmTags.SHA512;
this.mCompression = Id.choice.compression.zlib;
}
- public String getPackageName() {
- return mPackageName;
- }
-
- public void setPackageName(String packageName) {
- this.mPackageName = packageName;
- }
-
- public byte[] getPackageSignature() {
- return mPackageSignature;
+ public String getAccountName() {
+ return mAccountName;
}
- public void setPackageSignature(byte[] packageSignature) {
- this.mPackageSignature = packageSignature;
+ public void setAccountName(String mAccountName) {
+ this.mAccountName = mAccountName;
}
public long getKeyId() {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java
new file mode 100644
index 000000000..6c7e51bf0
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.remote;
+
+import org.spongycastle.bcpg.HashAlgorithmTags;
+import org.spongycastle.openpgp.PGPEncryptedData;
+import org.sufficientlysecure.keychain.Id;
+
+public class AppSettings {
+ private String mPackageName;
+ private byte[] mPackageSignature;
+
+ public AppSettings() {
+
+ }
+
+ public AppSettings(String packageName, byte[] packageSignature) {
+ super();
+ this.mPackageName = packageName;
+ this.mPackageSignature = packageSignature;
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ public void setPackageName(String packageName) {
+ this.mPackageName = packageName;
+ }
+
+ public byte[] getPackageSignature() {
+ return mPackageSignature;
+ }
+
+ public void setPackageSignature(byte[] packageSignature) {
+ this.mPackageSignature = packageSignature;
+ }
+
+}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
index 95dc897f0..fa6ccf63b 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package org.sufficientlysecure.keychain.service.remote;
+package org.sufficientlysecure.keychain.remote;
import android.app.PendingIntent;
import android.content.Intent;
@@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
@@ -137,7 +138,7 @@ public class OpenPgpService extends RemoteService {
}
private Intent signImpl(Intent data, ParcelFileDescriptor input,
- ParcelFileDescriptor output, AppSettings appSettings) {
+ ParcelFileDescriptor output, AccountSettings accSettings) {
try {
boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
@@ -146,11 +147,11 @@ public class OpenPgpService extends RemoteService {
if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
} else {
- passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId());
+ passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), accSettings.getKeyId());
}
if (passphrase == null) {
// get PendingIntent for passphrase input, add it to given params and return to client
- Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
+ Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId());
return passphraseBundle;
}
@@ -164,9 +165,9 @@ public class OpenPgpService extends RemoteService {
// sign-only
PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os);
builder.enableAsciiArmorOutput(asciiArmor)
- .signatureHashAlgorithm(appSettings.getHashAlgorithm())
+ .signatureHashAlgorithm(accSettings.getHashAlgorithm())
.signatureForceV3(false)
- .signatureKeyId(appSettings.getKeyId())
+ .signatureKeyId(accSettings.getKeyId())
.signaturePassphrase(passphrase);
builder.build().execute();
} finally {
@@ -187,7 +188,7 @@ public class OpenPgpService extends RemoteService {
}
private Intent encryptAndSignImpl(Intent data, ParcelFileDescriptor input,
- ParcelFileDescriptor output, AppSettings appSettings, boolean sign) {
+ ParcelFileDescriptor output, AccountSettings accSettings, boolean sign) {
try {
boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
@@ -217,7 +218,7 @@ public class OpenPgpService extends RemoteService {
// add own key for encryption
keyIds = Arrays.copyOf(keyIds, keyIds.length + 1);
- keyIds[keyIds.length - 1] = appSettings.getKeyId();
+ keyIds[keyIds.length - 1] = accSettings.getKeyId();
// build InputData and write into OutputStream
// Get Input- and OutputStream from ParcelFileDescriptor
@@ -229,8 +230,8 @@ public class OpenPgpService extends RemoteService {
PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os);
builder.enableAsciiArmorOutput(asciiArmor)
- .compressionId(appSettings.getCompression())
- .symmetricEncryptionAlgorithm(appSettings.getEncryptionAlgorithm())
+ .compressionId(accSettings.getCompression())
+ .symmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm())
.encryptionKeyIds(keyIds);
if (sign) {
@@ -239,18 +240,18 @@ public class OpenPgpService extends RemoteService {
passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
} else {
passphrase = PassphraseCacheService.getCachedPassphrase(getContext(),
- appSettings.getKeyId());
+ accSettings.getKeyId());
}
if (passphrase == null) {
// get PendingIntent for passphrase input, add it to given params and return to client
- Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
+ Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId());
return passphraseBundle;
}
// sign and encrypt
- builder.signatureHashAlgorithm(appSettings.getHashAlgorithm())
+ builder.signatureHashAlgorithm(accSettings.getHashAlgorithm())
.signatureForceV3(false)
- .signatureKeyId(appSettings.getKeyId())
+ .signatureKeyId(accSettings.getKeyId())
.signaturePassphrase(passphrase);
} else {
// encrypt only
@@ -276,7 +277,7 @@ public class OpenPgpService extends RemoteService {
}
private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input,
- ParcelFileDescriptor output, AppSettings appSettings) {
+ ParcelFileDescriptor output, AccountSettings accSettings) {
try {
// Get Input- and OutputStream from ParcelFileDescriptor
InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
@@ -292,7 +293,7 @@ public class OpenPgpService extends RemoteService {
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os);
builder.assumeSymmetric(false) // no support for symmetric encryption
// allow only the private key for this app for decryption
- .enforcedKeyId(appSettings.getKeyId())
+ .enforcedKeyId(accSettings.getKeyId())
.passphrase(passphrase);
// TODO: currently does not support binary signed-only content
@@ -300,7 +301,7 @@ public class OpenPgpService extends RemoteService {
if (decryptVerifyResult.isKeyPassphraseNeeded()) {
// get PendingIntent for passphrase input, add it to given params and return to client
- Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
+ Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId());
return passphraseBundle;
} else if (decryptVerifyResult.isSymmetricPassphraseNeeded()) {
throw new PgpGeneralException("Decryption of symmetric content not supported by API!");
@@ -432,17 +433,26 @@ public class OpenPgpService extends RemoteService {
return errorResult;
}
- final AppSettings appSettings = getAppSettings();
+ String accName;
+ if (data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME) != null) {
+ accName = data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME);
+ } else {
+ accName = "default";
+ }
+ final AccountSettings accSettings = getAccSettings(accName);
+ if (accSettings == null) {
+ return getCreateAccountIntent(data, accName);
+ }
String action = data.getAction();
if (OpenPgpApi.ACTION_SIGN.equals(action)) {
- return signImpl(data, input, output, appSettings);
+ return signImpl(data, input, output, accSettings);
} else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) {
- return encryptAndSignImpl(data, input, output, appSettings, false);
+ return encryptAndSignImpl(data, input, output, accSettings, false);
} else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) {
- return encryptAndSignImpl(data, input, output, appSettings, true);
+ return encryptAndSignImpl(data, input, output, accSettings, true);
} else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) {
- return decryptAndVerifyImpl(data, input, output, appSettings);
+ return decryptAndVerifyImpl(data, input, output, accSettings);
} else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) {
return getKeyImpl(data);
} else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java
index 6a883316a..7e935d317 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java
@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package org.sufficientlysecure.keychain.service.remote;
+package org.sufficientlysecure.keychain.remote;
import android.app.PendingIntent;
import android.app.Service;
@@ -27,12 +27,14 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.net.Uri;
import android.os.Binder;
+
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
import org.sufficientlysecure.keychain.util.Log;
import java.util.ArrayList;
@@ -47,7 +49,6 @@ public abstract class RemoteService extends Service {
private static final int PRIVATE_REQUEST_CODE_REGISTER = 651;
private static final int PRIVATE_REQUEST_CODE_ERROR = 652;
-
public Context getContext() {
return mContext;
}
@@ -55,13 +56,9 @@ public abstract class RemoteService extends Service {
protected Intent isAllowed(Intent data) {
try {
if (isCallerAllowed(false)) {
-
return null;
} else {
- String[] callingPackages = getPackageManager().getPackagesForUid(
- Binder.getCallingUid());
- // TODO: currently simply uses first entry
- String packageName = callingPackages[0];
+ String packageName = getCurrentCallingPackage();
byte[] packageSignature;
try {
@@ -84,7 +81,7 @@ public abstract class RemoteService extends Service {
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(),
- PRIVATE_REQUEST_CODE_REGISTER, intent, 0);
+ PRIVATE_REQUEST_CODE_REGISTER, intent, 0);
// return PendingIntent to be executed by client
Intent result = new Intent();
@@ -99,11 +96,11 @@ public abstract class RemoteService extends Service {
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE,
- getString(R.string.api_error_wrong_signature));
+ getString(R.string.api_error_wrong_signature));
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(),
- PRIVATE_REQUEST_CODE_ERROR, intent, 0);
+ PRIVATE_REQUEST_CODE_ERROR, intent, 0);
// return PendingIntent to be executed by client
Intent result = new Intent();
@@ -125,27 +122,56 @@ public abstract class RemoteService extends Service {
}
/**
- * Retrieves AppSettings from database for the application calling this remote service
+ * Returns package name associated with the UID, which is assigned to the process that sent you the
+ * current transaction that is being processed :)
*
- * @return
+ * @return package name
*/
- protected AppSettings getAppSettings() {
+ private String getCurrentCallingPackage() {
+ // TODO:
+ // callingPackages contains more than one entry when sharedUserId has been used...
String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid());
+ String currentPkg = callingPackages[0];
+ Log.d(Constants.TAG, "currentPkg: " + currentPkg);
- // get app settings for this package
- for (int i = 0; i < callingPackages.length; i++) {
- String currentPkg = callingPackages[i];
+ return currentPkg;
+ }
- Uri uri = KeychainContract.ApiApps.buildByPackageNameUri(currentPkg);
+ /**
+ * Retrieves AccountSettings from database for the application calling this remote service
+ *
+ * @return
+ */
+ protected AccountSettings getAccSettings(String accountName) {
+ String currentPkg = getCurrentCallingPackage();
+ Log.d(Constants.TAG, "accountName: " + accountName);
- AppSettings settings = ProviderHelper.getApiAppSettings(this, uri);
+ Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(currentPkg, accountName);
- if (settings != null) {
- return settings;
- }
- }
+ AccountSettings settings = ProviderHelper.getApiAccountSettings(this, uri);
+
+ return settings; // can be null!
+ }
+
+ protected Intent getCreateAccountIntent(Intent data, String accountName) {
+ String packageName = getCurrentCallingPackage();
+ Log.d(Constants.TAG, "accountName: " + accountName);
+
+ Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
+ intent.setAction(RemoteServiceActivity.ACTION_CREATE_ACCOUNT);
+ intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
+ intent.putExtra(RemoteServiceActivity.EXTRA_ACC_NAME, accountName);
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
+
+ PendingIntent pi = PendingIntent.getActivity(getBaseContext(),
+ PRIVATE_REQUEST_CODE_REGISTER, intent, 0);
+
+ // return PendingIntent to be executed by client
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
- return null;
+ return result;
}
/**
@@ -216,7 +242,7 @@ public abstract class RemoteService extends Service {
return true;
} else {
throw new WrongPackageSignatureException(
- "PACKAGE NOT ALLOWED! Signature wrong! (Signature not equals signature from database)");
+ "PACKAGE NOT ALLOWED! Signature wrong! (Signature not equals signature from database)");
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java
index 0b642086a..6f44a65e9 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java
@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package org.sufficientlysecure.keychain.service.remote;
+package org.sufficientlysecure.keychain.remote;
public class WrongPackageSignatureException extends Exception {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java
index 837295018..3d88d216e 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java
@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package org.sufficientlysecure.keychain.service.remote;
+package org.sufficientlysecure.keychain.remote.ui;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -25,16 +25,18 @@ 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.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.widget.*;
+import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
-import com.beardedhen.androidbootstrap.BootstrapButton;
+import android.widget.ImageView;
+import android.widget.Spinner;
+import android.widget.TextView;
+
import org.spongycastle.util.encoders.Hex;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.remote.AccountSettings;
+import org.sufficientlysecure.keychain.remote.AppSettings;
import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment;
import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter;
import org.sufficientlysecure.keychain.util.AlgorithmNames;
@@ -43,15 +45,13 @@ import org.sufficientlysecure.keychain.util.Log;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-public class AppSettingsFragment extends Fragment implements
+public class AccountSettingsFragment extends Fragment implements
SelectSecretKeyLayoutFragment.SelectSecretKeyCallback {
// model
- private AppSettings mAppSettings;
+ private AccountSettings mAccSettings;
// view
- private LinearLayout mAdvancedSettingsContainer;
- private BootstrapButton mAdvancedSettingsButton;
private TextView mAppNameView;
private ImageView mAppIconView;
private Spinner mEncryptionAlgorithm;
@@ -66,25 +66,25 @@ public class AppSettingsFragment extends Fragment implements
KeyValueSpinnerAdapter mHashAdapter;
KeyValueSpinnerAdapter mCompressionAdapter;
- public AppSettings getAppSettings() {
- return mAppSettings;
+ public AccountSettings getAccSettings() {
+ return mAccSettings;
}
- public void setAppSettings(AppSettings appSettings) {
- this.mAppSettings = appSettings;
- setPackage(appSettings.getPackageName());
- mPackageName.setText(appSettings.getPackageName());
-
- try {
- MessageDigest md = MessageDigest.getInstance("SHA-256");
- md.update(appSettings.getPackageSignature());
- byte[] digest = md.digest();
- String signature = new String(Hex.encode(digest));
-
- mPackageSignature.setText(signature);
- } catch (NoSuchAlgorithmException e) {
- Log.e(Constants.TAG, "Should not happen!", e);
- }
+ public void setAccSettings(AccountSettings appSettings) {
+ this.mAccSettings = appSettings;
+// setPackage(appSettings.getPackageName());
+// mPackageName.setText(appSettings.getPackageName());
+
+// try {
+// MessageDigest md = MessageDigest.getInstance("SHA-256");
+// md.update(appSettings.getPackageSignature());
+// byte[] digest = md.digest();
+// String signature = new String(Hex.encode(digest));
+//
+// mPackageSignature.setText(signature);
+// } catch (NoSuchAlgorithmException e) {
+// Log.e(Constants.TAG, "Should not happen!", e);
+// }
mSelectKeyFragment.selectKey(appSettings.getKeyId());
mEncryptionAlgorithm.setSelection(mEncryptionAdapter.getPosition(appSettings
@@ -98,7 +98,7 @@ public class AppSettingsFragment extends Fragment implements
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.api_app_settings_fragment, container, false);
+ View view = inflater.inflate(R.layout.api_account_settings_fragment, container, false);
initView(view);
return view;
}
@@ -114,22 +114,17 @@ public class AppSettingsFragment extends Fragment implements
private void initView(View view) {
mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getFragmentManager().findFragmentById(
- R.id.api_app_settings_select_key_fragment);
+ R.id.api_account_settings_select_key_fragment);
mSelectKeyFragment.setCallback(this);
- mAdvancedSettingsButton = (BootstrapButton) view
- .findViewById(R.id.api_app_settings_advanced_button);
- mAdvancedSettingsContainer = (LinearLayout) view
- .findViewById(R.id.api_app_settings_advanced);
-
- mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name);
- mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon);
+ mAppNameView = (TextView) view.findViewById(R.id.api_account_settings_app_name);
+ mAppIconView = (ImageView) view.findViewById(R.id.api_account_settings_app_icon);
mEncryptionAlgorithm = (Spinner) view
- .findViewById(R.id.api_app_settings_encryption_algorithm);
- mHashAlgorithm = (Spinner) view.findViewById(R.id.api_app_settings_hash_algorithm);
- mCompression = (Spinner) view.findViewById(R.id.api_app_settings_compression);
- mPackageName = (TextView) view.findViewById(R.id.api_app_settings_package_name);
- mPackageSignature = (TextView) view.findViewById(R.id.api_app_settings_package_signature);
+ .findViewById(R.id.api_account_settings_encryption_algorithm);
+ mHashAlgorithm = (Spinner) view.findViewById(R.id.api_account_settings_hash_algorithm);
+ mCompression = (Spinner) view.findViewById(R.id.api_account_settings_compression);
+ mPackageName = (TextView) view.findViewById(R.id.api_account_settings_package_name);
+ mPackageSignature = (TextView) view.findViewById(R.id.api_account_settings_package_signature);
AlgorithmNames algorithmNames = new AlgorithmNames(getActivity());
@@ -140,7 +135,7 @@ public class AppSettingsFragment extends Fragment implements
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- mAppSettings.setEncryptionAlgorithm((int) id);
+ mAccSettings.setEncryptionAlgorithm((int) id);
}
@Override
@@ -154,7 +149,7 @@ public class AppSettingsFragment extends Fragment implements
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- mAppSettings.setHashAlgorithm((int) id);
+ mAccSettings.setHashAlgorithm((int) id);
}
@Override
@@ -169,69 +164,40 @@ public class AppSettingsFragment extends Fragment implements
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- mAppSettings.setCompression((int) id);
+ mAccSettings.setCompression((int) id);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
-
- final Animation visibleAnimation = new AlphaAnimation(0.0f, 1.0f);
- visibleAnimation.setDuration(250);
- final Animation invisibleAnimation = new AlphaAnimation(1.0f, 0.0f);
- invisibleAnimation.setDuration(250);
-
- // TODO: Better: collapse/expand animation
- // final Animation animation2 = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
- // Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, -1.0f,
- // Animation.RELATIVE_TO_SELF, 0.0f);u
- // animation2.setDuration(150);
-
- mAdvancedSettingsButton.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- if (mAdvancedSettingsContainer.getVisibility() == View.VISIBLE) {
- mAdvancedSettingsContainer.startAnimation(invisibleAnimation);
- mAdvancedSettingsContainer.setVisibility(View.GONE);
- mAdvancedSettingsButton.setText(getString(R.string.api_settings_show_advanced));
- mAdvancedSettingsButton.setLeftIcon("fa-caret-up");
- } else {
- mAdvancedSettingsContainer.startAnimation(visibleAnimation);
- mAdvancedSettingsContainer.setVisibility(View.VISIBLE);
- mAdvancedSettingsButton.setText(getString(R.string.api_settings_hide_advanced));
- mAdvancedSettingsButton.setLeftIcon("fa-caret-down");
- }
- }
- });
- }
-
- private void setPackage(String packageName) {
- PackageManager pm = getActivity().getApplicationContext().getPackageManager();
-
- // get application name and icon from package manager
- String appName = null;
- Drawable appIcon = null;
- try {
- ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
-
- appName = (String) pm.getApplicationLabel(ai);
- appIcon = pm.getApplicationIcon(ai);
- } catch (final NameNotFoundException e) {
- // fallback
- appName = packageName;
- }
- mAppNameView.setText(appName);
- mAppIconView.setImageDrawable(appIcon);
}
+//
+// private void setPackage(String packageName) {
+// PackageManager pm = getActivity().getApplicationContext().getPackageManager();
+//
+// // get application name and icon from package manager
+// String appName = null;
+// Drawable appIcon = null;
+// try {
+// ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
+//
+// appName = (String) pm.getApplicationLabel(ai);
+// appIcon = pm.getApplicationIcon(ai);
+// } catch (final NameNotFoundException e) {
+// // fallback
+// appName = packageName;
+// }
+// mAppNameView.setText(appName);
+// mAppIconView.setImageDrawable(appIcon);
+// }
/**
* callback from select secret key fragment
*/
@Override
public void onKeySelected(long secretKeyId) {
- mAppSettings.setKeyId(secretKeyId);
+ mAccSettings.setKeyId(secretKeyId);
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java
new file mode 100644
index 000000000..853dc2d3c
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.remote.ui;
+
+import android.annotation.TargetApi;
+import android.content.ContentUris;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.SimpleCursorAdapter;
+
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
+
+// TODO: make compat with < 11
+@TargetApi(Build.VERSION_CODES.HONEYCOMB)
+public class AccountsListFragment extends ListFragment implements
+ LoaderManager.LoaderCallbacks<Cursor> {
+
+ private static final String ARG_DATA_URI = "uri";
+
+ // This is the Adapter being used to display the list's data.
+ SimpleCursorAdapter mAdapter;
+
+ private Uri mDataUri;
+
+ /**
+ * Creates new instance of this fragment
+ */
+ public static AccountsListFragment newInstance(Uri dataUri) {
+ AccountsListFragment frag = new AccountsListFragment();
+
+ Bundle args = new Bundle();
+ args.putParcelable(ARG_DATA_URI, dataUri);
+
+ frag.setArguments(args);
+
+ return frag;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ mDataUri = getArguments().getParcelable(ARG_DATA_URI);
+
+ getListView().setOnItemClickListener(new OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
+// // edit app settings
+// Intent intent = new Intent(getActivity(), AppSettingsActivity.class);
+// intent.setData(ContentUris.withAppendedId(ApiApps.CONTENT_URI, id));
+// startActivity(intent);
+ }
+ });
+
+ // Give some text to display if there is no data. In a real
+ // application this would come from a resource.
+ setEmptyText(getString(R.string.api_settings_accounts_empty));
+
+ // We have a menu item to show in action bar.
+ setHasOptionsMenu(true);
+
+ // Create an empty adapter we will use to display the loaded data.
+ mAdapter = new SimpleCursorAdapter(getActivity(),
+ android.R.layout.simple_list_item_1,
+ null,
+ new String[]{KeychainContract.ApiAccounts.ACCOUNT_NAME},
+ new int[]{android.R.id.text1},
+ 0);
+ setListAdapter(mAdapter);
+
+ // Prepare the loader. Either re-connect with an existing one,
+ // or start a new one.
+ getLoaderManager().initLoader(0, null, this);
+ }
+
+ // These are the Contacts rows that we will retrieve.
+ static final String[] PROJECTION = new String[]{
+ KeychainContract.ApiAccounts._ID,
+ KeychainContract.ApiAccounts.ACCOUNT_NAME};
+
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ // This is called when a new Loader needs to be created. This
+ // sample only has one Loader, so we don't care about the ID.
+ // First, pick the base URI to use depending on whether we are
+ // currently filtering.
+// Uri baseUri = KeychainContract.ApiAccounts.buildBaseUri(mPackageName);
+
+ // Now create and return a CursorLoader that will take care of
+ // creating a Cursor for the data being displayed.
+ return new CursorLoader(getActivity(), mDataUri, PROJECTION, null, null,
+ KeychainContract.ApiAccounts.ACCOUNT_NAME + " COLLATE LOCALIZED ASC");
+ }
+
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ mAdapter.swapCursor(data);
+ }
+
+ public void onLoaderReset(Loader<Cursor> loader) {
+ // This is called when the last Cursor provided to onLoadFinished()
+ // above is about to be closed. We need to make sure we are no
+ // longer using it.
+ mAdapter.swapCursor(null);
+ }
+
+// private class RegisteredAppsAdapter extends CursorAdapter {
+//
+// private LayoutInflater mInflater;
+// private PackageManager mPM;
+//
+// public RegisteredAppsAdapter(Context context, Cursor c, int flags) {
+// super(context, c, flags);
+//
+// mInflater = LayoutInflater.from(context);
+// mPM = context.getApplicationContext().getPackageManager();
+// }
+//
+// @Override
+// public void bindView(View view, Context context, Cursor cursor) {
+// TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name);
+// ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon);
+//
+// String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME));
+// if (packageName != null) {
+// // get application name
+// try {
+// ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0);
+//
+// text.setText(mPM.getApplicationLabel(ai));
+// icon.setImageDrawable(mPM.getApplicationIcon(ai));
+// } catch (final PackageManager.NameNotFoundException e) {
+// // fallback
+// text.setText(packageName);
+// }
+// } else {
+// // fallback
+// text.setText(packageName);
+// }
+//
+// }
+//
+// @Override
+// public View newView(Context context, Cursor cursor, ViewGroup parent) {
+// return mInflater.inflate(R.layout.api_apps_adapter_list_item, null);
+// }
+// }
+
+}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java
index 2ef170dec..33cde49ba 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java
@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package org.sufficientlysecure.keychain.service.remote;
+package org.sufficientlysecure.keychain.remote.ui;
import android.content.Intent;
import android.net.Uri;
@@ -24,16 +24,20 @@ import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.remote.AppSettings;
import org.sufficientlysecure.keychain.util.Log;
public class AppSettingsActivity extends ActionBarActivity {
private Uri mAppUri;
private AppSettingsFragment mSettingsFragment;
+ private AccountsListFragment mAccountsListFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -63,7 +67,7 @@ public class AppSettingsActivity extends ActionBarActivity {
return;
} else {
Log.d(Constants.TAG, "uri: " + mAppUri);
- loadData(mAppUri);
+ loadData(savedInstanceState, mAppUri);
}
}
@@ -87,9 +91,34 @@ public class AppSettingsActivity extends ActionBarActivity {
return super.onOptionsItemSelected(item);
}
- private void loadData(Uri appUri) {
+ private void loadData(Bundle savedInstanceState, Uri appUri) {
+ // TODO: load this also like other fragment with newInstance arguments?
AppSettings settings = ProviderHelper.getApiAppSettings(this, appUri);
mSettingsFragment.setAppSettings(settings);
+
+ Uri accountsUri = appUri.buildUpon().appendPath(KeychainContract.PATH_ACCOUNTS).build();
+ Log.d(Constants.TAG, "accountsUri: " + accountsUri);
+ startListFragment(savedInstanceState, accountsUri);
+ }
+
+ private void startListFragment(Bundle savedInstanceState, Uri dataUri) {
+ // However, if we're being restored from a previous state,
+ // then we don't need to do anything and should return or else
+ // we could end up with overlapping fragments.
+ if (savedInstanceState != null) {
+ return;
+ }
+
+ // Create an instance of the fragment
+ mAccountsListFragment = AccountsListFragment.newInstance(dataUri);
+
+ // Add the fragment to the 'fragment_container' FrameLayout
+ // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.api_accounts_list_fragment, mAccountsListFragment)
+ .commitAllowingStateLoss();
+ // do it immediately!
+ getSupportFragmentManager().executePendingTransactions();
}
private void revokeAccess() {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java
new file mode 100644
index 000000000..8bcd83fc7
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.remote.ui;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ImageView;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import org.spongycastle.util.encoders.Hex;
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.remote.AppSettings;
+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 java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class AppSettingsFragment extends Fragment {
+
+ // model
+ private AppSettings mAppSettings;
+
+ // view
+ private TextView mAppNameView;
+ private ImageView mAppIconView;
+ private TextView mPackageName;
+ private TextView mPackageSignature;
+
+ public AppSettings getAppSettings() {
+ return mAppSettings;
+ }
+
+ public void setAppSettings(AppSettings appSettings) {
+ this.mAppSettings = appSettings;
+ setPackage(appSettings.getPackageName());
+ mPackageName.setText(appSettings.getPackageName());
+
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
+ md.update(appSettings.getPackageSignature());
+ byte[] digest = md.digest();
+ String signature = new String(Hex.encode(digest));
+
+ mPackageSignature.setText(signature);
+ } catch (NoSuchAlgorithmException e) {
+ Log.e(Constants.TAG, "Should not happen!", e);
+ }
+
+ }
+
+ /**
+ * Inflate the layout for this fragment
+ */
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.api_app_settings_fragment, container, false);
+ initView(view);
+ return view;
+ }
+
+
+ private void initView(View view) {
+ mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name);
+ mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon);
+
+ mPackageName = (TextView) view.findViewById(R.id.api_app_settings_package_name);
+ mPackageSignature = (TextView) view.findViewById(R.id.api_app_settings_package_signature);
+ }
+
+ private void setPackage(String packageName) {
+ PackageManager pm = getActivity().getApplicationContext().getPackageManager();
+
+ // get application name and icon from package manager
+ String appName = null;
+ Drawable appIcon = null;
+ try {
+ ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
+
+ appName = (String) pm.getApplicationLabel(ai);
+ appIcon = pm.getApplicationIcon(ai);
+ } catch (final NameNotFoundException e) {
+ // fallback
+ appName = packageName;
+ }
+ mAppNameView.setText(appName);
+ mAppIconView.setImageDrawable(appIcon);
+ }
+
+
+}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java
index f6f216efd..f86d279f0 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java
@@ -15,13 +15,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package org.sufficientlysecure.keychain.service.remote;
+package org.sufficientlysecure.keychain.remote.ui;
import android.os.Bundle;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.DrawerActivity;
-public class RegisteredAppsListActivity extends DrawerActivity {
+public class AppsListActivity extends DrawerActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java
index 25d0c7593..f3fa6e7c6 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java
@@ -15,10 +15,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package org.sufficientlysecure.keychain.service.remote;
+package org.sufficientlysecure.keychain.remote.ui;
-import android.content.ContentUris;
+import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
@@ -26,14 +28,22 @@ import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
+import android.support.v4.widget.CursorAdapter;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
+import org.sufficientlysecure.keychain.util.Log;
-public class RegisteredAppsListFragment extends ListFragment implements
+public class AppsListFragment extends ListFragment implements
LoaderManager.LoaderCallbacks<Cursor> {
// This is the Adapter being used to display the list's data.
@@ -46,9 +56,10 @@ public class RegisteredAppsListFragment extends ListFragment implements
getListView().setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
+ String selectedPackageName = mAdapter.getItemPackageName(position);
// edit app settings
Intent intent = new Intent(getActivity(), AppSettingsActivity.class);
- intent.setData(ContentUris.withAppendedId(KeychainContract.ApiApps.CONTENT_URI, id));
+ intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(selectedPackageName));
startActivity(intent);
}
});
@@ -70,7 +81,10 @@ public class RegisteredAppsListFragment extends ListFragment implements
}
// These are the Contacts rows that we will retrieve.
- static final String[] PROJECTION = new String[]{ApiApps._ID, ApiApps.PACKAGE_NAME};
+ static final String[] PROJECTION = new String[]{
+ ApiApps._ID, // 0
+ ApiApps.PACKAGE_NAME // 1
+ };
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// This is called when a new Loader needs to be created. This
@@ -98,4 +112,65 @@ public class RegisteredAppsListFragment extends ListFragment implements
mAdapter.swapCursor(null);
}
+ private class RegisteredAppsAdapter extends CursorAdapter {
+
+ private LayoutInflater mInflater;
+ private PackageManager mPM;
+
+ public RegisteredAppsAdapter(Context context, Cursor c, int flags) {
+ super(context, c, flags);
+
+ mInflater = LayoutInflater.from(context);
+ mPM = context.getApplicationContext().getPackageManager();
+ }
+
+ /**
+ * Similar to CursorAdapter.getItemId().
+ * Required to build Uris for api app view, which is not based on row ids
+ *
+ * @param position
+ * @return
+ */
+ public String getItemPackageName(int position) {
+ if (mDataValid && mCursor != null) {
+ if (mCursor.moveToPosition(position)) {
+ return mCursor.getString(1);
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void bindView(View view, Context context, Cursor cursor) {
+ TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name);
+ ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon);
+
+ String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME));
+ if (packageName != null) {
+ // get application name
+ try {
+ ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0);
+
+ text.setText(mPM.getApplicationLabel(ai));
+ icon.setImageDrawable(mPM.getApplicationIcon(ai));
+ } catch (final PackageManager.NameNotFoundException e) {
+ // fallback
+ text.setText(packageName);
+ }
+ } else {
+ // fallback
+ text.setText(packageName);
+ }
+
+ }
+
+ @Override
+ public View newView(Context context, Cursor cursor, ViewGroup parent) {
+ return mInflater.inflate(R.layout.api_apps_adapter_list_item, null);
+ }
+ }
+
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
index e20114853..d3ac5cade 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package org.sufficientlysecure.keychain.service.remote;
+package org.sufficientlysecure.keychain.remote.ui;
import android.content.Intent;
import android.os.Bundle;
@@ -24,6 +24,7 @@ import android.os.Message;
import android.os.Messenger;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
+
import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.htmltextview.HtmlTextView;
import org.sufficientlysecure.keychain.Constants;
@@ -31,7 +32,10 @@ import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.remote.AccountSettings;
+import org.sufficientlysecure.keychain.remote.AppSettings;
import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
@@ -41,6 +45,8 @@ import java.util.ArrayList;
public class RemoteServiceActivity extends ActionBarActivity {
public static final String ACTION_REGISTER = Constants.INTENT_PREFIX + "API_ACTIVITY_REGISTER";
+ public static final String ACTION_CREATE_ACCOUNT = Constants.INTENT_PREFIX
+ + "API_ACTIVITY_CREATE_ACCOUNT";
public static final String ACTION_CACHE_PASSPHRASE = Constants.INTENT_PREFIX
+ "API_ACTIVITY_CACHE_PASSPHRASE";
public static final String ACTION_SELECT_PUB_KEYS = Constants.INTENT_PREFIX
@@ -57,6 +63,8 @@ public class RemoteServiceActivity extends ActionBarActivity {
// register action
public static final String EXTRA_PACKAGE_NAME = "package_name";
public static final String EXTRA_PACKAGE_SIGNATURE = "package_signature";
+ // create acc action
+ public static final String EXTRA_ACC_NAME = "acc_name";
// select pub keys action
public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "master_key_ids";
public static final String EXTRA_MISSING_USER_IDS = "missing_user_ids";
@@ -65,7 +73,9 @@ public class RemoteServiceActivity extends ActionBarActivity {
public static final String EXTRA_ERROR_MESSAGE = "error_message";
// register view
- private AppSettingsFragment mSettingsFragment;
+ private AppSettingsFragment mAppSettingsFragment;
+ // create acc view
+ private AccountSettingsFragment mAccSettingsFragment;
// select pub keys view
private SelectPublicKeyFragment mSelectFragment;
@@ -94,13 +104,52 @@ public class RemoteServiceActivity extends ActionBarActivity {
public void onClick(View v) {
// Allow
+ ProviderHelper.insertApiApp(RemoteServiceActivity.this,
+ mAppSettingsFragment.getAppSettings());
+
+ // give data through for new service call
+ Intent resultData = extras.getParcelable(EXTRA_DATA);
+ RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
+ RemoteServiceActivity.this.finish();
+ }
+ }, R.string.api_register_disallow, R.drawable.ic_action_cancel,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Disallow
+ RemoteServiceActivity.this.setResult(RESULT_CANCELED);
+ RemoteServiceActivity.this.finish();
+ }
+ }
+ );
+
+ setContentView(R.layout.api_app_register_activity);
+
+ mAppSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById(
+ R.id.api_app_settings_fragment);
+
+ AppSettings settings = new AppSettings(packageName, packageSignature);
+ mAppSettingsFragment.setAppSettings(settings);
+ } else if (ACTION_CREATE_ACCOUNT.equals(action)) {
+ final String packageName = extras.getString(EXTRA_PACKAGE_NAME);
+ final String accName = extras.getString(EXTRA_ACC_NAME);
+
+ // Inflate a "Done"/"Cancel" custom action bar view
+ ActionBarHelper.setTwoButtonView(getSupportActionBar(),
+ R.string.api_settings_save, R.drawable.ic_action_done,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Save
+
// user needs to select a key!
- if (mSettingsFragment.getAppSettings().getKeyId() == Id.key.none) {
- mSettingsFragment.setErrorOnSelectKeyFragment(
+ if (mAccSettingsFragment.getAccSettings().getKeyId() == Id.key.none) {
+ mAccSettingsFragment.setErrorOnSelectKeyFragment(
getString(R.string.api_register_error_select_key));
} else {
- ProviderHelper.insertApiApp(RemoteServiceActivity.this,
- mSettingsFragment.getAppSettings());
+ ProviderHelper.insertApiAccount(RemoteServiceActivity.this,
+ KeychainContract.ApiAccounts.buildBaseUri(packageName),
+ mAccSettingsFragment.getAccSettings());
// give data through for new service call
Intent resultData = extras.getParcelable(EXTRA_DATA);
@@ -108,24 +157,24 @@ public class RemoteServiceActivity extends ActionBarActivity {
RemoteServiceActivity.this.finish();
}
}
- }, R.string.api_register_disallow, R.drawable.ic_action_cancel,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Disallow
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
- }
+ }, R.string.api_settings_cancel, R.drawable.ic_action_cancel,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Cancel
+ RemoteServiceActivity.this.setResult(RESULT_CANCELED);
+ RemoteServiceActivity.this.finish();
+ }
}
);
- setContentView(R.layout.api_app_register_activity);
+ setContentView(R.layout.api_account_create_activity);
- mSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_app_settings_fragment);
+ mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById(
+ R.id.api_account_settings_fragment);
- AppSettings settings = new AppSettings(packageName, packageSignature);
- mSettingsFragment.setAppSettings(settings);
+ AccountSettings settings = new AccountSettings(accName);
+ mAccSettingsFragment.setAccSettings(settings);
} else if (ACTION_CACHE_PASSPHRASE.equals(action)) {
long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID);
Intent resultData = extras.getParcelable(EXTRA_DATA);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
index 6ec6dcf8a..bd3a0421b 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -25,6 +25,7 @@ import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
+
import org.spongycastle.openpgp.*;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
@@ -542,7 +543,15 @@ public class KeychainIntentService extends IntentService
ProviderHelper.getPGPSecretKeyRingByKeyId(this, masterKeyId),
oldPassPhrase, newPassPhrase);
} else {
- PGPPublicKey pubkey = ProviderHelper.getPGPPublicKeyByKeyId(this, masterKeyId);
+ //TODO: Workaround due to ProviderHelper.getPGPPublicKeyByKeyId can not resolve public key of master-key id with uri/cursor
+ PGPPublicKey pubkey = null;
+ for(PGPSecretKey key : keys) {
+ PGPPublicKey tempKey = key.getPublicKey();
+ if (tempKey.getKeyID() == masterKeyId) {
+ pubkey = tempKey;
+ }
+ }
+ //PGPPublicKey pubkey = ProviderHelper.getPGPPublicKeyByKeyId(this, masterKeyId);
keyOperations.buildSecretKey(userIds, keys, keysUsages, keysExpiryDates,
pubkey, oldPassPhrase, newPassPhrase);
}
@@ -692,11 +701,11 @@ public class KeychainIntentService extends IntentService
for (long masterKeyId : masterKeyIds) {
if ((keyType == Id.type.public_key || keyType == Id.type.public_secret_key)
- && allPublicMasterKeyIds.contains(masterKeyId)) {
+ && allPublicMasterKeyIds.contains(masterKeyId)) {
publicMasterKeyIds.add(masterKeyId);
}
if ((keyType == Id.type.secret_key || keyType == Id.type.public_secret_key)
- && allSecretMasterKeyIds.contains(masterKeyId)) {
+ && allSecretMasterKeyIds.contains(masterKeyId)) {
secretMasterKeyIds.add(masterKeyId);
}
}
@@ -745,49 +754,58 @@ public class KeychainIntentService extends IntentService
ArrayList<ImportKeysListEntry> entries = data.getParcelableArrayList(DOWNLOAD_KEY_LIST);
String keyServer = data.getString(DOWNLOAD_KEY_SERVER);
+ // TODO: add extra which requires fingerprint suport and force verification!
+ // only supported by newer sks keyserver versions
+
// this downloads the keys and places them into the ImportKeysListEntry entries
HkpKeyServer server = new HkpKeyServer(keyServer);
for (ImportKeysListEntry entry : entries) {
- byte[] downloadedKey = server.get(entry.getKeyId()).getBytes();
-
- /**
- * TODO: copied from ImportKeysListLoader
- *
- *
- * this parses the downloaded key
- */
- // need to have access to the bufferedInput, so we can reuse it for the possible
- // PGPObject chunks after the first one, e.g. files with several consecutive ASCII
- // armor blocks
- BufferedInputStream bufferedInput =
- new BufferedInputStream(new ByteArrayInputStream(downloadedKey));
- try {
-
- // read all available blocks... (asc files can contain many blocks with BEGIN END)
- while (bufferedInput.available() > 0) {
- InputStream in = PGPUtil.getDecoderStream(bufferedInput);
- PGPObjectFactory objectFactory = new PGPObjectFactory(in);
-
- // go through all objects in this block
- Object obj;
- while ((obj = objectFactory.nextObject()) != null) {
- Log.d(Constants.TAG, "Found class: " + obj.getClass());
-
- if (obj instanceof PGPKeyRing) {
- PGPKeyRing newKeyring = (PGPKeyRing) obj;
+ // if available use complete fingerprint for get request
+ byte[] downloadedKeyBytes;
+ if (entry.getFingerPrintHex() != null) {
+ downloadedKeyBytes = server.get("0x" + entry.getFingerPrintHex()).getBytes();
+ } else {
+ downloadedKeyBytes = server.get(entry.getKeyIdHex()).getBytes();
+ }
- entry.setBytes(newKeyring.getEncoded());
- } else {
- Log.e(Constants.TAG, "Object not recognized as PGPKeyRing!");
- }
+ // create PGPKeyRing object based on downloaded armored key
+ PGPKeyRing downloadedKey = null;
+ BufferedInputStream bufferedInput =
+ new BufferedInputStream(new ByteArrayInputStream(downloadedKeyBytes));
+ if (bufferedInput.available() > 0) {
+ InputStream in = PGPUtil.getDecoderStream(bufferedInput);
+ PGPObjectFactory objectFactory = new PGPObjectFactory(in);
+
+ // get first object in block
+ Object obj;
+ if ((obj = objectFactory.nextObject()) != null) {
+ Log.d(Constants.TAG, "Found class: " + obj.getClass());
+
+ if (obj instanceof PGPKeyRing) {
+ downloadedKey = (PGPKeyRing) obj;
+ } else {
+ throw new PgpGeneralException("Object not recognized as PGPKeyRing!");
}
}
- } catch (Exception e) {
- Log.e(Constants.TAG, "Exception on parsing key file!", e);
}
+
+ // verify downloaded key by comparing fingerprints
+ if (entry.getFingerPrintHex() != null) {
+ String downloadedKeyFp = PgpKeyHelper.convertFingerprintToHex(downloadedKey.getPublicKey().getFingerprint());
+ if (downloadedKeyFp.equals(entry.getFingerPrintHex())) {
+ Log.d(Constants.TAG, "fingerprint of downloaded key is the same as the requested fingerprint!");
+ } else {
+ throw new PgpGeneralException("fingerprint of downloaded key is NOT the same as the requested fingerprint!");
+ }
+ }
+
+ // save key bytes in entry object for doing the
+ // actual import afterwards
+ entry.setBytes(downloadedKey.getEncoded());
}
+
Intent importIntent = new Intent(this, KeychainIntentService.class);
importIntent.setAction(ACTION_IMPORT_KEYRING);
Bundle importData = new Bundle();
@@ -837,7 +855,7 @@ public class KeychainIntentService extends IntentService
if (this.mIsCanceled) {
return;
}
- Log.e(Constants.TAG, "ApgService Exception: ", e);
+ Log.e(Constants.TAG, "KeychainIntentService Exception: ", e);
e.printStackTrace();
Bundle data = new Bundle();
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsAdapter.java
deleted file mode 100644
index e0dc4162f..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsAdapter.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.service.remote;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.database.Cursor;
-import android.support.v4.widget.CursorAdapter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
-
-public class RegisteredAppsAdapter extends CursorAdapter {
-
- private LayoutInflater mInflater;
- private PackageManager mPM;
-
- public RegisteredAppsAdapter(Context context, Cursor c, int flags) {
- super(context, c, flags);
-
- mInflater = LayoutInflater.from(context);
- mPM = context.getApplicationContext().getPackageManager();
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name);
- ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon);
-
- String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME));
- if (packageName != null) {
- // get application name
- try {
- ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0);
-
- text.setText(mPM.getApplicationLabel(ai));
- icon.setImageDrawable(mPM.getApplicationIcon(ai));
- } catch (final NameNotFoundException e) {
- // fallback
- text.setText(packageName);
- }
- } else {
- // fallback
- text.setText(packageName);
- }
-
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.api_apps_adapter_list_item, null);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
index bd14369b0..5dc06c16d 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
@@ -198,6 +198,8 @@ public class CertifyKeyActivity extends ActionBarActivity implements
case LOADER_ID_KEYRING:
// the first key here is our master key
if (data.moveToFirst()) {
+ // TODO: put findViewById in onCreate!
+
long keyId = data.getLong(INDEX_MASTER_KEY_ID);
String keyIdStr = PgpKeyHelper.convertKeyIdToHexShort(keyId);
((TextView) findViewById(R.id.key_id)).setText(keyIdStr);
@@ -210,8 +212,8 @@ public class CertifyKeyActivity extends ActionBarActivity implements
// FALLBACK for old database entries
fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri);
}
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
- ((TextView) findViewById(R.id.fingerprint)).setText(OtherHelper.colorizeFingerprint(fingerprint));
+ String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
+ ((TextView) findViewById(R.id.fingerprint)).setText(PgpKeyHelper.colorizeFingerprint(fingerprint));
}
break;
case LOADER_ID_USER_IDS:
@@ -325,11 +327,11 @@ public class CertifyKeyActivity extends ActionBarActivity implements
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
- // Message is received after signing is done in ApgService
+ // Message is received after signing is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
getString(R.string.progress_signing), ProgressDialog.STYLE_SPINNER) {
public void handleMessage(Message message) {
- // handle messages by standard ApgHandler first
+ // handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
@@ -378,11 +380,11 @@ public class CertifyKeyActivity extends ActionBarActivity implements
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
- // Message is received after uploading is done in ApgService
+ // Message is received after uploading is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
- // handle messages by standard ApgHandler first
+ // handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
index 3e389c034..9b3b00c19 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
@@ -443,8 +443,7 @@ public class DecryptActivity extends DrawerActivity {
getDecryptionKeyFromInputStream();
// if we need a symmetric passphrase or a passphrase to use a secret key ask for it
- if (mSecretKeyId == Id.key.symmetric
- || PassphraseCacheService.getCachedPassphrase(this, mSecretKeyId) == null) {
+ if (mAssumeSymmetricEncryption || PassphraseCacheService.getCachedPassphrase(this, mSecretKeyId) == null) {
showPassphraseDialog();
} else {
if (mDecryptTarget == Id.target.file) {
@@ -494,6 +493,7 @@ public class DecryptActivity extends DrawerActivity {
* TODO: Rework function, remove global variables
*/
private void getDecryptionKeyFromInputStream() {
+ mAssumeSymmetricEncryption = false;
InputStream inStream = null;
if (mContentUri != null) {
try {
@@ -517,13 +517,6 @@ public class DecryptActivity extends DrawerActivity {
Log.e(Constants.TAG, "File not found!", e);
AppMsg.makeText(this, getString(R.string.error_file_not_found, e.getMessage()),
AppMsg.STYLE_ALERT).show();
- } finally {
- try {
- if (inStream != null) {
- inStream.close();
- }
- } catch (Exception e) {
- }
}
} else {
inStream = new ByteArrayInputStream(mMessage.getText().toString().getBytes());
@@ -540,7 +533,6 @@ public class DecryptActivity extends DrawerActivity {
if (mSecretKeyId == Id.key.none) {
throw new PgpGeneralException(getString(R.string.error_no_secret_key_found));
}
- mAssumeSymmetricEncryption = false;
} catch (NoAsymmetricEncryptionException e) {
if (inStream.markSupported()) {
inStream.reset();
@@ -553,6 +545,7 @@ public class DecryptActivity extends DrawerActivity {
mAssumeSymmetricEncryption = true;
}
} catch (Exception e) {
+ Log.e(Constants.TAG, "error while reading decryption key from input stream", e);
AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()),
AppMsg.STYLE_ALERT).show();
}
@@ -638,11 +631,11 @@ public class DecryptActivity extends DrawerActivity {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
- // Message is received after encrypting is done in ApgService
+ // Message is received after encrypting is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
- // handle messages by standard ApgHandler first
+ // handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
index 31804719f..6eb5b9d2d 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
@@ -46,6 +46,7 @@ import org.sufficientlysecure.keychain.helper.ExportHelper;
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
@@ -58,7 +59,6 @@ import org.sufficientlysecure.keychain.ui.widget.SectionView;
import org.sufficientlysecure.keychain.ui.widget.UserIdEditor;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
-
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.Vector;
@@ -180,7 +180,7 @@ public class EditKeyActivity extends ActionBarActivity {
serviceIntent.putExtra(KeychainIntentService.EXTRA_DATA, data);
- // Message is received after generating is done in ApgService
+ // Message is received after generating is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
this, getResources().getQuantityString(R.plurals.progress_generating, 1),
ProgressDialog.STYLE_HORIZONTAL, true,
@@ -197,7 +197,7 @@ public class EditKeyActivity extends ActionBarActivity {
@Override
public void handleMessage(Message message) {
- // handle messages by standard ApgHandler first
+ // handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
@@ -325,9 +325,13 @@ public class EditKeyActivity extends ActionBarActivity {
long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri);
long[] ids = new long[]{masterKeyId};
mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC,
- null);
+ null);
return true;
case R.id.menu_key_edit_delete: {
+ //Convert the uri to one based on rowId
+ long rowId= ProviderHelper.getRowId(this,mDataUri);
+ Uri convertUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(Long.toString(rowId));
+
// Message is received after key is deleted
Handler returnHandler = new Handler() {
@Override
@@ -339,7 +343,7 @@ public class EditKeyActivity extends ActionBarActivity {
}
};
- mExportHelper.deleteKey(mDataUri, Id.type.secret_key, returnHandler);
+ mExportHelper.deleteKey(convertUri, returnHandler);
return true;
}
}
@@ -491,11 +495,10 @@ public class EditKeyActivity extends ActionBarActivity {
private void saveClicked() {
long masterKeyId = getMasterKeyId();
- try {
- if (!isPassphraseSet()) {
- throw new PgpGeneralException(this.getString(R.string.set_a_passphrase));
- }
-
+ if (!isPassphraseSet()) {
+ Log.e(Constants.TAG, "No passphrase has been set");
+ Toast.makeText(this, R.string.set_a_passphrase, Toast.LENGTH_LONG).show();
+ } else {
String passphrase = null;
if (mIsPassPhraseSet) {
passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId);
@@ -508,9 +511,6 @@ public class EditKeyActivity extends ActionBarActivity {
mCurrentPassphrase = passphrase;
finallySaveClicked();
}
- } catch (PgpGeneralException e) {
- //Toast.makeText(this, getString(R.string.error_message, e.getMessage()),
- // Toast.LENGTH_SHORT).show();
}
}
@@ -540,11 +540,11 @@ public class EditKeyActivity extends ActionBarActivity {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
- // Message is received after saving is done in ApgService
+ // Message is received after saving is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
getString(R.string.progress_saving), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
- // handle messages by standard ApgHandler first
+ // handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
@@ -572,8 +572,9 @@ public class EditKeyActivity extends ActionBarActivity {
// start service with intent
startService(intent);
} catch (PgpGeneralException e) {
- //Toast.makeText(this, getString(R.string.error_message, e.getMessage()),
- // Toast.LENGTH_SHORT).show();
+ Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage()));
+ Toast.makeText(this, getString(R.string.error_message, e.getMessage()),
+ Toast.LENGTH_SHORT).show();
}
}
@@ -697,4 +698,4 @@ public class EditKeyActivity extends ActionBarActivity {
: getString(R.string.btn_set_passphrase));
}
-}
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
index 1231b6209..4f18f69d7 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
@@ -108,11 +108,6 @@ public class EncryptActivity extends DrawerActivity {
private String mInputFilename = null;
private String mOutputFilename = null;
- private Integer mShortAnimationDuration = null;
- private boolean mFileAdvancedSettingsVisible = false;
- private TextView mFileAdvancedSettings = null;
- private LinearLayout mFileAdvancedSettingsContainer = null;
- private FontAwesomeText mAdvancedSettingsIcon;
private boolean mAsciiArmorDemand = false;
private boolean mOverrideAsciiArmor = false;
@@ -147,9 +142,6 @@ public class EncryptActivity extends DrawerActivity {
updateMode();
updateActionBarButtons();
-
- // retrieve and cache the system's short animation time
- mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
}
/**
@@ -605,11 +597,11 @@ public class EncryptActivity extends DrawerActivity {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
- // Message is received after encrypting is done in ApgService
+ // Message is received after encrypting is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
- // handle messages by standard ApgHandler first
+ // handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
@@ -795,49 +787,10 @@ public class EncryptActivity extends DrawerActivity {
}
});
- mAdvancedSettingsIcon = (FontAwesomeText) findViewById(R.id.advancedSettingsIcon);
- mFileAdvancedSettingsContainer = (LinearLayout) findViewById(R.id.fileAdvancedSettingsContainer);
- mFileAdvancedSettings = (TextView) findViewById(R.id.advancedSettings);
- LinearLayout advancedSettingsControl = (LinearLayout) findViewById(R.id.advancedSettingsControl);
- advancedSettingsControl.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- mFileAdvancedSettingsVisible = !mFileAdvancedSettingsVisible;
- if (mFileAdvancedSettingsVisible) {
- mAdvancedSettingsIcon.setIcon("fa-chevron-down");
- mFileAdvancedSettingsContainer.setVisibility(View.VISIBLE);
- AlphaAnimation animation = new AlphaAnimation(0f, 1f);
- animation.setDuration(mShortAnimationDuration);
- mFileAdvancedSettingsContainer.startAnimation(animation);
- mFileAdvancedSettings.setText(R.string.btn_encryption_advanced_settings_hide);
- } else {
- mAdvancedSettingsIcon.setIcon("fa-chevron-right");
- AlphaAnimation animation = new AlphaAnimation(1f, 0f);
- animation.setDuration(mShortAnimationDuration);
- animation.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
- // do nothing
- }
- @Override
- public void onAnimationEnd(Animation animation) {
- // making sure that at the end the container is completely removed from view
- mFileAdvancedSettingsContainer.setVisibility(View.GONE);
- }
- @Override
- public void onAnimationRepeat(Animation animation) {
- // do nothing
- }
- });
- mFileAdvancedSettingsContainer.startAnimation(animation);
- mFileAdvancedSettings.setText(R.string.btn_encryption_advanced_settings_show);
- }
- }
- });
mFileCompression = (Spinner) findViewById(R.id.fileCompression);
Choice[] choices = new Choice[]{
@@ -1002,8 +955,8 @@ public class EncryptActivity extends DrawerActivity {
case Id.request.secret_keys: {
if (resultCode == RESULT_OK) {
- Bundle bundle = data.getExtras();
- mSecretKeyId = bundle.getLong(SelectSecretKeyActivity.RESULT_EXTRA_MASTER_KEY_ID);
+ Uri uri_master_key = data.getData();
+ mSecretKeyId = Long.valueOf(uri_master_key.getLastPathSegment());
} else {
mSecretKeyId = Id.key.none;
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
index 05bfc613e..834509f53 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
@@ -363,7 +363,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
* Import keys with mImportData
*/
public void importKeys() {
- // Message is received after importing is done in ApgService
+ // Message is received after importing is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
this,
getString(R.string.progress_importing),
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java
index 44b5848d8..110647284 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java
@@ -57,7 +57,7 @@ public class ImportKeysNFCFragment extends Fragment {
public void onClick(View v) {
// show nfc help
Intent intent = new Intent(getActivity(), HelpActivity.class);
- intent.putExtra(HelpActivity.EXTRA_SELECTED_TAB, 1);
+ intent.putExtra(HelpActivity.EXTRA_SELECTED_TAB, 2);
startActivityForResult(intent, 0);
}
});
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
index cac8b7046..daf455c03 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
@@ -355,25 +355,7 @@ public class KeyListFragment extends Fragment
@Override
public void handleMessage(Message message) {
if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) {
- Bundle returnData = message.getData();
- if (returnData != null
- && returnData.containsKey(DeleteKeyDialogFragment.MESSAGE_NOT_DELETED)) {
- ArrayList<String> notDeleted =
- returnData.getStringArrayList(DeleteKeyDialogFragment.MESSAGE_NOT_DELETED);
- String notDeletedMsg = "";
- for (String userId : notDeleted) {
- notDeletedMsg += userId + "\n";
- }
- Toast.makeText(getActivity(),
- getString(R.string.error_can_not_delete_contacts, notDeletedMsg)
- + getResources()
- .getQuantityString(
- R.plurals.error_can_not_delete_info,
- notDeleted.size()),
- Toast.LENGTH_LONG).show();
-
- mode.finish();
- }
+ mode.finish();
}
}
};
@@ -382,7 +364,7 @@ public class KeyListFragment extends Fragment
Messenger messenger = new Messenger(returnHandler);
DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
- keyRingRowIds, Id.type.public_key);
+ keyRingRowIds);
deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog");
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java
index 82a3c2e8e..0ff88d97c 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java
@@ -76,10 +76,6 @@ public class SelectSecretKeyActivity extends ActionBarActivity {
Intent data = new Intent();
data.setData(selectedUri);
- // TODO: deprecate RESULT_EXTRA_MASTER_KEY_ID!
- long masterKeyId = Long.valueOf(selectedUri.getLastPathSegment());
- data.putExtra(RESULT_EXTRA_MASTER_KEY_ID, masterKeyId);
-
setResult(RESULT_OK, data);
finish();
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java
index 960b4aafb..cbc0f4c5c 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java
@@ -19,22 +19,26 @@ package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
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;
-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 org.sufficientlysecure.keychain.provider.KeychainContract;
-public class SelectSecretKeyLayoutFragment extends Fragment {
+public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
private TextView mKeyUserId;
private TextView mKeyUserIdRest;
@@ -43,10 +47,21 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
private BootstrapButton mSelectKeyButton;
private Boolean mFilterCertify;
+ private Uri mReceivedUri = null;
+
private SelectSecretKeyCallback mCallback;
private static final int REQUEST_CODE_SELECT_KEY = 8882;
+ private static final int LOADER_ID = 0;
+
+ //The Projection we will retrieve, Master Key ID is for convenience sake,
+ //to avoid having to pass the Key Around
+ final String[] PROJECTION = new String[]{KeychainContract.UserIds.USER_ID
+ , KeychainContract.KeyRings.MASTER_KEY_ID};
+ final int INDEX_USER_ID = 0;
+ final int INDEX_MASTER_KEY_ID = 1;
+
public interface SelectSecretKeyCallback {
void onKeySelected(long secretKeyId);
}
@@ -59,63 +74,25 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
mFilterCertify = filterCertify;
}
- public void selectKey(long secretKeyId) {
- if (secretKeyId == Id.key.none) {
- mNoKeySelected.setVisibility(View.VISIBLE);
- mKeyUserId.setVisibility(View.GONE);
- mKeyUserIdRest.setVisibility(View.GONE);
- mKeyMasterKeyIdHex.setVisibility(View.GONE);
+ public void setNoKeySelected() {
+ mNoKeySelected.setVisibility(View.VISIBLE);
+ mKeyUserId.setVisibility(View.GONE);
+ mKeyUserIdRest.setVisibility(View.GONE);
+ mKeyMasterKeyIdHex.setVisibility(View.GONE);
+ }
- } else {
- PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(
- getActivity(), secretKeyId);
- if (keyRing != null) {
- PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing);
- String masterkeyIdHex = PgpKeyHelper.convertKeyIdToHexShort(secretKeyId);
-
- if (key != null) {
- String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key);
-
- String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
- String userName, userEmail;
-
- if (userIdSplit[0] != null) {
- userName = userIdSplit[0];
- } else {
- userName = getActivity().getResources().getString(R.string.user_id_no_name);
- }
-
- if (userIdSplit[1] != null) {
- userEmail = userIdSplit[1];
- } else {
- userEmail = getActivity().getResources().getString(R.string.error_user_id_no_email);
- }
-
- mKeyMasterKeyIdHex.setText(masterkeyIdHex);
- mKeyUserId.setText(userName);
- mKeyUserIdRest.setText(userEmail);
- mKeyMasterKeyIdHex.setVisibility(View.VISIBLE);
- mKeyUserId.setVisibility(View.VISIBLE);
- mKeyUserIdRest.setVisibility(View.VISIBLE);
- mNoKeySelected.setVisibility(View.GONE);
- } else {
- mKeyMasterKeyIdHex.setVisibility(View.GONE);
- mKeyUserId.setVisibility(View.GONE);
- mKeyUserIdRest.setVisibility(View.GONE);
- mNoKeySelected.setVisibility(View.VISIBLE);
- }
- } else {
- mKeyMasterKeyIdHex.setText(
- getActivity().getResources()
- .getString(R.string.no_keys_added_or_updated)
- + " for master id: " + secretKeyId);
- mKeyMasterKeyIdHex.setVisibility(View.VISIBLE);
- mKeyUserId.setVisibility(View.GONE);
- mKeyUserIdRest.setVisibility(View.GONE);
- mNoKeySelected.setVisibility(View.GONE);
- }
+ public void setSelectedKeyData(String userName, String email, String masterKeyHex) {
+
+ mNoKeySelected.setVisibility(View.GONE);
+
+ mKeyUserId.setText(userName);
+ mKeyUserIdRest.setText(email);
+ mKeyMasterKeyIdHex.setText(masterKeyHex);
+
+ mKeyUserId.setVisibility(View.VISIBLE);
+ mKeyUserIdRest.setVisibility(View.VISIBLE);
+ mKeyMasterKeyIdHex.setVisibility(View.VISIBLE);
- }
}
public void setError(String error) {
@@ -147,29 +124,80 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
return view;
}
+ //For AppSettingsFragment
+ public void selectKey(long masterKeyId) {
+ Uri buildUri = KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(masterKeyId));
+ mReceivedUri = buildUri;
+ getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this);
+ }
+
private void startSelectKeyActivity() {
Intent intent = new Intent(getActivity(), SelectSecretKeyActivity.class);
intent.putExtra(SelectSecretKeyActivity.EXTRA_FILTER_CERTIFY, mFilterCertify);
startActivityForResult(intent, REQUEST_CODE_SELECT_KEY);
}
+ @Override
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ //We don't care about the Loader id
+ return new CursorLoader(getActivity(), mReceivedUri, PROJECTION, null, null, null);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ if (data.moveToFirst()) {
+ String userName, email, masterKeyHex;
+ String userID = data.getString(INDEX_USER_ID);
+ long masterKeyID = data.getLong(INDEX_MASTER_KEY_ID);
+
+ String splitUserID[] = PgpKeyHelper.splitUserId(userID);
+
+ if (splitUserID[0] != null) {
+ userName = splitUserID[0];
+ } else {
+ userName = getActivity().getResources().getString(R.string.user_id_no_name);
+ }
+
+ if (splitUserID[1] != null) {
+ email = splitUserID[1];
+ } else {
+ email = getActivity().getResources().getString(R.string.error_user_id_no_email);
+ }
+
+ //TODO Can the cursor return invalid values for the Master Key ?
+ masterKeyHex = PgpKeyHelper.convertKeyIdToHexShort(masterKeyID);
+
+ //Set the data
+ setSelectedKeyData(userName, email, masterKeyHex);
+
+ //Give value to the callback
+ mCallback.onKeySelected(masterKeyID);
+ } else {
+ //Set The empty View
+ setNoKeySelected();
+ }
+
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Cursor> loader) {
+ return;
+ }
+
// Select Secret Key Activity delivers the intent which was sent by it using interface to Select
- // Secret Key Fragment.Intent contains Master Key Id, User Email, User Name, Master Key Id Hex.
+ // Secret Key Fragment.Intent contains the passed Uri
@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);
+ mReceivedUri = data.getData();
+
+ //Must be restartLoader() or the data will not be updated on selecting a new key
+ getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this);
- // remove displayed errors
mKeyUserId.setError(null);
- // give value back to callback
- mCallback.onKeySelected(secretKeyId);
}
break;
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
index 2c8f66488..0e231e6a8 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
@@ -98,11 +98,11 @@ public class UploadKeyActivity extends ActionBarActivity {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
- // Message is received after uploading is done in ApgService
+ // Message is received after uploading is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
- // handle messages by standard ApgHandler first
+ // handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
index c4097403c..3e7e6d7ce 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
@@ -182,7 +182,7 @@ public class ViewKeyActivity extends ActionBarActivity {
String content;
if (fingerprintOnly) {
byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri);
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, false);
+ String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
} else {
@@ -237,25 +237,12 @@ public class ViewKeyActivity extends ActionBarActivity {
Handler returnHandler = new Handler() {
@Override
public void handleMessage(Message message) {
- if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) {
- Bundle returnData = message.getData();
- if (returnData != null
- && returnData.containsKey(DeleteKeyDialogFragment.MESSAGE_NOT_DELETED)) {
- // we delete only this key, so MESSAGE_NOT_DELETED will solely contain this key
- Toast.makeText(ViewKeyActivity.this,
- getString(R.string.error_can_not_delete_contact)
- + getResources()
- .getQuantityString(R.plurals.error_can_not_delete_info, 1),
- Toast.LENGTH_LONG).show();
- } else {
- setResult(RESULT_CANCELED);
- finish();
- }
- }
+ setResult(RESULT_CANCELED);
+ finish();
}
};
- mExportHelper.deleteKey(dataUri, Id.type.public_key, returnHandler);
+ mExportHelper.deleteKey(dataUri, returnHandler);
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
index e4f707f3c..8a4f2758a 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
@@ -320,9 +320,9 @@ public class ViewKeyMainFragment extends Fragment implements
// FALLBACK for old database entries
fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), mDataUri);
}
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
+ String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
- mFingerprint.setText(OtherHelper.colorizeFingerprint(fingerprint));
+ mFingerprint.setText(PgpKeyHelper.colorizeFingerprint(fingerprint));
}
int valid_keys = 0;
data.moveToFirst();
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
index 0f05af447..7d3166af9 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
@@ -30,7 +30,9 @@ import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
+
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.helper.OtherHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import java.util.ArrayList;
@@ -43,13 +45,12 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
protected List<ImportKeysListEntry> mData;
static class ViewHolder {
- private TextView mMainUserId;
- private TextView mMainUserIdRest;
- private TextView mKeyId;
- private TextView mFingerprint;
- private TextView mAlgorithm;
- private TextView mStatus;
-
+ private TextView mainUserId;
+ private TextView mainUserIdRest;
+ private TextView keyId;
+ private TextView fingerprint;
+ private TextView algorithm;
+ private TextView status;
}
public ImportKeysAdapter(Activity activity) {
@@ -100,12 +101,12 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.import_keys_list_entry, null);
- holder.mMainUserId = (TextView) convertView.findViewById(R.id.mainUserId);
- holder.mMainUserIdRest = (TextView) convertView.findViewById(R.id.mainUserIdRest);
- holder.mKeyId = (TextView) convertView.findViewById(R.id.keyId);
- holder.mFingerprint = (TextView) convertView.findViewById(R.id.fingerprint);
- holder.mAlgorithm = (TextView) convertView.findViewById(R.id.algorithm);
- holder.mStatus = (TextView) convertView.findViewById(R.id.status);
+ holder.mainUserId = (TextView) convertView.findViewById(R.id.mainUserId);
+ holder.mainUserIdRest = (TextView) convertView.findViewById(R.id.mainUserIdRest);
+ holder.keyId = (TextView) convertView.findViewById(R.id.keyId);
+ holder.fingerprint = (TextView) convertView.findViewById(R.id.fingerprint);
+ holder.algorithm = (TextView) convertView.findViewById(R.id.algorithm);
+ holder.status = (TextView) convertView.findViewById(R.id.status);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
@@ -119,36 +120,36 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
// show red user id if it is a secret key
if (entry.secretKey) {
userIdSplit[0] = mActivity.getString(R.string.secret_key) + " " + userIdSplit[0];
- holder.mMainUserId.setTextColor(Color.RED);
+ holder.mainUserId.setTextColor(Color.RED);
}
- holder.mMainUserId.setText(userIdSplit[0]);
+ holder.mainUserId.setText(userIdSplit[0]);
} else {
- holder.mMainUserId.setText(R.string.user_id_no_name);
+ holder.mainUserId.setText(R.string.user_id_no_name);
}
// email
if (userIdSplit[1] != null) {
- holder.mMainUserIdRest.setText(userIdSplit[1]);
- holder.mMainUserIdRest.setVisibility(View.VISIBLE);
+ holder.mainUserIdRest.setText(userIdSplit[1]);
+ holder.mainUserIdRest.setVisibility(View.VISIBLE);
} else {
- holder.mMainUserIdRest.setVisibility(View.GONE);
+ holder.mainUserIdRest.setVisibility(View.GONE);
}
- holder.mKeyId.setText(entry.hexKeyId);
+ holder.keyId.setText(entry.keyIdHex);
- if (entry.fingerPrint != null) {
- holder.mFingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint);
- holder.mFingerprint.setVisibility(View.VISIBLE);
+ if (entry.fingerPrintHex != null) {
+ holder.fingerprint.setText(PgpKeyHelper.colorizeFingerprint(entry.fingerPrintHex));
+ holder.fingerprint.setVisibility(View.VISIBLE);
} else {
- holder.mFingerprint.setVisibility(View.GONE);
+ holder.fingerprint.setVisibility(View.GONE);
}
- holder.mAlgorithm.setText("" + entry.bitStrength + "/" + entry.algorithm);
+ holder.algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm);
if (entry.revoked) {
- holder.mStatus.setText(R.string.revoked);
+ holder.status.setText(R.string.revoked);
} else {
- holder.mStatus.setVisibility(View.GONE);
+ holder.status.setVisibility(View.GONE);
}
LinearLayout ll = (LinearLayout) convertView.findViewById(R.id.list);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
index 05521b0c9..9b20effc2 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
@@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.ui.adapter;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
+
import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
@@ -35,13 +36,13 @@ import java.util.Date;
public class ImportKeysListEntry implements Serializable, Parcelable {
private static final long serialVersionUID = -7797972103284992662L;
- public ArrayList<String> userIds;
+ public ArrayList<String> userIds;
public long keyId;
+ public String keyIdHex;
public boolean revoked;
public Date date; // TODO: not displayed
- public String fingerPrint;
- public String hexKeyId;
+ public String fingerPrintHex;
public int bitStrength;
public String algorithm;
public boolean secretKey;
@@ -55,8 +56,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
this.keyId = b.keyId;
this.revoked = b.revoked;
this.date = b.date;
- this.fingerPrint = b.fingerPrint;
- this.hexKeyId = b.hexKeyId;
+ this.fingerPrintHex = b.fingerPrintHex;
+ this.keyIdHex = b.keyIdHex;
this.bitStrength = b.bitStrength;
this.algorithm = b.algorithm;
this.secretKey = b.secretKey;
@@ -74,8 +75,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
dest.writeLong(keyId);
dest.writeByte((byte) (revoked ? 1 : 0));
dest.writeSerializable(date);
- dest.writeString(fingerPrint);
- dest.writeString(hexKeyId);
+ dest.writeString(fingerPrintHex);
+ dest.writeString(keyIdHex);
dest.writeInt(bitStrength);
dest.writeString(algorithm);
dest.writeByte((byte) (secretKey ? 1 : 0));
@@ -92,8 +93,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
vr.keyId = source.readLong();
vr.revoked = source.readByte() == 1;
vr.date = (Date) source.readSerializable();
- vr.fingerPrint = source.readString();
- vr.hexKeyId = source.readString();
+ vr.fingerPrintHex = source.readString();
+ vr.keyIdHex = source.readString();
vr.bitStrength = source.readInt();
vr.algorithm = source.readString();
vr.secretKey = source.readByte() == 1;
@@ -109,8 +110,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
}
};
- public long getKeyId() {
- return keyId;
+ public String getKeyIdHex() {
+ return keyIdHex;
}
public byte[] getBytes() {
@@ -121,6 +122,82 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
this.mBytes = bytes;
}
+ public boolean isSelected() {
+ return mSelected;
+ }
+
+ public void setSelected(boolean selected) {
+ this.mSelected = selected;
+ }
+
+ public long getKeyId() {
+ return keyId;
+ }
+
+ public void setKeyId(long keyId) {
+ this.keyId = keyId;
+ }
+
+ public void setKeyIdHex(String keyIdHex) {
+ this.keyIdHex = keyIdHex;
+ }
+
+ public boolean isRevoked() {
+ return revoked;
+ }
+
+ public void setRevoked(boolean revoked) {
+ this.revoked = revoked;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public String getFingerPrintHex() {
+ return fingerPrintHex;
+ }
+
+ public void setFingerPrintHex(String fingerPrintHex) {
+ this.fingerPrintHex = fingerPrintHex;
+ }
+
+ public int getBitStrength() {
+ return bitStrength;
+ }
+
+ public void setBitStrength(int bitStrength) {
+ this.bitStrength = bitStrength;
+ }
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ public void setAlgorithm(String algorithm) {
+ this.algorithm = algorithm;
+ }
+
+ public boolean isSecretKey() {
+ return secretKey;
+ }
+
+ public void setSecretKey(boolean secretKey) {
+ this.secretKey = secretKey;
+ }
+
+ public ArrayList<String> getUserIds() {
+ return userIds;
+ }
+
+ public void setUserIds(ArrayList<String> userIds) {
+ this.userIds = userIds;
+ }
+
/**
* Constructor for later querying from keyserver
*/
@@ -132,14 +209,6 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
userIds = new ArrayList<String>();
}
- public boolean isSelected() {
- return mSelected;
- }
-
- public void setSelected(boolean selected) {
- this.mSelected = selected;
- }
-
/**
* Constructor based on key object, used for import from NFC, QR Codes, files
*/
@@ -165,12 +234,13 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
for (String userId : new IterableIterator<String>(pgpKeyRing.getPublicKey().getUserIDs())) {
userIds.add(userId);
}
+
this.keyId = pgpKeyRing.getPublicKey().getKeyID();
+ this.keyIdHex = PgpKeyHelper.convertKeyIdToHex(keyId);
this.revoked = pgpKeyRing.getPublicKey().isRevoked();
- this.fingerPrint = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey()
- .getFingerprint(), true);
- this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId);
+ this.fingerPrintHex = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey()
+ .getFingerprint());
this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength();
final int algorithm = pgpKeyRing.getPublicKey().getAlgorithm();
this.algorithm = getAlgorithmFromId(algorithm);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
index 0064e9f13..d925480e9 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
@@ -18,9 +18,11 @@
package org.sufficientlysecure.keychain.ui.adapter;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.database.Cursor;
import android.graphics.Color;
import android.support.v4.widget.CursorAdapter;
+import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -30,6 +32,8 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
+import java.util.Date;
+
public class ViewKeyKeysAdapter extends CursorAdapter {
private LayoutInflater mInflater;
@@ -41,6 +45,9 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
private int mIndexCanEncrypt;
private int mIndexCanSign;
private int mIndexRevokedKey;
+ private int mIndexExpiry;
+
+ private ColorStateList mDefaultTextColor;
public ViewKeyKeysAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
@@ -73,6 +80,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
mIndexCanEncrypt = cursor.getColumnIndexOrThrow(Keys.CAN_ENCRYPT);
mIndexCanSign = cursor.getColumnIndexOrThrow(Keys.CAN_SIGN);
mIndexRevokedKey = cursor.getColumnIndexOrThrow(Keys.IS_REVOKED);
+ mIndexExpiry = cursor.getColumnIndexOrThrow(Keys.EXPIRY);
}
}
@@ -80,6 +88,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
public void bindView(View view, Context context, Cursor cursor) {
TextView keyId = (TextView) view.findViewById(R.id.keyId);
TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails);
+ TextView keyExpiry = (TextView) view.findViewById(R.id.keyExpiry);
ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey);
ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey);
ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
@@ -122,13 +131,36 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
keyId.setTextColor(Color.RED);
keyDetails.setTextColor(Color.RED);
} else {
+ keyId.setTextColor(mDefaultTextColor);
+ keyDetails.setTextColor(mDefaultTextColor);
revokedKeyIcon.setVisibility(View.GONE);
}
+
+ boolean valid = true;
+ if (!cursor.isNull(mIndexExpiry)) {
+ Date expiryDate = new Date(cursor.getLong(mIndexExpiry) * 1000);
+ valid = expiryDate.after(new Date());
+ keyExpiry.setText("(" +
+ context.getString(R.string.label_expiry) + ": " +
+ DateFormat.getDateFormat(context).format(expiryDate) + ")");
+ keyExpiry.setVisibility(View.VISIBLE);
+ }
+ else {
+ keyExpiry.setVisibility(View.GONE);
+ }
+ keyId.setEnabled(valid);
+ keyDetails.setEnabled(valid);
+ keyExpiry.setEnabled(valid);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.view_key_keys_item, null);
+ View view = mInflater.inflate(R.layout.view_key_keys_item, null);
+ if (mDefaultTextColor == null) {
+ TextView keyId = (TextView) view.findViewById(R.id.keyId);
+ mDefaultTextColor = keyId.getTextColors();
+ }
+ return view;
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
index b067010df..b4c38184c 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
@@ -87,11 +87,11 @@ public class DeleteFileDialogFragment extends DialogFragment {
false,
null);
- // Message is received after deleting is done in ApgService
+ // Message is received after deleting is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler =
new KeychainIntentServiceHandler(activity, deletingDialog) {
public void handleMessage(Message message) {
- // handle messages by standard ApgHandler first
+ // handle messages by standard KeychainIntentHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
index 1bcf5b33c..3ff88aa2b 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
*
* 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
@@ -28,6 +28,12 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
@@ -40,143 +46,163 @@ import java.util.ArrayList;
public class DeleteKeyDialogFragment extends DialogFragment {
private static final String ARG_MESSENGER = "messenger";
- private static final String ARG_DELETE_KEY_RING_ROW_IDS = "delete_file";
- private static final String ARG_KEY_TYPE = "key_type";
+ private static final String ARG_DELETE_KEY_RING_ROW_IDS = "delete_key_ring_row_ids";
public static final int MESSAGE_OKAY = 1;
+ public static final int MESSAGE_ERROR = 0;
+
+ private boolean isSingleSelection = false;
- public static final String MESSAGE_NOT_DELETED = "not_deleted";
+ private TextView mainMessage;
+ private CheckBox checkDeleteSecret;
+ private LinearLayout deleteSecretKeyView;
+ private View inflateView;
private Messenger mMessenger;
/**
* Creates new instance of this delete file dialog fragment
*/
- public static DeleteKeyDialogFragment newInstance(Messenger messenger, long[] keyRingRowIds,
- int keyType) {
+ public static DeleteKeyDialogFragment newInstance(Messenger messenger, long[] keyRingRowIds
+ ) {
DeleteKeyDialogFragment frag = new DeleteKeyDialogFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_MESSENGER, messenger);
args.putLongArray(ARG_DELETE_KEY_RING_ROW_IDS, keyRingRowIds);
- args.putInt(ARG_KEY_TYPE, keyType);
+ //We don't need the key type
frag.setArguments(args);
return frag;
}
- /**
- * Creates dialog
- */
+
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
+
final FragmentActivity activity = getActivity();
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
final long[] keyRingRowIds = getArguments().getLongArray(ARG_DELETE_KEY_RING_ROW_IDS);
- final int keyType = getArguments().getInt(ARG_KEY_TYPE);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+
+ //Setup custom View to display in AlertDialog
+ LayoutInflater inflater = activity.getLayoutInflater();
+ inflateView = inflater.inflate(R.layout.view_key_delete_fragment, null);
+ builder.setView(inflateView);
+
+ deleteSecretKeyView = (LinearLayout) inflateView.findViewById(R.id.deleteSecretKeyView);
+ mainMessage = (TextView) inflateView.findViewById(R.id.mainMessage);
+ checkDeleteSecret = (CheckBox) inflateView.findViewById(R.id.checkDeleteSecret);
+
builder.setTitle(R.string.warning);
+ //If only a single key has been selected
if (keyRingRowIds.length == 1) {
Uri dataUri;
- if (keyType == Id.type.public_key) {
- dataUri = KeychainContract.KeyRings.buildPublicKeyRingsUri(String.valueOf(keyRingRowIds[0]));
+ ArrayList<Long> publicKeyRings; //Any one will do
+ isSingleSelection = true;
+
+ long selectedRow = keyRingRowIds[0];
+ long keyType;
+ publicKeyRings = ProviderHelper.getPublicKeyRingsRowIds(activity);
+
+ if (publicKeyRings.contains(selectedRow)) {
+ //TODO Should be a better method to do this other than getting all the KeyRings
+ dataUri = KeychainContract.KeyRings.buildPublicKeyRingsUri(String.valueOf(selectedRow));
+ keyType = Id.type.public_key;
} else {
- dataUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowIds[0]));
+ dataUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(String.valueOf(selectedRow));
+ keyType = Id.type.secret_key;
}
+
String userId = ProviderHelper.getUserId(activity, dataUri);
+ //Hide the Checkbox and TextView since this is a single selection,user will be notified thru message
+ deleteSecretKeyView.setVisibility(View.GONE);
+ //Set message depending on which key it is.
+ mainMessage.setText(getString(keyType == Id.type.secret_key ? R.string.secret_key_deletion_confirmation
+ : R.string.public_key_deletetion_confirmation, userId));
+
- builder.setMessage(getString(
- keyType == Id.type.public_key ? R.string.key_deletion_confirmation
- : R.string.secret_key_deletion_confirmation, userId));
} else {
- builder.setMessage(R.string.key_deletion_confirmation_multi);
+ deleteSecretKeyView.setVisibility(View.VISIBLE);
+ mainMessage.setText(R.string.key_deletion_confirmation_multi);
}
+
builder.setIcon(R.drawable.ic_dialog_alert_holo_light);
builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
-
@Override
- public void onClick(DialogInterface dialog, int id) {
- ArrayList<String> notDeleted = new ArrayList<String>();
-
- if (keyType == Id.type.public_key) {
- Uri queryUri = KeychainContract.KeyRings.buildPublicKeyRingsUri();
- String[] projection = new String[]{
- KeychainContract.KeyRings._ID, // 0
- KeychainContract.KeyRings.MASTER_KEY_ID, // 1
- KeychainContract.UserIds.USER_ID // 2
- };
-
- // make selection with all entries where _ID is one of the given row ids
- String selection = KeychainDatabase.Tables.KEY_RINGS + "." +
- KeychainContract.KeyRings._ID + " IN(";
- String selectionIDs = "";
- for (int i = 0; i < keyRingRowIds.length; i++) {
- selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'";
- if (i + 1 < keyRingRowIds.length) {
- selectionIDs += ",";
- }
- }
- selection += selectionIDs + ")";
-
- Cursor cursor = activity.getContentResolver().query(queryUri, projection,
- selection, null, null);
-
- long rowId;
- long masterKeyId;
- String userId;
- try {
- while (cursor != null && cursor.moveToNext()) {
- rowId = cursor.getLong(0);
- masterKeyId = cursor.getLong(1);
- userId = cursor.getString(2);
-
- Log.d(Constants.TAG, "rowId: " + rowId + ", masterKeyId: " + masterKeyId
- + ", userId: " + userId);
-
- // check if a corresponding secret key exists...
- Cursor secretCursor = activity.getContentResolver().query(
- KeychainContract.KeyRings
- .buildSecretKeyRingsByMasterKeyIdUri(
- String.valueOf(masterKeyId)),
- null, null, null, null
- );
- if (secretCursor != null && secretCursor.getCount() > 0) {
- notDeleted.add(userId);
- } else {
- // it is okay to delete this key, no secret key found!
- ProviderHelper.deletePublicKeyRing(activity, rowId);
- }
- if (secretCursor != null) {
- secretCursor.close();
+ public void onClick(DialogInterface dialog, int which) {
+ Uri queryUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri();
+ String[] projection = new String[]{
+ KeychainContract.KeyRings.MASTER_KEY_ID, // 0
+ KeychainContract.KeyRings.TYPE// 1
+ };
+
+ // make selection with all entries where _ID is one of the given row ids
+ String selection = KeychainDatabase.Tables.KEY_RINGS + "." +
+ KeychainContract.KeyRings._ID + " IN(";
+ String selectionIDs = "";
+ for (int i = 0; i < keyRingRowIds.length; i++) {
+ selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'";
+ if (i + 1 < keyRingRowIds.length)
+ selectionIDs += ",";
+ }
+ selection += selectionIDs + ")";
+
+ Cursor cursor = activity.getContentResolver().query(queryUri, projection,
+ selection, null, null);
+
+
+ long masterKeyId;
+ long keyType;
+ boolean isSuccessfullyDeleted;
+ try {
+ isSuccessfullyDeleted = false;
+ while (cursor != null && cursor.moveToNext()) {
+ masterKeyId = cursor.getLong(0);
+ keyType = cursor.getLong(1);
+
+ Log.d(Constants.TAG, "masterKeyId: " + masterKeyId
+ + ", keyType:" + (keyType == KeychainContract.KeyTypes.PUBLIC ? "Public" : "Private"));
+
+
+ if (keyType == KeychainContract.KeyTypes.SECRET) {
+ if (checkDeleteSecret.isChecked() || isSingleSelection) {
+ ProviderHelper.deleteUnifiedKeyRing(activity, String.valueOf(masterKeyId), true);
}
- }
- } finally {
- if (cursor != null) {
- cursor.close();
+ } else {
+ ProviderHelper.deleteUnifiedKeyRing(activity, String.valueOf(masterKeyId), false);
}
}
- } else {
- for (long keyRowId : keyRingRowIds) {
- ProviderHelper.deleteSecretKeyRing(activity, keyRowId);
+
+ //Check if the selected rows have actually been deleted
+ cursor = activity.getContentResolver().query(queryUri, projection, selection, null, null);
+ if (cursor == null || cursor.getCount() == 0 || !checkDeleteSecret.isChecked()) {
+ isSuccessfullyDeleted = true;
}
+
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+
}
dismiss();
- if (notDeleted.size() > 0) {
- Bundle data = new Bundle();
- data.putStringArrayList(MESSAGE_NOT_DELETED, notDeleted);
- sendMessageToHandler(MESSAGE_OKAY, data);
- } else {
+ if (isSuccessfullyDeleted) {
sendMessageToHandler(MESSAGE_OKAY, null);
+ } else {
+ sendMessageToHandler(MESSAGE_ERROR, null);
}
}
- });
+
+ }
+ );
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
@@ -198,7 +224,6 @@ public class DeleteKeyDialogFragment extends DialogFragment {
if (data != null) {
msg.setData(data);
}
-
try {
mMessenger.send(msg);
} catch (RemoteException e) {
@@ -207,4 +232,5 @@ public class DeleteKeyDialogFragment extends DialogFragment {
Log.w(Constants.TAG, "Messenger is null!", e);
}
}
-}
+
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
index b501ba230..94586810e 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
@@ -90,7 +90,7 @@ public class ShareQrCodeDialogFragment extends DialogFragment {
alert.setPositiveButton(R.string.btn_okay, null);
byte[] fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), dataUri);
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, false);
+ String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
mText.setText(getString(R.string.share_qr_code_dialog_fingerprint_text) + " " + fingerprint);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java
new file mode 100644
index 000000000..f9a5b92f3
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import com.beardedhen.androidbootstrap.FontAwesomeText;
+import org.sufficientlysecure.keychain.R;
+
+/**
+ * Class representing a LinearLayout that can fold and hide it's content when pressed
+ * To use just add the following to your xml layout
+
+ <org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ custom:foldedLabel="@string/TEXT_TO_DISPLAY_WHEN_FOLDED"
+ custom:unFoldedLabel="@string/TEXT_TO_DISPLAY_WHEN_UNFOLDED"
+ custom:foldedIcon="ICON_NAME_FROM_FontAwesomeText_TO_USE_WHEN_FOLDED"
+ custom:unFoldedIcon="ICON_NAME_FROM_FontAwesomeText_TO_USE_WHEN_UNFOLDED">
+
+ <include layout="@layout/ELEMENTS_TO_BE_FOLDED"/>
+
+ </org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout>
+
+ */
+public class FoldableLinearLayout extends LinearLayout {
+
+ private FontAwesomeText mFoldableIcon;
+ private boolean mFolded;
+ private boolean mHasMigrated = false;
+ private Integer mShortAnimationDuration = null;
+ private TextView mFoldableTextView = null;
+ private LinearLayout mFoldableContainer = null;
+ private View mFoldableLayout = null;
+
+ private String mFoldedIconName;
+ private String mUnFoldedIconName;
+ private String mFoldedLabel;
+ private String mUnFoldedLabel;
+
+ public FoldableLinearLayout(Context context) {
+ super(context);
+ processAttributes(context, null);
+ }
+
+ public FoldableLinearLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ processAttributes(context, attrs);
+ }
+
+ public FoldableLinearLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs);
+ processAttributes(context, attrs);
+ }
+
+ /**
+ * Load given attributes to inner variables,
+ * @param context
+ * @param attrs
+ */
+ private void processAttributes(Context context, AttributeSet attrs) {
+ if(attrs != null) {
+ TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.FoldableLinearLayout, 0, 0);
+ mFoldedIconName = a.getString(R.styleable.FoldableLinearLayout_foldedIcon);
+ mUnFoldedIconName = a.getString(R.styleable.FoldableLinearLayout_unFoldedIcon);
+ mFoldedLabel = a.getString(R.styleable.FoldableLinearLayout_foldedLabel);
+ mUnFoldedLabel = a.getString(R.styleable.FoldableLinearLayout_unFoldedLabel);
+ a.recycle();
+ }
+ // If any attribute isn't found then set a default one
+ mFoldedIconName = (mFoldedIconName == null) ? "fa-chevron-right" : mFoldedIconName;
+ mUnFoldedIconName = (mUnFoldedIconName == null) ? "fa-chevron-down" : mUnFoldedIconName;
+ mFoldedLabel = (mFoldedLabel == null) ? context.getString(R.id.none) : mFoldedLabel;
+ mUnFoldedLabel = (mUnFoldedLabel == null) ? context.getString(R.id.none) : mUnFoldedLabel;
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ // if the migration has already happened
+ // there is no need to move any children
+ if(!mHasMigrated) {
+ migrateChildrenToContainer();
+ mHasMigrated = true;
+ }
+
+ initialiseInnerViews();
+
+ super.onFinishInflate();
+ }
+
+ /**
+ * Migrates Child views as declared in xml to the inner foldableContainer
+ */
+ private void migrateChildrenToContainer() {
+ // Collect children of FoldableLinearLayout as declared in XML
+ int childNum = getChildCount();
+ View[] children = new View[childNum];
+
+ for(int i = 0; i < childNum; i++) {
+ children[i] = getChildAt(i);
+ }
+ if(children[0].getId() == R.id.foldableControl) {
+
+ }
+
+ // remove all of them from FoldableLinearLayout
+ detachAllViewsFromParent();
+
+ // Inflate the inner foldable_linearlayout.xml
+ LayoutInflater inflator = (LayoutInflater)getContext().getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+
+ mFoldableLayout = inflator.inflate(R.layout.foldable_linearlayout, this, true);
+ mFoldableContainer = (LinearLayout) mFoldableLayout.findViewById(R.id.foldableContainer);
+
+ // Push previously collected children into foldableContainer.
+ for(int i = 0; i < childNum; i++) {
+ addView(children[i]);
+ }
+ }
+
+ private void initialiseInnerViews() {
+ mFoldableIcon = (FontAwesomeText) mFoldableLayout.findViewById(R.id.foldableIcon);
+ mFoldableIcon.setIcon(mFoldedIconName);
+ mFoldableTextView = (TextView) mFoldableLayout.findViewById(R.id.foldableText);
+ mFoldableTextView.setText(mFoldedLabel);
+
+ // retrieve and cache the system's short animation time
+ mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
+
+ LinearLayout foldableControl = (LinearLayout) mFoldableLayout.findViewById(R.id.foldableControl);
+ foldableControl.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mFolded = !mFolded;
+ if (mFolded) {
+ mFoldableIcon.setIcon(mUnFoldedIconName);
+ mFoldableContainer.setVisibility(View.VISIBLE);
+ AlphaAnimation animation = new AlphaAnimation(0f, 1f);
+ animation.setDuration(mShortAnimationDuration);
+ mFoldableContainer.startAnimation(animation);
+ mFoldableTextView.setText(mUnFoldedLabel);
+
+ } else {
+ mFoldableIcon.setIcon(mFoldedIconName);
+ AlphaAnimation animation = new AlphaAnimation(1f, 0f);
+ animation.setDuration(mShortAnimationDuration);
+ animation.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) { }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ // making sure that at the end the container is completely removed from view
+ mFoldableContainer.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) { }
+ });
+ mFoldableContainer.startAnimation(animation);
+ mFoldableTextView.setText(mFoldedLabel);
+ }
+ }
+ });
+
+ }
+
+ /**
+ * Adds provided child view to foldableContainer View
+ * @param child
+ */
+ @Override
+ public void addView(View child) {
+ if(mFoldableContainer != null) {
+ mFoldableContainer.addView(child);
+ }
+ }
+}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java
index e5b6003b1..1ef178f15 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java
@@ -256,11 +256,11 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
}
});
- // Message is received after generating is done in ApgService
+ // Message is received after generating is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(mActivity,
mGeneratingDialog) {
public void handleMessage(Message message) {
- // handle messages by standard ApgHandler first
+ // handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java
index 9d6850027..b987e1533 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java
@@ -18,7 +18,6 @@
package org.sufficientlysecure.keychain.util;
-import android.text.Html;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
@@ -30,6 +29,7 @@ import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
+import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
@@ -72,26 +72,26 @@ public class HkpKeyServer extends KeyServer {
/**
* pub:%keyid%:%algo%:%keylen%:%creationdate%:%expirationdate%:%flags%
* <ul>
- * <li>%<b>keyid</b>% = this is either the fingerprint or the key ID of the key. Either the 16-digit or 8-digit
- * key IDs are acceptable, but obviously the fingerprint is best.</li>
- * <li>%<b>algo</b>% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc).
- * See <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a></li>
- * <li>%<b>keylen</b>% = the key length (i.e. 1024, 2048, 4096, etc.)</li>
- * <li>%<b>creationdate</b>% = creation date of the key in standard
- * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since
- * 1/1/1970 UTC time)</li>
- * <li>%<b>expirationdate</b>% = expiration date of the key in standard
- * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since
- * 1/1/1970 UTC time)</li>
- * <li>%<b>flags</b>% = letter codes to indicate details of the key, if any. Flags may be in any order. The
- * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so
- * the absence of a given flag does not necessarily mean the absence of the detail.
- * <ul>
- * <li>r == revoked</li>
- * <li>d == disabled</li>
- * <li>e == expired</li>
- * </ul>
- * </li>
+ * <li>%<b>keyid</b>% = this is either the fingerprint or the key ID of the key. Either the 16-digit or 8-digit
+ * key IDs are acceptable, but obviously the fingerprint is best.</li>
+ * <li>%<b>algo</b>% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc).
+ * See <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a></li>
+ * <li>%<b>keylen</b>% = the key length (i.e. 1024, 2048, 4096, etc.)</li>
+ * <li>%<b>creationdate</b>% = creation date of the key in standard
+ * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since
+ * 1/1/1970 UTC time)</li>
+ * <li>%<b>expirationdate</b>% = expiration date of the key in standard
+ * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since
+ * 1/1/1970 UTC time)</li>
+ * <li>%<b>flags</b>% = letter codes to indicate details of the key, if any. Flags may be in any order. The
+ * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so
+ * the absence of a given flag does not necessarily mean the absence of the detail.
+ * <ul>
+ * <li>r == revoked</li>
+ * <li>d == disabled</li>
+ * <li>e == expired</li>
+ * </ul>
+ * </li>
* </ul>
*
* @see <a href="http://tools.ietf.org/html/draft-shaw-openpgp-hkp-00#section-5.2">5.2. Machine Readable Indexes</a>
@@ -105,23 +105,23 @@ public class HkpKeyServer extends KeyServer {
/**
* uid:%escaped uid string%:%creationdate%:%expirationdate%:%flags%
* <ul>
- * <li>%<b>escaped uid string</b>% = the user ID string, with HTTP %-escaping for anything that isn't 7-bit
- * safe as well as for the ":" character. Any other characters may be escaped, as desired.</li>
- * <li>%<b>creationdate</b>% = creation date of the key in standard
- * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since
- * 1/1/1970 UTC time)</li>
- * <li>%<b>expirationdate</b>% = expiration date of the key in standard
- * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since
- * 1/1/1970 UTC time)</li>
- * <li>%<b>flags</b>% = letter codes to indicate details of the key, if any. Flags may be in any order. The
- * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so
- * the absence of a given flag does not necessarily mean the absence of the detail.
- * <ul>
- * <li>r == revoked</li>
- * <li>d == disabled</li>
- * <li>e == expired</li>
- * </ul>
- * </li>
+ * <li>%<b>escaped uid string</b>% = the user ID string, with HTTP %-escaping for anything that isn't 7-bit
+ * safe as well as for the ":" character. Any other characters may be escaped, as desired.</li>
+ * <li>%<b>creationdate</b>% = creation date of the key in standard
+ * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since
+ * 1/1/1970 UTC time)</li>
+ * <li>%<b>expirationdate</b>% = expiration date of the key in standard
+ * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since
+ * 1/1/1970 UTC time)</li>
+ * <li>%<b>flags</b>% = letter codes to indicate details of the key, if any. Flags may be in any order. The
+ * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so
+ * the absence of a given flag does not necessarily mean the absence of the detail.
+ * <ul>
+ * <li>r == revoked</li>
+ * <li>d == disabled</li>
+ * <li>e == expired</li>
+ * </ul>
+ * </li>
* </ul>
*/
public static final Pattern UID_LINE = Pattern
@@ -179,6 +179,7 @@ public class HkpKeyServer extends KeyServer {
for (int i = 0; i < ips.length; ++i) {
try {
String url = "http://" + ips[i].getHostAddress() + ":" + mPort + request;
+ Log.d(Constants.TAG, "hkp keyserver query: " + url);
URL realUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
conn.setConnectTimeout(5000);
@@ -238,22 +239,34 @@ public class HkpKeyServer extends KeyServer {
final Matcher matcher = PUB_KEY_LINE.matcher(data);
while (matcher.find()) {
- final ImportKeysListEntry info = new ImportKeysListEntry();
- info.bitStrength = Integer.parseInt(matcher.group(3));
- final int algorithmId = Integer.decode(matcher.group(2));
- info.algorithm = getAlgorithmFromId(algorithmId);
+ final ImportKeysListEntry entry = new ImportKeysListEntry();
+
+ entry.setBitStrength(Integer.parseInt(matcher.group(3)));
- info.hexKeyId = "0x" + matcher.group(1);
- info.keyId = PgpKeyHelper.convertHexToKeyId(matcher.group(1));
+ final int algorithmId = Integer.decode(matcher.group(2));
+ entry.setAlgorithm(getAlgorithmFromId(algorithmId));
+
+ // group 1 contains the full fingerprint (v4) or the long key id if available
+ // see https://bitbucket.org/skskeyserver/sks-keyserver/pull-request/12/fixes-for-machine-readable-indexes/diff
+ // and https://github.com/openpgp-keychain/openpgp-keychain/issues/259#issuecomment-38168176
+ String fingerprintOrKeyId = matcher.group(1);
+ if (fingerprintOrKeyId.length() > 16) {
+ entry.setFingerPrintHex(fingerprintOrKeyId.toLowerCase(Locale.US));
+ entry.setKeyIdHex("0x" + fingerprintOrKeyId.substring(fingerprintOrKeyId.length()
+ - 16, fingerprintOrKeyId.length()));
+ } else {
+ // set key id only
+ entry.setKeyIdHex("0x" + fingerprintOrKeyId);
+ }
final long creationDate = Long.parseLong(matcher.group(4));
final GregorianCalendar tmpGreg = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
tmpGreg.setTimeInMillis(creationDate * 1000);
- info.date = tmpGreg.getTime();
+ entry.setDate(tmpGreg.getTime());
- info.revoked = matcher.group(6).contains("r");
- info.userIds = new ArrayList<String>();
+ entry.setRevoked(matcher.group(6).contains("r"));
+ ArrayList<String> userIds = new ArrayList<String>();
final String uidLines = matcher.group(7);
final Matcher uidMatcher = UID_LINE.matcher(uidLines);
while (uidMatcher.find()) {
@@ -266,20 +279,23 @@ public class HkpKeyServer extends KeyServer {
// will never happen, because "UTF8" is supported
}
}
- info.userIds.add(tmp);
+ userIds.add(tmp);
}
- results.add(info);
+ entry.setUserIds(userIds);
+
+ results.add(entry);
}
return results;
}
@Override
- public String get(long keyId) throws QueryException {
+ public String get(String keyIdHex) throws QueryException {
HttpClient client = new DefaultHttpClient();
try {
- HttpGet get = new HttpGet("http://" + mHost + ":" + mPort
- + "/pks/lookup?op=get&options=mr&search=" + PgpKeyHelper.convertKeyIdToHex(keyId));
-
+ String query = "http://" + mHost + ":" + mPort +
+ "/pks/lookup?op=get&options=mr&search=" + keyIdHex;
+ Log.d(Constants.TAG, "hkp keyserver get: " + query);
+ HttpGet get = new HttpGet(query);
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new QueryException("not found");
@@ -302,13 +318,14 @@ public class HkpKeyServer extends KeyServer {
}
@Override
- public void add(String armoredText) throws AddKeyException {
+ public void add(String armoredKey) throws AddKeyException {
HttpClient client = new DefaultHttpClient();
try {
- HttpPost post = new HttpPost("http://" + mHost + ":" + mPort + "/pks/add");
-
+ String query = "http://" + mHost + ":" + mPort + "/pks/add";
+ HttpPost post = new HttpPost(query);
+ Log.d(Constants.TAG, "hkp keyserver add: " + query);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
- nameValuePairs.add(new BasicNameValuePair("keytext", armoredText));
+ nameValuePairs.add(new BasicNameValuePair("keytext", armoredKey));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java
index a31fdc5ae..7f70867a5 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java
@@ -46,7 +46,7 @@ public abstract class KeyServer {
abstract List<ImportKeysListEntry> search(String query) throws QueryException, TooManyResponses,
InsufficientQuery;
- abstract String get(long keyId) throws QueryException;
+ abstract String get(String keyIdHex) throws QueryException;
- abstract void add(String armoredText) throws AddKeyException;
+ abstract void add(String armoredKey) throws AddKeyException;
}
diff --git a/OpenPGP-Keychain/src/main/res/layout/api_account_create_activity.xml b/OpenPGP-Keychain/src/main/res/layout/api_account_create_activity.xml
new file mode 100644
index 000000000..ead336dbb
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/layout/api_account_create_activity.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="16dp"
+ android:orientation="vertical">
+
+ <fragment
+ android:id="@+id/api_account_settings_fragment"
+ android:name="org.sufficientlysecure.keychain.remote.ui.AccountSettingsFragment"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ tools:layout="@layout/api_app_settings_fragment" />
+
+ </LinearLayout>
+</ScrollView>
diff --git a/OpenPGP-Keychain/src/main/res/layout/api_account_settings_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/api_account_settings_fragment.xml
new file mode 100644
index 000000000..3284b5b0a
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/layout/api_account_settings_fragment.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ xmlns:custom="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="4dp"
+ android:gravity="center_horizontal"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/api_account_settings_app_icon"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginRight="6dp"
+ android:src="@drawable/icon" />
+
+ <TextView
+ android:id="@+id/api_account_settings_app_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toRightOf="@+id/api_app_settings_app_icon"
+ android:gravity="center_vertical"
+ android:orientation="vertical"
+ android:text="Name (set in-code)"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+ </RelativeLayout>
+
+ <fragment
+ android:id="@+id/api_account_settings_select_key_fragment"
+ android:name="org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ tools:layout="@layout/select_secret_key_layout_fragment" />
+
+ <org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ custom:foldedLabel="@string/api_settings_show_advanced"
+ custom:unFoldedLabel="@string/api_settings_hide_advanced"
+ custom:foldedIcon="fa-chevron-right"
+ custom:unFoldedIcon="fa-chevron-down">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/label_encryption_algorithm"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <Spinner
+ android:id="@+id/api_account_settings_encryption_algorithm"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/label_hash_algorithm"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <Spinner
+ android:id="@+id/api_account_settings_hash_algorithm"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/label_message_compression"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <Spinner
+ android:id="@+id/api_account_settings_compression"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/api_settings_package_name"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/api_account_settings_package_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="com.example"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/api_settings_package_signature"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/api_account_settings_package_signature"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Base64 encoded signature"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ </org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml
index aa9d59004..f85f3b8f7 100644
--- a/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml
@@ -20,7 +20,7 @@
<fragment
android:id="@+id/api_app_settings_fragment"
- android:name="org.sufficientlysecure.keychain.service.remote.AppSettingsFragment"
+ android:name="org.sufficientlysecure.keychain.remote.ui.AppSettingsFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout="@layout/api_app_settings_fragment" />
diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml
index d83c8e87d..d38567497 100644
--- a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml
@@ -12,10 +12,24 @@
<fragment
android:id="@+id/api_app_settings_fragment"
- android:name="org.sufficientlysecure.keychain.service.remote.AppSettingsFragment"
+ android:name="org.sufficientlysecure.keychain.remote.ui.AppSettingsFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout="@layout/api_app_settings_fragment" />
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/api_settings_accounts"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <FrameLayout
+ android:id="@+id/api_accounts_list_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingLeft="4dp"
+ android:paddingRight="4dp" />
+
</LinearLayout>
</ScrollView>
diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml
index a8b68859b..96271d418 100644
--- a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml
@@ -2,6 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
+ xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
@@ -35,64 +36,13 @@
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
- <fragment
- android:id="@+id/api_app_settings_select_key_fragment"
- android:name="org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment"
+ <org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- tools:layout="@layout/select_secret_key_layout_fragment" />
-
- <com.beardedhen.androidbootstrap.BootstrapButton
- android:id="@+id/api_app_settings_advanced_button"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="4dp"
- android:text="@string/api_settings_show_advanced"
- bootstrapbutton:bb_icon_left="fa-caret-up"
- bootstrapbutton:bb_size="default"
- bootstrapbutton:bb_type="default" />
-
- <LinearLayout
- android:id="@+id/api_app_settings_advanced"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:visibility="gone">
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/label_encryption_algorithm"
- android:textAppearance="?android:attr/textAppearanceMedium" />
-
- <Spinner
- android:id="@+id/api_app_settings_encryption_algorithm"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/label_hash_algorithm"
- android:textAppearance="?android:attr/textAppearanceMedium" />
-
- <Spinner
- android:id="@+id/api_app_settings_hash_algorithm"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/label_message_compression"
- android:textAppearance="?android:attr/textAppearanceMedium" />
-
- <Spinner
- android:id="@+id/api_app_settings_compression"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ android:layout_height="match_parent"
+ custom:foldedLabel="@string/api_settings_show_info"
+ custom:unFoldedLabel="@string/api_settings_hide_info"
+ custom:foldedIcon="fa-chevron-right"
+ custom:unFoldedIcon="fa-chevron-down">
<TextView
android:layout_width="match_parent"
@@ -119,5 +69,7 @@
android:layout_height="wrap_content"
android:text="Base64 encoded signature"
android:textAppearance="?android:attr/textAppearanceSmall" />
- </LinearLayout>
+
+ </org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout>
+
</LinearLayout> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/layout/api_apps_list_content.xml b/OpenPGP-Keychain/src/main/res/layout/api_apps_list_content.xml
index b8606b929..9f9b99045 100644
--- a/OpenPGP-Keychain/src/main/res/layout/api_apps_list_content.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/api_apps_list_content.xml
@@ -8,7 +8,7 @@
<fragment
android:id="@+id/crypto_consumers_list_fragment"
- android:name="org.sufficientlysecure.keychain.service.remote.RegisteredAppsListFragment"
+ android:name="org.sufficientlysecure.keychain.remote.ui.AppsListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml b/OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml
index d6a05f0d4..1dba66cfa 100644
--- a/OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:fontawesometext="http://schemas.android.com/apk/res-auto"
- xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto" android:id="@+id/content_frame"
+ xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
+ xmlns:custom="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/content_frame"
android:layout_marginLeft="@dimen/drawer_content_padding"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -71,7 +72,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:paddingLeft="16dp">
+ android:paddingLeft="16dp"
+ android:paddingRight="4dip">
<TextView
android:id="@+id/mainUserId"
@@ -215,7 +217,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="top"
- android:inputType="text|textCapSentences|textMultiLine|textLongMessage"/>
+ android:inputType="text|textCapSentences|textMultiLine|textLongMessage"
+ android:hint="@string/encrypt_content_edit_text_hint"/>
</LinearLayout>
<LinearLayout
@@ -253,101 +256,18 @@
bootstrapbutton:bb_type="default"/>
</LinearLayout>
- <LinearLayout
- android:id="@+id/advancedSettingsControl"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:clickable="true">
-
- <com.beardedhen.androidbootstrap.FontAwesomeText
- android:id="@+id/advancedSettingsIcon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="10dp"
- android:textSize="12sp"
- android:paddingTop="@dimen/padding_medium"
- android:paddingBottom="@dimen/padding_medium"
- fontawesometext:fa_icon="fa-chevron-right"/>
-
- <TextView
- android:id="@+id/advancedSettings"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/btn_encryption_advanced_settings_show"
- android:paddingTop="@dimen/padding_medium"
- android:paddingBottom="@dimen/padding_medium"
- android:textColor="@color/emphasis"/>
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/fileAdvancedSettingsContainer"
+ <org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:visibility="gone">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
-
- <TextView
- android:id="@+id/label_fileCompression"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_weight="1"
- android:paddingRight="10dip"
- android:text="@string/label_file_compression"
- android:textAppearance="?android:attr/textAppearanceSmall"/>
-
- <Spinner
- android:id="@+id/fileCompression"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"/>
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
-
- <CheckBox
- android:id="@+id/deleteAfterEncryption"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:text="@string/label_delete_after_encryption"/>
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
+ android:layout_height="match_parent"
+ custom:foldedLabel="@string/btn_encryption_advanced_settings_show"
+ custom:unFoldedLabel="@string/btn_encryption_advanced_settings_hide"
+ custom:foldedIcon="fa-chevron-right"
+ custom:unFoldedIcon="fa-chevron-down">
- <CheckBox
- android:id="@+id/shareAfterEncryption"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:text="@string/label_share_after_encryption"/>
- </LinearLayout>
+ <include layout="@layout/encrypt_content_adv_settings"/>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
+ </org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout>
- <CheckBox
- android:id="@+id/asciiArmour"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:text="@string/label_ascii_armor"/>
- </LinearLayout>
- </LinearLayout>
</LinearLayout>
</ViewFlipper>
@@ -371,7 +291,7 @@
android:padding="4dp"
android:layout_weight="1"
android:text="@string/btn_share"
- bootstrapbutton:bb_icon_left="fa-lock"
+ bootstrapbutton:bb_icon_left="fa-share-square"
bootstrapbutton:bb_type="info"/>
<com.beardedhen.androidbootstrap.BootstrapButton
@@ -381,7 +301,7 @@
android:padding="4dp"
android:layout_weight="1"
android:text="@string/btn_clipboard"
- bootstrapbutton:bb_icon_left="fa-lock"
+ bootstrapbutton:bb_icon_left="fa-clipboard"
bootstrapbutton:bb_type="info"/>
<com.beardedhen.androidbootstrap.BootstrapButton
@@ -395,4 +315,4 @@
bootstrapbutton:bb_type="info"/>
</LinearLayout>
</LinearLayout>
-</ScrollView> \ No newline at end of file
+</ScrollView>
diff --git a/OpenPGP-Keychain/src/main/res/layout/encrypt_content_adv_settings.xml b/OpenPGP-Keychain/src/main/res/layout/encrypt_content_adv_settings.xml
new file mode 100644
index 000000000..2281759d1
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/layout/encrypt_content_adv_settings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/label_fileCompression"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_weight="1"
+ android:paddingRight="10dip"
+ android:text="@string/label_file_compression"
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
+
+ <Spinner
+ android:id="@+id/fileCompression"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <CheckBox
+ android:id="@+id/deleteAfterEncryption"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:text="@string/label_delete_after_encryption"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <CheckBox
+ android:id="@+id/shareAfterEncryption"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:text="@string/label_share_after_encryption"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <CheckBox
+ android:id="@+id/asciiArmour"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:text="@string/label_ascii_armor"/>
+ </LinearLayout>
+</merge> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/layout/foldable_linearlayout.xml b/OpenPGP-Keychain/src/main/res/layout/foldable_linearlayout.xml
new file mode 100644
index 000000000..2b863d52b
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/layout/foldable_linearlayout.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:fontawesometext="http://schemas.android.com/apk/res-auto"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <LinearLayout
+ android:id="@+id/foldableControl"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:clickable="true">
+
+ <com.beardedhen.androidbootstrap.FontAwesomeText
+ android:id="@+id/foldableIcon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="10dp"
+ android:textSize="12sp"
+ android:paddingTop="@dimen/padding_medium"
+ android:paddingBottom="@dimen/padding_medium"
+ fontawesometext:fa_icon="fa-chevron-right"/>
+
+ <TextView
+ android:id="@+id/foldableText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/none"
+ android:paddingTop="@dimen/padding_medium"
+ android:paddingBottom="@dimen/padding_medium"
+ android:textColor="@color/emphasis"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/foldableContainer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone"/>
+</LinearLayout> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/layout/import_keys_list_entry.xml b/OpenPGP-Keychain/src/main/res/layout/import_keys_list_entry.xml
index 3cc0bc6dc..f5a39f115 100644
--- a/OpenPGP-Keychain/src/main/res/layout/import_keys_list_entry.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/import_keys_list_entry.xml
@@ -15,7 +15,7 @@
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="3dip"
@@ -23,7 +23,7 @@
android:singleLine="true" >
<LinearLayout
- android:layout_width="fill_parent"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
@@ -52,13 +52,6 @@
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
- android:id="@+id/fingerprint"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="fingerprint"
- android:textAppearance="?android:attr/textAppearanceSmall" />
-
- <TextView
android:id="@+id/mainUserIdRest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -77,10 +70,11 @@
<TextView
android:id="@+id/keyId"
android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:text="BBBBBBBB"
+ android:layout_height="wrap_content"
+ android:text="0xBBBBBBBBBBBBBBBB"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:typeface="monospace" />
+ android:typeface="monospace"
+ android:layout_weight="1" />
<TextView
android:id="@+id/algorithm"
@@ -89,6 +83,14 @@
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
+ android:id="@+id/fingerprint"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="fingerprint"
+ android:typeface="monospace"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -99,10 +101,10 @@
<LinearLayout
android:id="@+id/list"
- android:layout_width="fill_parent"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="36dip"
android:orientation="vertical" >
</LinearLayout>
-</LinearLayout> \ No newline at end of file
+</LinearLayout>
diff --git a/OpenPGP-Keychain/src/main/res/layout/key_list_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/key_list_fragment.xml
index 77bd6f4e9..f2430f213 100644
--- a/OpenPGP-Keychain/src/main/res/layout/key_list_fragment.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/key_list_fragment.xml
@@ -11,7 +11,7 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:visibility="gone"
+ android:visibility="visible"
android:gravity="center">
<ProgressBar
@@ -51,7 +51,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:visibility="gone">
<TextView
android:layout_width="wrap_content"
diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_delete_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_delete_fragment.xml
new file mode 100644
index 000000000..ef31f7690
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/layout/view_key_delete_fragment.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/mainMessage"
+ android:layout_margin="4dp"
+ android:textAppearance="?android:textAppearanceMedium" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:weightSum="1"
+ android:id="@+id/deleteSecretKeyView">
+
+ <CheckBox
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.1"
+ android:layout_margin="4dp"
+ android:id="@+id/checkDeleteSecret" />
+
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_margin="4dp"
+ android:textAppearance="?android:textAppearanceMedium"
+ android:layout_weight="0.9"
+ android:text="@string/secret_key_delete_text" />
+
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml
index 235949ce2..43f06e246 100644
--- a/OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml
@@ -28,9 +28,17 @@
android:id="@+id/keyDetails"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:paddingRight="5dip"
android:text="(RSA, 1024bit)"
android:textAppearance="?android:attr/textAppearanceSmall" />
+ <TextView
+ android:id="@+id/keyExpiry"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/label_expiry"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -63,4 +71,4 @@
android:src="@drawable/signed_small" />
</LinearLayout>
-</LinearLayout> \ No newline at end of file
+</LinearLayout>
diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml
index 6ef3f3072..adbdb98dd 100644
--- a/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml
@@ -130,19 +130,23 @@
android:text="" />
</TableRow>
- <TableRow>
+ <TableRow
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/tableRow">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"
- android:text="@string/label_creation" />
+ android:text="@string/label_fingerprint" />
<TextView
- android:id="@+id/creation"
+ android:id="@+id/fingerprint"
android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ android:layout_height="wrap_content"
+ android:typeface="monospace" />
</TableRow>
<TableRow>
@@ -152,31 +156,27 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"
- android:text="@string/label_expiry" />
+ android:text="@string/label_creation" />
<TextView
- android:id="@+id/expiry"
+ android:id="@+id/creation"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</TableRow>
- <TableRow
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:id="@+id/tableRow">
+ <TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"
- android:text="@string/label_fingerprint" />
+ android:text="@string/label_expiry" />
<TextView
- android:id="@+id/fingerprint"
+ android:id="@+id/expiry"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:typeface="monospace" />
+ android:layout_height="wrap_content" />
</TableRow>
<TableRow>
@@ -264,4 +264,4 @@
</LinearLayout>
-</ScrollView> \ No newline at end of file
+</ScrollView>
diff --git a/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_about.html b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_about.html
new file mode 100644
index 000000000..d9150a5e8
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_about.html
@@ -0,0 +1,48 @@
+<html>
+<head></head>
+<body>
+<p><a href="http://www.openkeychain.org">http://www.openkeychain.org</a></p>
+<p><a href="http://www.openkeychain.org">OpenKeychain</a> is an OpenPGP implementation for Android.</p>
+<p>License: GPLv3+</p>
+
+<h2>Developers OpenKeychain</h2>
+<ul>
+<li>Dominik Schürmann (Lead developer)</li>
+<li>Ash Hughes (crypto patches)</li>
+<li>Brian C. Barnes</li>
+<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
+
+</ul>
+<h2>Developers APG 1.x</h2>
+<ul>
+<li>Thialfihar (Lead developer)</li>
+<li>'Senecaso' (QRCode, sign key, upload key)</li>
+<li>Markus Doits</li>
+</ul>
+<h2>Libraries</h2>
+<ul>
+<li>
+<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v4</a> (Apache License v2)</li>
+<li>
+<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v7 'appcompat'</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/emilsjolander/StickyListHeaders">StickyListHeaders</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/Bearded-Hen/Android-Bootstrap">Android-Bootstrap</a> (MIT License)</li>
+<li>
+<a href="http://code.google.com/p/zxing/">ZXing</a> (Apache License v2)</li>
+<li>
+<a href="http://rtyley.github.com/spongycastle/">SpongyCastle</a> (MIT X11 License)</li>
+<li>
+<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
+</ul>
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_changelog.html
new file mode 100644
index 000000000..abf660ba8
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_changelog.html
@@ -0,0 +1,108 @@
+<html>
+<head></head>
+<body>
+<h2>2.3</h2>
+<ul>
+<li>remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)</li>
+<li>fix setting expiry dates on keys (thanks to Ash Hughes)</li>
+<li>more internal fixes when editing keys (thanks to Ash Hughes)</li>
+<li>querying keyservers directly from the import screen</li>
+<li>fix layout and dialog style on Android 2.2-3.0</li>
+<li>fix crash on keys with empty user ids</li>
+<li>fix crash and empty lists when coming back from signing screen</li>
+<li>Bouncy Castle (cryptography library) updated from 1.47 to 1.50 and build from source</li>
+<li>fix upload of key from signing screen</li>
+</ul>
+<h2>2.2</h2>
+<ul>
+<li>new design with navigation drawer</li>
+<li>new public key list design</li>
+<li>new public key view</li>
+<li>bug fixes for importing of keys</li>
+<li>key cross-certification (thanks to Ash Hughes)</li>
+<li>handle UTF-8 passwords properly (thanks to Ash Hughes)</li>
+<li>first version with new languages (thanks to the contributors on Transifex)</li>
+<li>sharing of keys via QR Codes fixed and improved</li>
+<li>package signature verification for API</li>
+</ul>
+<h2>2.1.1</h2>
+<ul>
+<li>API Updates, preparation for K-9 Mail integration</li>
+</ul>
+<h2>2.1</h2>
+<ul>
+<li>lots of bug fixes</li>
+<li>new API for developers</li>
+<li>PRNG bug fix by Google</li>
+</ul>
+<h2>2.0</h2>
+<ul>
+<li>complete redesign</li>
+<li>share public keys via qr codes, nfc beam</li>
+<li>sign keys</li>
+<li>upload keys to server</li>
+<li>fixes import issues</li>
+<li>new AIDL API</li>
+</ul>
+<h2>1.0.8</h2>
+<ul>
+<li>basic keyserver support</li>
+<li>app2sd</li>
+<li>more choices for pass phrase cache: 1, 2, 4, 8, hours</li>
+<li>translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)</li>
+<li>bugfixes</li>
+<li>optimizations</li>
+</ul>
+<h2>1.0.7</h2>
+<ul>
+<li>fixed problem with signature verification of texts with trailing newline</li>
+<li>more options for pass phrase cache time to live (20, 40, 60 mins)</li>
+</ul>
+<h2>1.0.6</h2>
+<ul>
+<li>account adding crash on Froyo fixed</li>
+<li>secure file deletion</li>
+<li>option to delete key file after import</li>
+<li>stream encryption/decryption (gallery, etc.)</li>
+<li>new options (language, force v3 signatures)</li>
+<li>interface changes</li>
+<li>bugfixes</li>
+</ul>
+<h2>1.0.5</h2>
+<ul>
+<li>German and Italian translation</li>
+<li>much smaller package, due to reduced BC sources</li>
+<li>new preferences GUI</li>
+<li>layout adjustment for localization</li>
+<li>signature bugfix</li>
+</ul>
+<h2>1.0.4</h2>
+<ul>
+<li>fixed another crash caused by some SDK bug with query builder</li>
+</ul>
+<h2>1.0.3</h2>
+<ul>
+<li>fixed crashes during encryption/signing and possibly key export</li>
+</ul>
+<h2>1.0.2</h2>
+<ul>
+<li>filterable key lists</li>
+<li>smarter pre-selection of encryption keys</li>
+<li>new Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers</li>
+<li>fixes and additional features (key preselection) for K-9 Mail, new beta build available</li>
+</ul>
+<h2>1.0.1</h2>
+<ul>
+<li>GMail account listing was broken in 1.0.0, fixed again</li>
+</ul>
+<h2>1.0.0</h2>
+<ul>
+<li>K-9 Mail integration, APG supporting beta build of K-9 Mail</li>
+<li>support of more file managers (including ASTRO)</li>
+<li>Slovenian translation</li>
+<li>new database, much faster, less memory usage</li>
+<li>defined Intents and content provider for other apps</li>
+<li>bugfixes</li>
+</ul>
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_nfc_beam.html
new file mode 100644
index 000000000..88492731c
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_nfc_beam.html
@@ -0,0 +1,12 @@
+<html>
+<head></head>
+<body>
+<h2>How to receive keys</h2>
+<ol>
+<li>Go to your partners contacts and open the contact you want to share.</li>
+<li>Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.</li>
+<li>After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
+<li>Tap the card and the content will then load on the your device.</li>
+</ol>
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_start.html b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_start.html
new file mode 100644
index 000000000..0e60c17a7
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_start.html
@@ -0,0 +1,19 @@
+<html>
+<head></head>
+<body>
+<h2>Getting started</h2>
+<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+
+<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+
+<h2>I found a bug in OpenKeychain!</h2>
+<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
+
+<h2>Contribute</h2>
+<p>If you want to help us developing OpenKeychain by contributing code <a href="https://github.com/openpgp-keychain/openpgp-keychain#contribute-code">follow our small guide on Github</a>.</p>
+
+<h2>Translations</h2>
+<p>Help translating OpenKeychain! Everybody can participate at <a href="https://www.transifex.com/projects/p/openpgp-keychain/">OpenKeychain on Transifex</a>.</p>
+
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/nfc_beam_share.html
new file mode 100644
index 000000000..083e055c7
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/nfc_beam_share.html
@@ -0,0 +1,11 @@
+<html>
+<head></head>
+<body>
+<ol>
+<li>Make sure that NFC is turned on in Settings &gt; More &gt; NFC and make sure that Android Beam is also on in the same section.</li>
+<li>Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.</li>
+<li>After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
+<li>Tap the card and the content will then load on the other person’s device.</li>
+</ol>
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_about.html b/OpenPGP-Keychain/src/main/res/raw-de/help_about.html
index 37d4193f7..676c2bdd2 100644
--- a/OpenPGP-Keychain/src/main/res/raw-de/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-de/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (crypto patches)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Entwickler APG 1.x</h2>
<ul>
-<li>'Thialfihar' (Leitender Entwickler)</li>
+<li>Thialfihar (Leitender Entwickler)</li>
<li>'Senecaso' (QR-Code, Schlüssel signtieren, Schlüssel hochladen)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>Bibliotheken</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache Lizenz v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Bibliothek</a> (Apache Lizenz v2)</li>
-<li>Icons von <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike Lizenz 3.0)</li>
-<li>Icons von <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html
index 1197869b5..e414324d0 100644
--- a/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html
+++ b/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html
@@ -8,7 +8,7 @@
<li>more internal fixes when editing keys (thanks to Ash Hughes)</li>
<li>querying keyservers directly from the import screen</li>
<li>fix layout and dialog style on Android 2.2-3.0</li>
-<li>fix crash on keys with empty user ids</li>
+<li>Absturz bei leeren Nutzer IDs behoben </li>
<li>fix crash and empty lists when coming back from signing screen</li>
<li>Bouncy Castle (cryptography library) updated from 1.47 to 1.50 and build from source</li>
<li>fix upload of key from signing screen</li>
@@ -38,15 +38,15 @@
<h2>2.0</h2>
<ul>
<li>Komlett neu designd</li>
-<li>share public keys via qr codes, nfc beam</li>
+<li>Öffentliche Schlüssel teilen via QR Code, NFC Beam</li>
<li>Schlüssel signieren</li>
<li>Schlüssel auf den Server hochladen</li>
-<li>fixes import issues</li>
+<li>Importprobleme behoben</li>
<li>new AIDL API</li>
</ul>
<h2>1.0.8</h2>
<ul>
-<li>basic keyserver support</li>
+<li>Grundlegende Schlüsselserverunterstützung</li>
<li>app2sd</li>
<li>mehr Auswahlmöglichkeiten für den Passwortcache: 1, 2, 4, 8, Stunden</li>
<li>Übersetzungen: norwegisch (Danke, Sander Danielsen), chinesisch (danke, Zhang Fredrick)</li>
@@ -98,8 +98,8 @@
<h2>1.0.0</h2>
<ul>
<li>K-9 Mail integration, APG supporting beta build of K-9 Mail</li>
-<li>support of more file managers (including ASTRO)</li>
-<li>Slovenian translation</li>
+<li>Unterstützung von mehr Filemanagern (einschließlich ASTRO)</li>
+<li>Slowenische Übersetzung</li>
<li>Neue Datenbank, viel schneller, weniger Speicherbedarf</li>
<li>defined Intents and content provider for other apps</li>
<li>Fehlerbehebungen</li>
diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html
index d2735f739..7a652682e 100644
--- a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html
@@ -1,15 +1,15 @@
<html>
<head></head>
<body>
-<h2>Getting started</h2>
-<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+<h2>Los gehts</h2>
+<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
<h2>Ich habe einen Fehler in OpenKeychain gefunden!</h2>
<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
-<h2>Contribute</h2>
+<h2>Unterstützen</h2>
<p>If you want to help us developing OpenKeychain by contributing code <a href="https://github.com/openpgp-keychain/openpgp-keychain#contribute-code">follow our small guide on Github</a>.</p>
<h2>Übersetzungen</h2>
diff --git a/OpenPGP-Keychain/src/main/res/raw-el/help_about.html b/OpenPGP-Keychain/src/main/res/raw-el/help_about.html
index 863aeee58..d9150a5e8 100644
--- a/OpenPGP-Keychain/src/main/res/raw-el/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-el/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (crypto patches)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Developers APG 1.x</h2>
<ul>
-<li>'Thialfihar' (Lead developer)</li>
+<li>Thialfihar (Lead developer)</li>
<li>'Senecaso' (QRCode, sign key, upload key)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>Libraries</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
-<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li>
-<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-el/help_start.html b/OpenPGP-Keychain/src/main/res/raw-el/help_start.html
index 3a6443a2f..0e60c17a7 100644
--- a/OpenPGP-Keychain/src/main/res/raw-el/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-el/help_start.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Getting started</h2>
-<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
diff --git a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html
index 863aeee58..d9150a5e8 100644
--- a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (crypto patches)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Developers APG 1.x</h2>
<ul>
-<li>'Thialfihar' (Lead developer)</li>
+<li>Thialfihar (Lead developer)</li>
<li>'Senecaso' (QRCode, sign key, upload key)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>Libraries</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
-<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li>
-<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html
index 3a6443a2f..0e60c17a7 100644
--- a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Getting started</h2>
-<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_about.html b/OpenPGP-Keychain/src/main/res/raw-es/help_about.html
index 95189425d..552155d68 100644
--- a/OpenPGP-Keychain/src/main/res/raw-es/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-es/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (Parches cryptográficos)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Desarrolladores de APG 1.x</h2>
<ul>
-<li>'Thialfihar' (Desarrollador principal)</li>
+<li>Thialfihar (Desarrollador principal)</li>
<li>'Senecaso' (Código QR, clave de firma, carga de clave)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>Librerías</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Licencia Apache v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Librería Android AppMsg</a> (Licencia Apache v2)</li>
-<li>Icons de <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Compartir-Igual licencia 3.0)</li>
-<li>Iconos de <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Dominio Público)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_start.html b/OpenPGP-Keychain/src/main/res/raw-es/help_start.html
index 2907bbc99..895b52469 100644
--- a/OpenPGP-Keychain/src/main/res/raw-es/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-es/help_start.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Primeros pasos</h2>
-<p>Primero necesitas un par de claves personales. Crea una a través del menú "Mis claves" o importa un par de claves ya existentes a través de "Importar claves". Después, puedes descargar las claves de tus amigos o intercambiarlas a través de códigos QR o NFC.</p>
+<p>Primero necesitas un par de claves personales. Crea una a través del menú "Contactos" o importa un par de claves ya existentes a través de "Importar claves". Después, puedes descargar las claves de tus amigos o intercambiarlas a través de códigos QR o NFC.</p>
<p>Es recomendable que instales <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> para una mejor selección de archivos y <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> para escanear los códigos QR generados. Pulsando en los enlaces se abrirá Google Play o F-Droid.</p>
diff --git a/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_about.html b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_about.html
index 863aeee58..d9150a5e8 100644
--- a/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (crypto patches)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Developers APG 1.x</h2>
<ul>
-<li>'Thialfihar' (Lead developer)</li>
+<li>Thialfihar (Lead developer)</li>
<li>'Senecaso' (QRCode, sign key, upload key)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>Libraries</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
-<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li>
-<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-fr/help_about.html b/OpenPGP-Keychain/src/main/res/raw-fr/help_about.html
index 3cbbce4d5..43094ce9d 100644
--- a/OpenPGP-Keychain/src/main/res/raw-fr/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-fr/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (correctif crypto)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar « kalkin » Gadimov (interface utilisateur)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Les développeurs d'APG 1.x</h2>
<ul>
-<li>« Thialfihar (développeur principal)</li>
+<li>Thialfihar (développeur principal)</li>
<li>« Senecaso » (Code QR, signer/téléverser la clef)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>Bibliothèques</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Licence Apache v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Bibliothèque Android AppMsg</a> (Licence Apache v2)</li>
-<li>Icônes du <a href="http://rrze-icon-set.berlios.de/">jeu d'icônes RRZE</a> (Licence Creative Commons Paternité - Partage des Conditions Initiales à l'Identique 3.0)</li>
-<li>Icônes du <a href="http://tango.freedesktop.org/">jeu d'icônes Tango</a> (domaine public)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html b/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html
index 0c1610f0c..962c33d86 100644
--- a/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Commencer</h2>
-<p>Vous avez d'abord besoin d'une paire de clefs personelles. Créez-en une avec l'option du menu « Mes clefs » ou importez des paires de clefs existantes avec « Importer des clefs ». Ensuite vous pouvez télécharger les clefs de vos amis, ou les échanger par codes QR ou NFC.</p>
+<p>Vous avez d'abord besoin d'une paire de clefs personelles. Créez-en une avec l'option du menu « Contacts » ou importez des paires de clefs existantes avec « Importer des clefs ». Ensuite vous pouvez télécharger les clefs de vos amis, ou les échanger par codes QR ou NFC.</p>
<p>Il vous est recommendé d'installer le <a href="market://details?id=org.openintents.filemanager">gestionnaire de fichiers OI</a> pour sa fonction améliorée de séléction des fichiers et le <a href="market://details?id=com.google.zxing.client.android">lecteur de codes à barres</a> pour balayer les codes QR générés. Cliquer sur les liens ouvrira Google Play Store ou F-Droid pour l'installation.</p>
diff --git a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html
index ba0676f3e..2d17e1882 100644
--- a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (Patch crittografia)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (Interfaccia Utente)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Sviluppatori APG 1.x</h2>
<ul>
-<li>'Thialfihar' (Capo Sviluppatore)</li>
+<li>Thialfihar (Capo Sviluppatore)</li>
<li>'Senecaso' (QRCode, firma chiavi, caricamento chiavi)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>Librerie</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Licenza Apache v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Licenza Apache v2)</li>
-<li>Icone da <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Licenza Creative Commons Attribution Share-Alike 3.0)</li>
-<li>Icone da <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Pubblico Dominio)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html
index 4eadd82fc..1a4a7303e 100644
--- a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Per iniziare</h2>
-<p>Per prima cosa hai bisogno di un paio di chiavi personali. Creane una tramite i menu di opzione sotto 'Mie Chiavi' o importane di esistenti attraverso "Importa Chiavi". Dopodiche' puoi scaricare le chiavi dei tuoi amici o scambiarle tramite Codici QR o NFC.</p>
+<p>Per prima cosa hai bisogno di un paio di chiavi personali. Creane una tramite i menu di opzione sotto 'Contatti' o importane di esistenti attraverso "Importa Chiavi". Dopodiche' puoi scaricare le chiavi dei tuoi amici o scambiarle tramite Codici QR o NFC.</p>
<p>Si raccomanda di installare <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> per una migliore selezione dei file e <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> per scansionare i codici QR. I collegamenti verranno aperti in Google Play Store o F-Droid per l'installazione.</p>
diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html b/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html
index 206fc9f8d..3f630264c 100644
--- a/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (暗号関係パッチ提供)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>APG 1.xの開発者達</h2>
<ul>
-<li>'Thialfihar' (主任開発者)</li>
+<li>Thialfihar (主任開発者)</li>
<li>'Senecaso' (QRコード, 鍵署名, 鍵アップロード関係)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>ライブラリ</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
-<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li>
-<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (パブリックドメイン)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html b/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html
index 9764e876a..04ad31352 100644
--- a/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>入門</h2>
-<p>最初にあなたの個人用鍵ペアが必要になります。オプションメニューの"自分の鍵"で生成するか、"鍵のインポート"から既存の鍵ペアをインポートします。その後、あなたの友人の鍵をダウンロード、もしくはQRコードやNFCで交換します。</p>
+<p>最初にあなたの個人用鍵ペアが必要になります。オプションメニューの"連絡先"で生成するか、"鍵のインポート"から既存の鍵ペアをインポートします。その後、あなたの友人の鍵をダウンロード、もしくはQRコードやNFCで交換します。</p>
<p>ファイルの選択を拡張するには<a href="market://details?id=org.openintents.filemanager">OI File Manager</a>、<a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>を生成したQRコードのスキャンのため、それぞれのインストールを必要とします。 リンクをクリックして、Google Play Store上かF-Droidからインストールしてください。</p>
diff --git a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html
index 863aeee58..d9150a5e8 100644
--- a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (crypto patches)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Developers APG 1.x</h2>
<ul>
-<li>'Thialfihar' (Lead developer)</li>
+<li>Thialfihar (Lead developer)</li>
<li>'Senecaso' (QRCode, sign key, upload key)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>Libraries</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
-<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li>
-<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html
index 3a6443a2f..0e60c17a7 100644
--- a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Getting started</h2>
-<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
diff --git a/OpenPGP-Keychain/src/main/res/raw-pl/help_about.html b/OpenPGP-Keychain/src/main/res/raw-pl/help_about.html
new file mode 100644
index 000000000..c41859b60
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-pl/help_about.html
@@ -0,0 +1,48 @@
+<html>
+<head></head>
+<body>
+<p><a href="http://www.openkeychain.org">http://www.openkeychain.org</a></p>
+<p><a href="http://www.openkeychain.org">OpenKeychain</a> to implementacja OpenPGP na platformę Android.</p>
+<p>Licencja: GPLv3+</p>
+
+<h2>Deweloperzy OpenKeychain</h2>
+<ul>
+<li>Dominik Schürmann (Wiodący developer)</li>
+<li>Ash Hughes (łatki crypto)</li>
+<li>Brian C. Barnes</li>
+<li>Bahtiar 'kalkin' Gadimov (Interfejs Użytkownika)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
+
+</ul>
+<h2>Deweloperzy APG 1.x</h2>
+<ul>
+<li>Thialfihar (Wiodacy deweloper)</li>
+<li>'Senecaso' (kody QR, podpisy kluczy, wysyłanie kluczy)</li>
+<li>Markus Doits</li>
+</ul>
+<h2>Biblioteki</h2>
+<ul>
+<li>
+<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v4</a> (Licencja Apache v2)</li>
+<li>
+<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v7 'appcompat'</a> (Licencja Apache v2)</li>
+<li>
+<a href="https://github.com/emilsjolander/StickyListHeaders">StickyListHeaders</a> (Licencja Apache v2)</li>
+<li>
+<a href="https://github.com/Bearded-Hen/Android-Bootstrap">Android-Bootstrap</a> (Licencja MIT)</li>
+<li>
+<a href="http://code.google.com/p/zxing/">ZXing</a> (Licencja Apache v2)</li>
+<li>
+<a href="http://rtyley.github.com/spongycastle/">SpongyCastle</a> (Licencja MIT X11)</li>
+<li>
+<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Licencja Apache v2)</li>
+<li>
+<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Licencja Apache v2)</li>
+</ul>
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-pl/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-pl/help_changelog.html
new file mode 100644
index 000000000..cdf124d3a
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-pl/help_changelog.html
@@ -0,0 +1,108 @@
+<html>
+<head></head>
+<body>
+<h2>2.3</h2>
+<ul>
+<li>usunięto zbędne eksportowanie kluczy publicznych przy eksportowaniu kluczy prywatnych (podziękowania dla Ash Hughes)</li>
+<li>naprawiono błąd z ustawianiem daty wygaśnięcia kluczy (podziękowania dla Ash Hugens)</li>
+<li>więcej wewnętrznych poprawek przy edytowaniu kluczy (podziękowania dla Ash Hughes)</li>
+<li>wysyłanie zapytań do serwera kluczy bezpośrednio z ekranu importu</li>
+<li>poprawiony wygląd interfejsu i okienek na Androidzie 2.2-3.0</li>
+<li>naprawiono awarię programu dla kluczy z pustym identyfikatorem użytkownika</li>
+<li>naprawiono awarię aplikacji przy powrocie z ekranu podpisywania</li>
+<li>Bouncy Castle (biblioteka kryptograficzna) zaktualizowana z wersji 1.47 do 1.50 i kompilowana ze źródeł</li>
+<li>naprawiony błąd przy wysyłaniu klucza z ekranu podpisywania</li>
+</ul>
+<h2>2.2</h2>
+<ul>
+<li>nowy wygląd z panelem nawigacji</li>
+<li>nowy wygląd listy kluczy publicznych</li>
+<li>nowy widok klucza publicznego</li>
+<li>naprawiono błędy związane z importowaniem kluczy</li>
+<li>krzyżowa certyfikacja kluczy (podziękowania dla Ash Hughes)</li>
+<li>hasła zapisane w UTF-8 są teraz prawidłowo obsługiwane (podziękowania dla Ash Hughes)</li>
+<li>pierwsza wersja z nowymi językami (podziękowania dla tłumaczy-wolontariuszy z Transifex)</li>
+<li>udostępnianie kluczy przez kody QR zostało poprawione i ulepszone</li>
+<li>weryfikacja podpisu paczki dla API</li>
+</ul>
+<h2>2.1.1</h2>
+<ul>
+<li>aktualizacje API, przygotowanie do integracji z K-9 Mail</li>
+</ul>
+<h2>2.1</h2>
+<ul>
+<li>wiele poprawek błędów</li>
+<li>nowe API dla programistów</li>
+<li>Naprawiono błąd generatora liczb losowych (PRNG), Google.</li>
+</ul>
+<h2>2.0</h2>
+<ul>
+<li>kompletna przebudowa</li>
+<li>udostępnianie kluczy publicznych przez kody QR oraz NFC</li>
+<li>możliwość podpisywania kluczem</li>
+<li>wysyłanie kluczy na serwer</li>
+<li>naprawiono problemy związane z importowaniem</li>
+<li>nowy AIDL API</li>
+</ul>
+<h2>1.0.8</h2>
+<ul>
+<li>podstawowa obsługa serwerów kluczy</li>
+<li>app2sd</li>
+<li>dodano więcej przedziałów czasowych zapamiętywania hasła: 1, 2, 4, 8 godzin</li>
+<li>tłumaczenia: norweski (podziękowania dla Sander Danielsen), chiński (podziękowania dla Zhang Fredrick)</li>
+<li>naprawione błędy</li>
+<li>usprawnienia</li>
+</ul>
+<h2>1.0.7</h2>
+<ul>
+<li>naprawiono problem z weryfikowaniem podpisu tekstów kończących się znakiem nowej linii</li>
+<li>dodano więcej przedziałów czasowych zapamiętywania hasła (20, 40, 60 minut)</li>
+</ul>
+<h2>1.0.6</h2>
+<ul>
+<li>naprawiono błąd powodujący awarię aplikacji przy dodawaniu nowego konta na Androidzie 2.2 Froyo</li>
+<li>dodano bezpieczne usuwanie plików</li>
+<li>Dodano możliwość usuwania plików kluczy po zaimportowaniu</li>
+<li>możliwość strumieniowego szyfrowania/deszyfrowania (galeria i inne)</li>
+<li>nowe opcje (języki, wymuszanie podpisów v3)</li>
+<li>zmiany w interfejsie</li>
+<li>naprawione błędy</li>
+</ul>
+<h2>1.0.5</h2>
+<ul>
+<li>tłumaczenie na niemiecki i włoski</li>
+<li>znaczne zmniejszenie rozmiaru paczki, z powodu zredukowania źródeł BC</li>
+<li>nowy interfejs graficzny Właściwości</li>
+<li>usprawnienia wyglądu dla lokalizacji</li>
+<li>naprawa błędu z podpisami</li>
+</ul>
+<h2>1.0.4</h2>
+<ul>
+<li>naprawiono kolejny błąd powodujący awarię aplikacji, spowodowany przez jakąś usterkę w SDK przy budowaniu zapytań</li>
+</ul>
+<h2>1.0.3</h2>
+<ul>
+<li>naprawiono błąd w trakcie szyfrowania/podpisywania i prawdopodobnie eksportowania klucza</li>
+</ul>
+<h2>1.0.2</h2>
+<ul>
+<li>dodano możliwość filtrowania listy kluczy</li>
+<li>sprytniejsze automatyczne wybieranie kluczy szyfrujących</li>
+<li>dodano nowy sposób obsługi intencji "wyświetl" i "wyślij", umożliwia szyfrowanie/deszyfrowanie plików wprost z menadżera plików.</li>
+<li>poprawki i dodatkowe funkcje (podpowiedź wyboru klucza) dla K-9 Mail, nowe wydanie beta dostępne</li>
+</ul>
+<h2>1.0.1</h2>
+<ul>
+<li>wyświetlanie kont w GMailu było zepsute w 1.0.0, naprawiono je ponownie</li>
+</ul>
+<h2>1.0.0</h2>
+<ul>
+<li>integracja z K-9 Mail, APG obsługuje wersję beta K-9 Mail</li>
+<li>dodano wsparcie dla większej liczby menadżerów plików (włącznie z ASTRO)</li>
+<li>tłumaczenie na słoweński</li>
+<li>Wykorzystanie nowej bazy danych, która jest znacznie szybsza i mniej pamięciożerna</li>
+<li>zdefiniowano intecję i dostawców treści dla pozostałych aplikacji</li>
+<li>naprawione błędy</li>
+</ul>
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-pl/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-pl/help_nfc_beam.html
new file mode 100644
index 000000000..53db5e80c
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-pl/help_nfc_beam.html
@@ -0,0 +1,12 @@
+<html>
+<head></head>
+<body>
+<h2>Jak odbierać klucze</h2>
+<ol>
+<li>Wejdź do listy kontaktów Twojego partnera i otwórz kontakt, który chcesz przesłać.</li>
+<li>Przytrzymaj oba urządzenia plecami do siebie (powinny się niemal dotykać) i poczujesz wibrację.</li>
+<li>Po zakończeniu wibracji zobaczysz, że zawartość urządzenia partnera zamienia się w obiekt zbliżony do wizytówki, z animacją rodem ze Star Treka w tle.</li>
+<li>Dotknij wizytówkę, a jej zawartość zostanie wysłana na Twoje urządzenie.</li>
+</ol>
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-pl/help_start.html b/OpenPGP-Keychain/src/main/res/raw-pl/help_start.html
new file mode 100644
index 000000000..d2faa2db9
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-pl/help_start.html
@@ -0,0 +1,19 @@
+<html>
+<head></head>
+<body>
+<h2>Pierwsze kroki</h2>
+<p>Po pierwsze potrzebujesz swoją osobistą parę kluczy. Stwórz ją, korzystając z odpowiedniej opcji w sekcji "Kontakty" lub też zaimportuj istniejącą parę korzystając z sekcji "Importuj klucze". Następnie możesz pobrać klucze Twoich znajomych lub wymieniać się z nimi za pośrednictwem kodów QR lub technologii NFC.</p>
+
+<p>Zalecana jest instalacja menadżera plików <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> w celu zapewnienia wygodniejszego wyboru plików oraz programu <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>, który jest w stanie skanować wygenerowane kody QR. Kliknięcie na powyższe linki przekieruje Cię do sklepu Google Play / F-Droid.</p>
+
+<h2>Znalazłem błąd w OpenKeychain!</h2>
+<p>Zgłoś błąd korzystając z <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">systemu śledzenia błędów OpenKeychain</a>.</p>
+
+<h2>Wkład</h2>
+<p>Jeżeli chcesz pomóc nam rozwijać OpenKeychain jako programista, <a href="https://github.com/openpgp-keychain/openpgp-keychain#contribute-code">zapoznaj się z naszym małym poradnikiem na Githubie</a>.</p>
+
+<h2>Tłumaczenia</h2>
+<p>Pomóż przetłumaczyć OpenKeychain! Każdy może wziąć udział przez stronę <a href="https://www.transifex.com/projects/p/openpgp-keychain/">OpenKeychain w serwisie Transifex</a>.</p>
+
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-pl/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-pl/nfc_beam_share.html
new file mode 100644
index 000000000..f17e44079
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-pl/nfc_beam_share.html
@@ -0,0 +1,11 @@
+<html>
+<head></head>
+<body>
+<ol>
+<li>Upewnij się, że NFC (Near Field Communication, pol.: komunikacja bliskiego zasięgu) jest włączone. W tym celu wejdź w Ustawienia &gt; Inne &gt; NFC. Upewnij się również, że włączona jest funkcja Android Beam (znajduje się w tym samym miejscu).</li>
+<li>Przytrzymaj oba urządzenia plecami do siebie (powinny się niemal dotykać) i poczujesz wibrację.</li>
+<li>Po zakończeniu wibracji zobaczysz, że zawartość urządzenia partnera zamienia się w obiekt zbliżony do wizytówki, z animacją rodem ze Star Treka w tle.</li>
+<li>Dotknij wizytówkę, a jej zawartość zostanie wysłana na urządzenie drugiej osoby.</li>
+</ol>
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html
index 863aeee58..d9150a5e8 100644
--- a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (crypto patches)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Developers APG 1.x</h2>
<ul>
-<li>'Thialfihar' (Lead developer)</li>
+<li>Thialfihar (Lead developer)</li>
<li>'Senecaso' (QRCode, sign key, upload key)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>Libraries</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
-<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li>
-<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html
index 3a6443a2f..0e60c17a7 100644
--- a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Getting started</h2>
-<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
diff --git a/OpenPGP-Keychain/src/main/res/raw-ru/help_about.html b/OpenPGP-Keychain/src/main/res/raw-ru/help_about.html
index 655e98758..63335110e 100644
--- a/OpenPGP-Keychain/src/main/res/raw-ru/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-ru/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (патчи криптографии)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Разработчики APG 1.x</h2>
<ul>
-<li>'Thialfihar' (главный разработчик)</li>
+<li>Thialfihar (главный разработчик)</li>
<li>'Senecaso' (QR коды, подписание и загрузка ключей)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>Компоненты</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Библиотека Android AppMsg</a> (Apache License v2)</li>
-<li>Иконки <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li>
-<li>Иконки <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html b/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html
index 9b2b99e96..bc9dade67 100644
--- a/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Приступая</h2>
-<p>Для начала вам понадобится своя пара ключей. Воспользуйтесь меню в разделе "Мои ключи", что бы создать новую, или добавьте ранее созданную пару в разделе "Импорт ключей". После этого вы сможете скачать ключи ваших друзей или обменяться ключами посредством QR кодов или NFC.</p>
+<p>Для начала вам понадобится своя пара ключей. Воспользуйтесь меню в разделе "Контакты", что бы создать новую, или добавьте ранее созданную пару в разделе "Импорт ключей". После этого вы сможете скачать ключи ваших друзей или обменяться ключами посредством QR кодов или NFC.</p>
<p>Рекомендуется установить <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> для удобного выбора файлов и <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> для распознавания QR кодов. Перейдите по ссылкам на соответствующие страницы Google Play или F-Droid для дальнейшей установки.</p>
diff --git a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html
index 863aeee58..d9150a5e8 100644
--- a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (crypto patches)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Developers APG 1.x</h2>
<ul>
-<li>'Thialfihar' (Lead developer)</li>
+<li>Thialfihar (Lead developer)</li>
<li>'Senecaso' (QRCode, sign key, upload key)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>Libraries</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
-<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li>
-<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html
index 3a6443a2f..0e60c17a7 100644
--- a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Getting started</h2>
-<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
diff --git a/OpenPGP-Keychain/src/main/res/raw-tr/help_about.html b/OpenPGP-Keychain/src/main/res/raw-tr/help_about.html
index eb262b242..d50154765 100644
--- a/OpenPGP-Keychain/src/main/res/raw-tr/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-tr/help_about.html
@@ -11,13 +11,18 @@
<li>Ash Hughes (kripto yamaları)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (Arayüz)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Geliştiriciler APG 1.x</h2>
<ul>
-<li>'Thialfihar' (Baş geliştirici)</li>
+<li>Thialfihar (Baş geliştirici)</li>
<li>'Senecaso' (QR Kodu, anahtar imzalama, anahtar yükleme)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
<h2>Kütüphaneler</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
-<li>İkonlar <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li>
-<li>İkonlar <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html b/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html
index 3a6443a2f..0e60c17a7 100644
--- a/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Getting started</h2>
-<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
diff --git a/OpenPGP-Keychain/src/main/res/raw-uk/help_about.html b/OpenPGP-Keychain/src/main/res/raw-uk/help_about.html
index c8a5a82c5..4e6bb02dd 100644
--- a/OpenPGP-Keychain/src/main/res/raw-uk/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-uk/help_about.html
@@ -11,13 +11,18 @@
<li>Аш Гюдж (латки шифрування)</li>
<li>Браян С. Барнс</li>
<li>Бахтіяр 'kalkin' Ґадімов (інтерфейс)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Розробники APG 1.x</h2>
<ul>
-<li>'Thialfihar' (основний розробник)</li>
+<li>Thialfihar (основний розробник)</li>
<li>'Senecaso' (штрих-код, підпис і завантаження ключів)</li>
-<li>Олівер Ранж</li>
<li>Маркус Дойтс</li>
</ul>
<h2>Бібліотеки</h2>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (ліцензія Apache в.2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Бібліотека Android AppMsg Library</a> (Ліцензія Apache в. 2)</li>
-<li>Піктограми із <a href="http://rrze-icon-set.berlios.de/">набору піктограм RRZE</a> (ліцензія Creative Commons - Із зазначенням авторства - Розповсюдження на тих самих умовах - версія 3.0)</li>
-<li>Піктограми із <a href="http://tango.freedesktop.org/">набору піктограм Tango</a> (відкритий домен)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html b/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html
index 3bfb40f8a..78443070d 100644
--- a/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Приступаючи до роботи</h2>
-<p>Спершу вам потрібна персональна в'язка ключів. Створіть одну через меню параметрів у "Мої Ключі" або імпортуйте наявні в'язки ключів через "Імпорт ключів". Після цього ви зможете завантажувати ключі ваших друзів чи обміняти їх через штрих-коди або NFC.</p>
+<p>Спершу вам потрібна персональна в'язка ключів. Створіть одну через меню параметрів у "Контакти" або імпортуйте наявні в'язки ключів через "Імпорт ключів". Після цього ви зможете завантажувати ключі ваших друзів чи обміняти їх через штрих-коди або NFC.</p>
<p>Рекомендуємо вам встановити <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> для поліпшеного виділення файлів та <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> для сканування згенерованих штрих-кодів. Натискання посилань відкриє Google Play або F-Droid для встановлення.</p>
diff --git a/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_about.html b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_about.html
new file mode 100644
index 000000000..d9150a5e8
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_about.html
@@ -0,0 +1,48 @@
+<html>
+<head></head>
+<body>
+<p><a href="http://www.openkeychain.org">http://www.openkeychain.org</a></p>
+<p><a href="http://www.openkeychain.org">OpenKeychain</a> is an OpenPGP implementation for Android.</p>
+<p>License: GPLv3+</p>
+
+<h2>Developers OpenKeychain</h2>
+<ul>
+<li>Dominik Schürmann (Lead developer)</li>
+<li>Ash Hughes (crypto patches)</li>
+<li>Brian C. Barnes</li>
+<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
+
+</ul>
+<h2>Developers APG 1.x</h2>
+<ul>
+<li>Thialfihar (Lead developer)</li>
+<li>'Senecaso' (QRCode, sign key, upload key)</li>
+<li>Markus Doits</li>
+</ul>
+<h2>Libraries</h2>
+<ul>
+<li>
+<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v4</a> (Apache License v2)</li>
+<li>
+<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v7 'appcompat'</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/emilsjolander/StickyListHeaders">StickyListHeaders</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/Bearded-Hen/Android-Bootstrap">Android-Bootstrap</a> (MIT License)</li>
+<li>
+<a href="http://code.google.com/p/zxing/">ZXing</a> (Apache License v2)</li>
+<li>
+<a href="http://rtyley.github.com/spongycastle/">SpongyCastle</a> (MIT X11 License)</li>
+<li>
+<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
+</ul>
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_changelog.html
new file mode 100644
index 000000000..abf660ba8
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_changelog.html
@@ -0,0 +1,108 @@
+<html>
+<head></head>
+<body>
+<h2>2.3</h2>
+<ul>
+<li>remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)</li>
+<li>fix setting expiry dates on keys (thanks to Ash Hughes)</li>
+<li>more internal fixes when editing keys (thanks to Ash Hughes)</li>
+<li>querying keyservers directly from the import screen</li>
+<li>fix layout and dialog style on Android 2.2-3.0</li>
+<li>fix crash on keys with empty user ids</li>
+<li>fix crash and empty lists when coming back from signing screen</li>
+<li>Bouncy Castle (cryptography library) updated from 1.47 to 1.50 and build from source</li>
+<li>fix upload of key from signing screen</li>
+</ul>
+<h2>2.2</h2>
+<ul>
+<li>new design with navigation drawer</li>
+<li>new public key list design</li>
+<li>new public key view</li>
+<li>bug fixes for importing of keys</li>
+<li>key cross-certification (thanks to Ash Hughes)</li>
+<li>handle UTF-8 passwords properly (thanks to Ash Hughes)</li>
+<li>first version with new languages (thanks to the contributors on Transifex)</li>
+<li>sharing of keys via QR Codes fixed and improved</li>
+<li>package signature verification for API</li>
+</ul>
+<h2>2.1.1</h2>
+<ul>
+<li>API Updates, preparation for K-9 Mail integration</li>
+</ul>
+<h2>2.1</h2>
+<ul>
+<li>lots of bug fixes</li>
+<li>new API for developers</li>
+<li>PRNG bug fix by Google</li>
+</ul>
+<h2>2.0</h2>
+<ul>
+<li>complete redesign</li>
+<li>share public keys via qr codes, nfc beam</li>
+<li>sign keys</li>
+<li>upload keys to server</li>
+<li>fixes import issues</li>
+<li>new AIDL API</li>
+</ul>
+<h2>1.0.8</h2>
+<ul>
+<li>basic keyserver support</li>
+<li>app2sd</li>
+<li>more choices for pass phrase cache: 1, 2, 4, 8, hours</li>
+<li>translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)</li>
+<li>bugfixes</li>
+<li>optimizations</li>
+</ul>
+<h2>1.0.7</h2>
+<ul>
+<li>fixed problem with signature verification of texts with trailing newline</li>
+<li>more options for pass phrase cache time to live (20, 40, 60 mins)</li>
+</ul>
+<h2>1.0.6</h2>
+<ul>
+<li>account adding crash on Froyo fixed</li>
+<li>secure file deletion</li>
+<li>option to delete key file after import</li>
+<li>stream encryption/decryption (gallery, etc.)</li>
+<li>new options (language, force v3 signatures)</li>
+<li>interface changes</li>
+<li>bugfixes</li>
+</ul>
+<h2>1.0.5</h2>
+<ul>
+<li>German and Italian translation</li>
+<li>much smaller package, due to reduced BC sources</li>
+<li>new preferences GUI</li>
+<li>layout adjustment for localization</li>
+<li>signature bugfix</li>
+</ul>
+<h2>1.0.4</h2>
+<ul>
+<li>fixed another crash caused by some SDK bug with query builder</li>
+</ul>
+<h2>1.0.3</h2>
+<ul>
+<li>fixed crashes during encryption/signing and possibly key export</li>
+</ul>
+<h2>1.0.2</h2>
+<ul>
+<li>filterable key lists</li>
+<li>smarter pre-selection of encryption keys</li>
+<li>new Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers</li>
+<li>fixes and additional features (key preselection) for K-9 Mail, new beta build available</li>
+</ul>
+<h2>1.0.1</h2>
+<ul>
+<li>GMail account listing was broken in 1.0.0, fixed again</li>
+</ul>
+<h2>1.0.0</h2>
+<ul>
+<li>K-9 Mail integration, APG supporting beta build of K-9 Mail</li>
+<li>support of more file managers (including ASTRO)</li>
+<li>Slovenian translation</li>
+<li>new database, much faster, less memory usage</li>
+<li>defined Intents and content provider for other apps</li>
+<li>bugfixes</li>
+</ul>
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_nfc_beam.html
new file mode 100644
index 000000000..88492731c
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_nfc_beam.html
@@ -0,0 +1,12 @@
+<html>
+<head></head>
+<body>
+<h2>How to receive keys</h2>
+<ol>
+<li>Go to your partners contacts and open the contact you want to share.</li>
+<li>Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.</li>
+<li>After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
+<li>Tap the card and the content will then load on the your device.</li>
+</ol>
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_start.html b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_start.html
new file mode 100644
index 000000000..0e60c17a7
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_start.html
@@ -0,0 +1,19 @@
+<html>
+<head></head>
+<body>
+<h2>Getting started</h2>
+<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+
+<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+
+<h2>I found a bug in OpenKeychain!</h2>
+<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
+
+<h2>Contribute</h2>
+<p>If you want to help us developing OpenKeychain by contributing code <a href="https://github.com/openpgp-keychain/openpgp-keychain#contribute-code">follow our small guide on Github</a>.</p>
+
+<h2>Translations</h2>
+<p>Help translating OpenKeychain! Everybody can participate at <a href="https://www.transifex.com/projects/p/openpgp-keychain/">OpenKeychain on Transifex</a>.</p>
+
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-zh-rTW/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/nfc_beam_share.html
new file mode 100644
index 000000000..083e055c7
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/nfc_beam_share.html
@@ -0,0 +1,11 @@
+<html>
+<head></head>
+<body>
+<ol>
+<li>Make sure that NFC is turned on in Settings &gt; More &gt; NFC and make sure that Android Beam is also on in the same section.</li>
+<li>Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.</li>
+<li>After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
+<li>Tap the card and the content will then load on the other person’s device.</li>
+</ol>
+</body>
+</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-zh/help_about.html b/OpenPGP-Keychain/src/main/res/raw-zh/help_about.html
index 863aeee58..1eec8bdbf 100644
--- a/OpenPGP-Keychain/src/main/res/raw-zh/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-zh/help_about.html
@@ -3,24 +3,29 @@
<body>
<p><a href="http://www.openkeychain.org">http://www.openkeychain.org</a></p>
<p><a href="http://www.openkeychain.org">OpenKeychain</a> is an OpenPGP implementation for Android.</p>
-<p>License: GPLv3+</p>
+<p>授權:GPLv3+</p>
<h2>Developers OpenKeychain</h2>
<ul>
<li>Dominik Schürmann (Lead developer)</li>
<li>Ash Hughes (crypto patches)</li>
<li>Brian C. Barnes</li>
-<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Bahtiar 'kalkin' Gadimov (介面)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Developers APG 1.x</h2>
<ul>
-<li>'Thialfihar' (Lead developer)</li>
+<li>Thialfihar (Lead developer)</li>
<li>'Senecaso' (QRCode, sign key, upload key)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
-<h2>Libraries</h2>
+<h2>函式庫</h2>
<ul>
<li>
<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v4</a> (Apache License v2)</li>
@@ -38,8 +43,6 @@
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
-<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li>
-<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-zh/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-zh/help_nfc_beam.html
index 88492731c..7a90a794b 100644
--- a/OpenPGP-Keychain/src/main/res/raw-zh/help_nfc_beam.html
+++ b/OpenPGP-Keychain/src/main/res/raw-zh/help_nfc_beam.html
@@ -1,12 +1,12 @@
<html>
<head></head>
<body>
-<h2>How to receive keys</h2>
+<h2>如何接收金要</h2>
<ol>
-<li>Go to your partners contacts and open the contact you want to share.</li>
-<li>Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.</li>
-<li>After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
-<li>Tap the card and the content will then load on the your device.</li>
+<li>前往你夥伴裝置上的聯絡人清單,並點選你要分享的聯絡人。</li>
+<li>將兩部裝置背對背貼近(幾乎接觸),你會感覺到一股震動。</li>
+<li>震動之後你會看見你夥伴的畫面變成卡片狀,並且背景帶有如 Star Trek 般的特效。</li>
+<li>輕觸卡片,內容隨即顯示在你的裝置上。</li>
</ol>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw-zh/help_start.html b/OpenPGP-Keychain/src/main/res/raw-zh/help_start.html
index 3a6443a2f..104bdd545 100644
--- a/OpenPGP-Keychain/src/main/res/raw-zh/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw-zh/help_start.html
@@ -1,18 +1,18 @@
<html>
<head></head>
<body>
-<h2>Getting started</h2>
-<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+<h2>快速上手</h2>
+<p>首先你需要屬於你個人的金鑰對,從〝我的金鑰〞選單中建立一個或是使用〝匯入金鑰〞匯入現有的金鑰對。在這之後,你可以下載你朋友的公鑰或者是透過二維條碼或NFC和他交換公鑰。</p>
<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
-<h2>I found a bug in OpenKeychain!</h2>
-<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
+<h2>我在OpenKeychain發現問題!</h2>
+<p>請利用 <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">OpenKeychain 項目回報系統</a>回報問題。</p>
-<h2>Contribute</h2>
+<h2>發布</h2>
<p>If you want to help us developing OpenKeychain by contributing code <a href="https://github.com/openpgp-keychain/openpgp-keychain#contribute-code">follow our small guide on Github</a>.</p>
-<h2>Translations</h2>
+<h2>翻譯</h2>
<p>Help translating OpenKeychain! Everybody can participate at <a href="https://www.transifex.com/projects/p/openpgp-keychain/">OpenKeychain on Transifex</a>.</p>
</body>
diff --git a/OpenPGP-Keychain/src/main/res/raw-zh/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-zh/nfc_beam_share.html
index 083e055c7..99ffe4c12 100644
--- a/OpenPGP-Keychain/src/main/res/raw-zh/nfc_beam_share.html
+++ b/OpenPGP-Keychain/src/main/res/raw-zh/nfc_beam_share.html
@@ -2,10 +2,10 @@
<head></head>
<body>
<ol>
-<li>Make sure that NFC is turned on in Settings &gt; More &gt; NFC and make sure that Android Beam is also on in the same section.</li>
-<li>Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.</li>
-<li>After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
-<li>Tap the card and the content will then load on the other person’s device.</li>
+<li>確定在 "設定" &gt; "更多內容…" &gt; "NFC" 裡面已經開啟 NFC 和 Android Beam。</li>
+<li>將兩部裝置背對背貼近(幾乎接觸),你會感覺到一股震動。</li>
+<li>震動之後你會看見你夥伴的畫面變成卡片狀,並且背景帶有如 Star Trek 般的特效。</li>
+<li>輕觸卡片,內容隨即顯示在你的裝置上。</li>
</ol>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw/help_about.html b/OpenPGP-Keychain/src/main/res/raw/help_about.html
index 51e3f1325..2ffbb47a6 100644
--- a/OpenPGP-Keychain/src/main/res/raw/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw/help_about.html
@@ -15,13 +15,18 @@ And don't add newlines before or after p tags because of transifex -->
<li>Ash Hughes (crypto patches)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (UI)</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>Miroojin Bakshi</li>
+<li>Paul Sarbinowski</li>
+<li>Vincent Breitmoser</li>
</ul>
<h2>Developers APG 1.x</h2>
<ul>
-<li>'Thialfihar' (Lead developer)</li>
+<li>Thialfihar (Lead developer)</li>
<li>'Senecaso' (QRCode, sign key, upload key)</li>
-<li>Oliver Runge</li>
<li>Markus Doits</li>
</ul>
@@ -35,8 +40,6 @@ And don't add newlines before or after p tags because of transifex -->
<li><a href="http://rtyley.github.com/spongycastle/">SpongyCastle</a> (MIT X11 License)</li>
<li><a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
<li><a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
-<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li>
-<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li>
</ul>
</body>
</html>
diff --git a/OpenPGP-Keychain/src/main/res/raw/help_start.html b/OpenPGP-Keychain/src/main/res/raw/help_start.html
index 7afac0f08..56c02b1fd 100644
--- a/OpenPGP-Keychain/src/main/res/raw/help_start.html
+++ b/OpenPGP-Keychain/src/main/res/raw/help_start.html
@@ -6,7 +6,7 @@ And don't add newlines before or after p tags because of transifex -->
</head>
<body>
<h2>Getting started</h2>
-<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
diff --git a/OpenPGP-Keychain/src/main/res/values-cs-rCZ/strings.xml b/OpenPGP-Keychain/src/main/res/values-cs-rCZ/strings.xml
new file mode 100644
index 000000000..3d00a143f
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/values-cs-rCZ/strings.xml
@@ -0,0 +1,27 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+ <!--title-->
+ <!--section-->
+ <!--button-->
+ <!--menu-->
+ <!--label-->
+ <string name="unknown_status"></string>
+ <!--choice-->
+ <!--sentences-->
+ <!--errors
+ no punctuation, all lowercase,
+ they will be put after "error_message", e.g. "Error: file not found"-->
+ <!--progress dialogs, usually ending in '…'-->
+ <!--action strings-->
+ <!--key bit length selections-->
+ <!--compression-->
+ <!--Help-->
+ <!--Import-->
+ <!--Intent labels-->
+ <!--Remote API-->
+ <!--Share-->
+ <!--Key list-->
+ <!--Key view-->
+ <!--Navigation Drawer-->
+ <!--hints-->
+</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-de/strings.xml b/OpenPGP-Keychain/src/main/res/values-de/strings.xml
index 1e0fda3bc..493b81314 100644
--- a/OpenPGP-Keychain/src/main/res/values-de/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-de/strings.xml
@@ -13,8 +13,10 @@
<string name="title_preferences">Einstellungen</string>
<string name="title_api_registered_apps">Registrierte Anwendungen</string>
<string name="title_key_server_preference">Schlüsselserver</string>
+ <string name="title_change_passphrase">Passphrase ändern</string>
<string name="title_set_passphrase">Passwort setzen</string>
<string name="title_send_email">E-Mail senden...</string>
+ <string name="title_send_file">Datei senden</string>
<string name="title_encrypt_to_file">In eine Datei verschlüsseln</string>
<string name="title_decrypt_to_file">In eine Datei entschlüsseln</string>
<string name="title_import_keys">Schlüssel importieren</string>
@@ -62,6 +64,8 @@
<string name="btn_clipboard">Zwischenablage</string>
<string name="btn_share">Teilen mit…</string>
<string name="btn_lookup_key">Schlüssel nachschlagen</string>
+ <string name="btn_encryption_advanced_settings_show">Erweiterte Einstellungen anzeigen</string>
+ <string name="btn_encryption_advanced_settings_hide">Erweiterte Einstellungen verbergen</string>
<!--menu-->
<string name="menu_preferences">Einstellungen</string>
<string name="menu_help">Hilfe</string>
@@ -70,15 +74,17 @@
<string name="menu_import">Importieren</string>
<string name="menu_import_from_nfc">NFC</string>
<string name="menu_export_keys">Alle Schlüssel exportieren</string>
+ <string name="menu_export_secret_keys">Alle geheimen Schlüssel exportieren</string>
<string name="menu_export_key">In Datei exportieren</string>
<string name="menu_delete_key">Schlüssel löschen</string>
<string name="menu_create_key">Schlüssel erstellen</string>
<string name="menu_create_key_expert">Schlüssel erstellen (Experte)</string>
<string name="menu_search">Suchen</string>
- <string name="menu_key_server">Schlüsselserver</string>
+ <string name="menu_import_from_key_server">Schlüsselserver</string>
+ <string name="menu_key_server">Schlüsselserver…</string>
<string name="menu_update_key">Von einem Schlüsselserver aktualisieren</string>
<string name="menu_export_key_to_server">Auf Schlüsselserver hochladen</string>
- <string name="menu_share">Teilen</string>
+ <string name="menu_share">Teilen…</string>
<string name="menu_share_title_fingerprint">Teile Fingerabdruck…</string>
<string name="menu_share_title">Teile gesamten Schlüssel…</string>
<string name="menu_share_default_fingerprint">mit…</string>
@@ -91,6 +97,7 @@
<string name="menu_beam_preferences">Beam-Einstellungen</string>
<string name="menu_key_edit_cancel">Abbrechen</string>
<string name="menu_encrypt_to">Verschlüsseln nach…</string>
+ <string name="menu_select_all">Alles auswählen</string>
<!--label-->
<string name="label_sign">Signieren</string>
<string name="label_message">Nachricht</string>
@@ -103,6 +110,7 @@
<string name="label_select_public_keys">Empfänger</string>
<string name="label_delete_after_encryption">Nach Verschlüsselung löschen</string>
<string name="label_delete_after_decryption">Nach Entschlüsselung löschen</string>
+ <string name="label_share_after_encryption">Nach dem Verschlüsseln teilen</string>
<string name="label_encryption_algorithm">Verschlüsselungsalgorithmus</string>
<string name="label_hash_algorithm">Hash-Algorithmus</string>
<string name="label_asymmetric">Öffentlicher Schlüssel</string>
@@ -121,9 +129,12 @@
<string name="label_name">Name</string>
<string name="label_comment">Kommentar</string>
<string name="label_email">E-Mail</string>
+ <string name="label_sign_user_id">Benutzer ID unterschreiben</string>
+ <string name="label_sign_email">Email unterschreiben</string>
<string name="label_send_key">Schlüssel nach Beglaubigung auf ausgewählten Schlüsselserver hochladen</string>
<string name="label_fingerprint">Fingerabdruck</string>
<string name="select_keys_button_default">Auswählen</string>
+ <string name="expiry_date_dialog_title">Ablaufdatum festsetzen</string>
<plurals name="select_keys_button">
<item quantity="one">%d ausgewählt</item>
<item quantity="other">%d ausgewählt</item>
@@ -131,11 +142,17 @@
<string name="user_id_no_name">&lt;kein Name&gt;</string>
<string name="none">&lt;keine&gt;</string>
<string name="no_key">&lt;kein Schlüssel&gt;</string>
+ <string name="no_email">&lt;Keine E-Mail&gt;</string>
<string name="unknown_status"></string>
<string name="can_encrypt">kann verschlüsseln</string>
<string name="can_sign">kann signieren</string>
<string name="expired">abgelaufen</string>
<string name="revoked">zurückgezogen</string>
+ <string name="user_id">Benutzer ID</string>
+ <plurals name="n_contacts">
+ <item quantity="one">1 Kontakt</item>
+ <item quantity="other">%d Kontakte</item>
+ </plurals>
<plurals name="n_key_servers">
<item quantity="one">%d Schlüsselserver</item>
<item quantity="other">%d Schlüsselserver</item>
@@ -191,6 +208,7 @@
<string name="key_deletion_confirmation">Soll der Schlüssel \'%s\' wirklich gelöscht werden?\nDies kann nicht rückgängig gemacht werden! </string>
<string name="key_deletion_confirmation_multi">Möchtest du wirklich alle ausgewählten Schlüssel löschen?\nDies kann nicht rückgängig gemacht werden!</string>
<string name="secret_key_deletion_confirmation">Soll der PRIVATE Schlüssel \'%s\' wirklich gelöscht werden?\nDies kann nicht rückgängig gemacht werden!</string>
+ <string name="also_export_secret_keys">Private Schlüssel auch exportieren</string>
<plurals name="keys_added_and_updated_1">
<item quantity="one">%d Schlüssel erfolgreich hinzugefügt</item>
<item quantity="other">%d Schlüssel erfolgreich hinzugefügt</item>
@@ -212,6 +230,7 @@
<string name="keys_exported">%d Schlüssel erfolgreich exportiert.</string>
<string name="no_keys_exported">Keine Schlüssel exportiert.</string>
<string name="key_creation_el_gamal_info">Beachte: nur Unterschlüssel unterstützen ElGamal. Für ElGamal wird die am nächsten liegende Schlüssellänge von 1536, 2048, 3072, 4096 oder 8192 verwendet.</string>
+ <string name="key_creation_weak_rsa_info">Beachte: RSA-Schlüssel mit einer Schlüssellänge von 1024-Bits oder weniger werden als unsicher angesehen und können daher nicht für neue Schlüssel erstellt werden.</string>
<string name="key_not_found">Schlüssel %08X konnte nicht gefunden werden.</string>
<plurals name="keys_found">
<item quantity="one">%d Schlüssel gefunden.</item>
@@ -243,6 +262,7 @@
<string name="error_master_key_must_not_be_el_gamal">Der Hauptschlüssel kann kein ElGamal Schlüssel sein</string>
<string name="error_unknown_algorithm_choice">Unbekannte Auswahl für Algorithmus</string>
<string name="error_user_id_needs_a_name">ein Name muss angegeben werden</string>
+ <string name="error_user_id_no_email">keine E-Mail gefunden</string>
<string name="error_user_id_needs_an_email_address">eine E-Mail-Adresse muss angegeben werden</string>
<string name="error_key_needs_a_user_id">Mindestens eine Benutzer-ID wird benötigt</string>
<string name="error_main_user_id_must_not_be_empty">Hauptbenutzer-ID darf nicht leer sein</string>
@@ -265,48 +285,59 @@
<string name="error_expiry_must_come_after_creation">Ablaufdatum muss später sein als das Erstellungsdatum</string>
<string name="error_can_not_delete_contact">Sie können diesen Kontakt nicht löschen, denn es ist ihr eigener.</string>
<string name="error_can_not_delete_contacts">Sie können folgende Kontakte nicht löschen, denn sie gehören Ihnen selbst:\n%s</string>
+ <string name="error_keyserver_insufficient_query">Unzureichende Serveranfrage</string>
<string name="error_keyserver_query">Keyserveranfrage fehlgeschlagen</string>
+ <string name="error_keyserver_too_many_responses">Zu viele Antworten</string>
+ <string name="error_import_file_no_content">Datei ist leer</string>
+ <string name="error_generic_report_bug">Ein allgemeiner Fehler trat auf, bitte schreiben Sie einen neuen Bugreport für OpenKeychain.</string>
<plurals name="error_can_not_delete_info">
<item quantity="one">Bitte lösche ihn unter \'Meine Schlüssel\'!</item>
<item quantity="other">Bitte lösche sie unter \'Meine Schlüssel\'!</item>
</plurals>
+ <plurals name="error_import_non_pgp_part">
+ <item quantity="one">Ein Teil der geladenen Datei ist ein gültiges OpenPGP Objekt aber kein OpenPGP Schlüssel</item>
+ <item quantity="other">Teile der geladenen Dateien sind gültige OpenPGP Objekte aber keine OpenPGP Schlüssel</item>
+ </plurals>
<!--progress dialogs, usually ending in '…'-->
- <string name="progress_done">fertig.</string>
+ <string name="progress_done">Erledigt</string>
<string name="progress_cancel">Abbrechen</string>
- <string name="progress_saving">speichern...</string>
- <string name="progress_importing">importieren...</string>
- <string name="progress_exporting">exportieren...</string>
- <string name="progress_generating">erstelle Schlüssel, dies kann bis zu 3 Minuten dauern...</string>
- <string name="progress_building_key">erstelle Schlüssel...</string>
- <string name="progress_preparing_master_key">Hauptschlüssel wird vorbereitet...</string>
- <string name="progress_certifying_master_key">Hauptschlüssel wird beglaubigt...</string>
- <string name="progress_building_master_key">erstelle Hauptring...</string>
- <string name="progress_adding_sub_keys">füge Unterschlüssel hinzu...</string>
- <string name="progress_saving_key_ring">Schlüssel wird gespeichert...</string>
+ <string name="progress_saving">speichern…</string>
+ <string name="progress_importing">importieren…</string>
+ <string name="progress_exporting">exportieren…</string>
+ <string name="progress_building_key">erstelle Schlüssel…</string>
+ <string name="progress_preparing_master_key">Hauptschlüssel wird vorbereitet…</string>
+ <string name="progress_certifying_master_key">Hauptschlüssel wird beglaubigt…</string>
+ <string name="progress_building_master_key">erstelle Hauptring…</string>
+ <string name="progress_adding_sub_keys">füge Unterschlüssel hinzu…</string>
+ <string name="progress_saving_key_ring">Schlüssel wird gespeichert…</string>
<plurals name="progress_exporting_key">
<item quantity="one">Schlüssel wird exportiert…</item>
<item quantity="other">Schlüssel werden exportiert…</item>
</plurals>
- <string name="progress_extracting_signature_key">extrahiere Signaturschlüssel...</string>
- <string name="progress_extracting_key">extrahiere Schlüssel...</string>
- <string name="progress_preparing_streams">Datenstrom wird vorbereitet...</string>
- <string name="progress_encrypting">Daten werden verschlüsselt...</string>
- <string name="progress_decrypting">Daten werden entschlüsselt...</string>
- <string name="progress_preparing_signature">Signatur wird vorbereitet...</string>
- <string name="progress_generating_signature">Signatur wird erstellt...</string>
- <string name="progress_processing_signature">Signatur wird verarbeitet...</string>
- <string name="progress_verifying_signature">Signatur wird verifiziert...</string>
- <string name="progress_signing">signiere...</string>
- <string name="progress_reading_data">Daten werden gelesen...</string>
- <string name="progress_finding_key">Schlüssel wird gesucht...</string>
- <string name="progress_decompressing_data">Daten werden entpackt...</string>
- <string name="progress_verifying_integrity">Integrität wird überprüft...</string>
- <string name="progress_deleting_securely">\'%s\' wird sicher gelöscht...</string>
- <string name="progress_querying">Anfrage wird gestellt...</string>
+ <plurals name="progress_generating">
+ <item quantity="one">erstelle Schlüssel, das kann bis zu 3 Minuten dauern…</item>
+ <item quantity="other">erstelle Schlüssel, das kann bis zu 3 Minuten dauern…</item>
+ </plurals>
+ <string name="progress_extracting_signature_key">extrahiere Signaturschlüssel…</string>
+ <string name="progress_extracting_key">extrahiere Schlüssel…</string>
+ <string name="progress_preparing_streams">Datenstrom wird vorbereitet…</string>
+ <string name="progress_encrypting">Daten werden verschlüsselt…</string>
+ <string name="progress_decrypting">Daten werden entschlüsselt…</string>
+ <string name="progress_preparing_signature">Signatur wird vorbereitet…</string>
+ <string name="progress_generating_signature">Signatur wird erstellt…</string>
+ <string name="progress_processing_signature">Signatur wird verarbeitet…</string>
+ <string name="progress_verifying_signature">Signatur wird verifiziert…</string>
+ <string name="progress_signing">signiere…</string>
+ <string name="progress_reading_data">Daten werden gelesen…</string>
+ <string name="progress_finding_key">Schlüssel wird gesucht…</string>
+ <string name="progress_decompressing_data">Daten werden entpackt…</string>
+ <string name="progress_verifying_integrity">Integrität wird überprüft…</string>
+ <string name="progress_deleting_securely">\'%s\' wird sicher gelöscht…</string>
+ <string name="progress_querying">Anfrage wird gestellt…</string>
<!--action strings-->
<string name="hint_public_keys">Öffentliche Schlüssel suchen</string>
<string name="hint_secret_keys">Private Schlüssel suchen</string>
- <string name="action_share_key_with">Teile Schlüssel über...</string>
+ <string name="action_share_key_with">Teile Schlüssel über…</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_1024">1024</string>
@@ -317,6 +348,7 @@
<string name="compression_very_slow">sehr langsam</string>
<!--Help-->
<string name="help_tab_start">Start</string>
+ <string name="help_tab_faq">FAQ</string>
<string name="help_tab_nfc_beam">NFC-Beam</string>
<string name="help_tab_changelog">Changelog</string>
<string name="help_tab_about">Über</string>
@@ -338,6 +370,10 @@
<string name="import_nfc_help_button">Hilfe</string>
<string name="import_clipboard_button">Füge den Schlüssel aus der Zwischenablage ein</string>
<!--Intent labels-->
+ <string name="intent_decrypt_file">Datei mit OpenKeychain entschlüsseln</string>
+ <string name="intent_import_key">Schlüssel mit OpenKeychain importieren</string>
+ <string name="intent_send_encrypt">Mit OpenKeychain verschlüsseln</string>
+ <string name="intent_send_decrypt">Mit OpenKeychain entschlüsseln</string>
<!--Remote API-->
<string name="api_no_apps">Keine registrierten Anwendungen vorhanden!\n\nAnwendungen von Dritten können Zugriff auf OpenKeychain erbitten. Nachdem Zugriff gewährt wurde, werden diese hier aufgelistet.</string>
<string name="api_settings_show_advanced">Erweiterte Einstellungen anzeigen</string>
@@ -356,7 +392,7 @@
<string name="api_select_pub_keys_missing_text">Für diese Benutzer-IDs wurden keine öffentlichen Schlüssel gefunden:</string>
<string name="api_select_pub_keys_dublicates_text">Für diese Benutzer-IDs existieren mehrere öffentliche Schlüssel:</string>
<string name="api_select_pub_keys_text">Bitte die Liste der Empfänger überprüfen!</string>
- <string name="api_error_wrong_signature">Signaturüberprüfung fehlgeschlagen! Haben Sie diese App von einer anderen Quelle installiert? Wenn Sie eine Attacke ausschließen können, sollten Sie die Registrierung der App in OpenKeychain widerrufen und die App erneut registrieren.</string>
+ <string name="api_error_wrong_signature">Signaturüberprüfung fehlgeschlagen! Haben Sie diese App von einer anderen Quelle installiert? Wenn Sie eine Attacke ausschliessen können, sollten Sie die Registrierung der App in OpenKeychain widerrufen und die App erneut registrieren.</string>
<!--Share-->
<string name="share_qr_code_dialog_title">Über QR Code teilen</string>
<string name="share_qr_code_dialog_start">Mit \'Weiter\' durch alle QR-Codes gehen und diese nacheinander scannen.</string>
@@ -374,6 +410,7 @@
<string name="key_list_empty_button_create">deinen eigenen Schlüssel erstellst</string>
<string name="key_list_empty_button_import">existierende Schlüssel importierst.</string>
<!--Key view-->
+ <string name="key_view_action_edit">Diesen Schlüssel bearbeiten</string>
<string name="key_view_action_encrypt">Für diesen Kontakt verschlüsseln</string>
<string name="key_view_action_certify">Schlüssel dieses Kontakts beglaubigen</string>
<string name="key_view_tab_main">Info</string>
@@ -387,4 +424,12 @@
<string name="nav_apps">Registrierte Anwendungen</string>
<string name="drawer_open">Menu öffnen</string>
<string name="drawer_close">Menu schließen</string>
+ <string name="edit">Bearbeiten</string>
+ <string name="my_keys">Meine Schlüssel</string>
+ <string name="label_secret_key">Geheime Schlüssel</string>
+ <string name="secret_key_yes">verfügbar</string>
+ <string name="secret_key_no">nicht verfügbar</string>
+ <string name="section_uids_to_sign">Benutzer-IDs, die beglaubigt werden sollen</string>
+ <string name="progress_re_adding_certs">Wiederhinzufügen der Zertifikate</string>
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-el/strings.xml b/OpenPGP-Keychain/src/main/res/values-el/strings.xml
index 84b39c221..094dfe28a 100644
--- a/OpenPGP-Keychain/src/main/res/values-el/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-el/strings.xml
@@ -50,4 +50,5 @@
<!--Key list-->
<!--Key view-->
<!--Navigation Drawer-->
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml
index 41dc629aa..ce365b776 100644
--- a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml
@@ -97,4 +97,5 @@
<!--Key list-->
<!--Key view-->
<!--Navigation Drawer-->
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-es/strings.xml b/OpenPGP-Keychain/src/main/res/values-es/strings.xml
index c643a3cd8..85c77b0da 100644
--- a/OpenPGP-Keychain/src/main/res/values-es/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-es/strings.xml
@@ -16,6 +16,7 @@
<string name="title_change_passphrase">Cambiar frase de contraseña</string>
<string name="title_set_passphrase">Establecer frase de contraseña</string>
<string name="title_send_email">Enviar email...</string>
+ <string name="title_send_file">Enviar archivo...</string>
<string name="title_encrypt_to_file">Cifrar hacia archivo</string>
<string name="title_decrypt_to_file">Descifrar hacia archivo</string>
<string name="title_import_keys">Importar claves</string>
@@ -63,6 +64,8 @@
<string name="btn_clipboard">Portapapeles</string>
<string name="btn_share">Compartir con...</string>
<string name="btn_lookup_key">Buscar clave</string>
+ <string name="btn_encryption_advanced_settings_show">Mostrar ajustes avanzados</string>
+ <string name="btn_encryption_advanced_settings_hide">Ocultar ajustes avanzados</string>
<!--menu-->
<string name="menu_preferences">Ajustes</string>
<string name="menu_help">Ayuda</string>
@@ -71,15 +74,17 @@
<string name="menu_import">Importar</string>
<string name="menu_import_from_nfc">Importar desde NFC</string>
<string name="menu_export_keys">Exportar todas las claves</string>
+ <string name="menu_export_secret_keys">Exportar todas las claves secretas</string>
<string name="menu_export_key">Exportar hacia archivo</string>
<string name="menu_delete_key">Borrar clave</string>
<string name="menu_create_key">Crear clave</string>
<string name="menu_create_key_expert">Crear clave (experto)</string>
<string name="menu_search">Buscar</string>
- <string name="menu_key_server">Importar desde servidor de claves</string>
+ <string name="menu_import_from_key_server">Servidor de claves...</string>
+ <string name="menu_key_server">Servidor de claves...</string>
<string name="menu_update_key">Actualizar desde servidor de claves</string>
<string name="menu_export_key_to_server">Cargar al servidor de claves</string>
- <string name="menu_share">Compartir</string>
+ <string name="menu_share">Compartir...</string>
<string name="menu_share_title_fingerprint">Compartir la huella digital...</string>
<string name="menu_share_title">Compartir la clave completa...</string>
<string name="menu_share_default_fingerprint">con...</string>
@@ -105,6 +110,7 @@
<string name="label_select_public_keys">Destinatarios</string>
<string name="label_delete_after_encryption">Borrar después del cifrado</string>
<string name="label_delete_after_decryption">Borrar después del descifrado</string>
+ <string name="label_share_after_encryption">Compartir después del cifrado</string>
<string name="label_encryption_algorithm">Algoritmo de cifrado</string>
<string name="label_hash_algorithm">Algoritmo de Hash</string>
<string name="label_asymmetric">Clave pública</string>
@@ -123,6 +129,8 @@
<string name="label_name">Nombre</string>
<string name="label_comment">Comentario</string>
<string name="label_email">Email</string>
+ <string name="label_sign_user_id">Firmar Id de usuario</string>
+ <string name="label_sign_email">Firmar correo</string>
<string name="label_send_key">Cargar clave al servidor de claves seleccionado después de la certificación</string>
<string name="label_fingerprint">Huella digital</string>
<string name="select_keys_button_default">Seleccionar</string>
@@ -134,11 +142,17 @@
<string name="user_id_no_name">&lt;sin nombre&gt;</string>
<string name="none">&lt;ninguna&gt;</string>
<string name="no_key">&lt;sin clave&gt;</string>
+ <string name="no_email">&lt;No hay un email&gt;</string>
<string name="unknown_status"></string>
<string name="can_encrypt">se puede cifrar</string>
<string name="can_sign">se puede firmar</string>
<string name="expired">caducado</string>
<string name="revoked">revocado</string>
+ <string name="user_id">ID de usuario</string>
+ <plurals name="n_contacts">
+ <item quantity="one">1 contacto</item>
+ <item quantity="other">%d contactos</item>
+ </plurals>
<plurals name="n_key_servers">
<item quantity="one">%d servidor de claves</item>
<item quantity="other">%d servidores de claves</item>
@@ -194,6 +208,7 @@
<string name="key_deletion_confirmation">¿Quieres realmente borrar la clave \'%s\'?\n¡No podrás deshacerlo!</string>
<string name="key_deletion_confirmation_multi">¿Quieres realmente borrar todas las claves seleccionadas?\n¡No podrás deshacerlo!</string>
<string name="secret_key_deletion_confirmation">¿Quieres realmente borrar la clave SECRETA \'%s\'?\n¡No podrás deshacerlo!</string>
+ <string name="also_export_secret_keys">¿Exportar también las claves secretas?</string>
<plurals name="keys_added_and_updated_1">
<item quantity="one">%d clave añadida satisfactoriamente</item>
<item quantity="other">%d claves añadidas satisfactoriamente</item>
@@ -215,6 +230,7 @@
<string name="keys_exported">%d claves exportadas satisfactoriamente.</string>
<string name="no_keys_exported">No se han exportado claves.</string>
<string name="key_creation_el_gamal_info">Nota: solo las subclaves son compatibles con ElGamal, y para ElGamal debe usarse el tamaño de clave más próximo de 1536, 2048, 3072, 4096, o 8192.</string>
+ <string name="key_creation_weak_rsa_info">Nota: generar una clave RSA de longitud 1024-bit o menos está considerado inseguro y desactivado para generar nuevas claves.</string>
<string name="key_not_found">No se puede encontrar la clave %08X.</string>
<plurals name="keys_found">
<item quantity="one">Se ha encontrado %d clave.</item>
@@ -246,6 +262,7 @@
<string name="error_master_key_must_not_be_el_gamal">la clave maestra no puede ser una clave ElGamal</string>
<string name="error_unknown_algorithm_choice">elegido algoritmo desconocido</string>
<string name="error_user_id_needs_a_name">necesitas determinar un nombre</string>
+ <string name="error_user_id_no_email">no se ha encontrado un email</string>
<string name="error_user_id_needs_an_email_address">tienes que determinar una dirección de email</string>
<string name="error_key_needs_a_user_id">necesitas al menos una ID de usuario</string>
<string name="error_main_user_id_must_not_be_empty">la ID del usuario principal no puede estar vacía</string>
@@ -271,17 +288,22 @@
<string name="error_keyserver_insufficient_query">Consulta al servidor insuficiente</string>
<string name="error_keyserver_query">La consulta al servidor de claves ha fallado</string>
<string name="error_keyserver_too_many_responses">Demasiadas respuestas</string>
+ <string name="error_import_file_no_content">El archivo está vacio</string>
+ <string name="error_generic_report_bug">Ha ocurrido un error genérico, por favor, informa de este bug a OpenKeychain</string>
<plurals name="error_can_not_delete_info">
<item quantity="one">Por favor, bórralo desde la pantalla \'Mis claves\'!</item>
<item quantity="other">Por favor, bórralos desde la pantalla \'Mis claves\'!</item>
</plurals>
+ <plurals name="error_import_non_pgp_part">
+ <item quantity="one">parte del archivo cargado es un objeto OpenPGP válido pero no una clave OpenPGP</item>
+ <item quantity="other">partes del archivo cargado son objetos OpenPGP válidos pero no claves OpenPGP</item>
+ </plurals>
<!--progress dialogs, usually ending in '…'-->
- <string name="progress_done">hecho.</string>
- <string name="progress_cancel">cancelar</string>
+ <string name="progress_done">Hecho.</string>
+ <string name="progress_cancel">Cancelar</string>
<string name="progress_saving">guardando...</string>
<string name="progress_importing">importando...</string>
<string name="progress_exporting">exportando...</string>
- <string name="progress_generating">generando la clave, esto puede tardar más de 3 minutos...</string>
<string name="progress_building_key">construyendo la clave...</string>
<string name="progress_preparing_master_key">preparando la clave maestra...</string>
<string name="progress_certifying_master_key">certificando la clave maestra...</string>
@@ -292,6 +314,10 @@
<item quantity="one">exportando clave...</item>
<item quantity="other">exportando claves...</item>
</plurals>
+ <plurals name="progress_generating">
+ <item quantity="one">generando clave, esto puede tardar más de 3 minutos...</item>
+ <item quantity="other">generando claves, esto puede tardar más de 3 minutos...</item>
+ </plurals>
<string name="progress_extracting_signature_key">extrayendo la clave de firma...</string>
<string name="progress_extracting_key">extrayendo la clave...</string>
<string name="progress_preparing_streams">preparando las transmisiones...</string>
@@ -322,6 +348,7 @@
<string name="compression_very_slow">muy lento</string>
<!--Help-->
<string name="help_tab_start">Comenzar</string>
+ <string name="help_tab_faq">FAQ</string>
<string name="help_tab_nfc_beam">NFC Beam</string>
<string name="help_tab_changelog">Registro de cambios</string>
<string name="help_tab_about">A cerca de</string>
@@ -383,6 +410,7 @@
<string name="key_list_empty_button_create">crear tu propia clave</string>
<string name="key_list_empty_button_import">importar claves</string>
<!--Key view-->
+ <string name="key_view_action_edit">Editar esta clave</string>
<string name="key_view_action_encrypt">Cifrar hacia este contacto</string>
<string name="key_view_action_certify">Certificar la clave de este contacto</string>
<string name="key_view_tab_main">Información</string>
@@ -396,4 +424,12 @@
<string name="nav_apps">Aplicaciones registradas</string>
<string name="drawer_open">Abrir el Navigation Drawer</string>
<string name="drawer_close">Cerrar el Navigation Drawer</string>
+ <string name="edit">Editar</string>
+ <string name="my_keys">Mis claves</string>
+ <string name="label_secret_key">Claves secretas</string>
+ <string name="secret_key_yes">disponible</string>
+ <string name="secret_key_no">no disponible</string>
+ <string name="section_uids_to_sign">IDs de usuario para firmar</string>
+ <string name="progress_re_adding_certs">Nueva aplicación de certificados</string>
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-fa-rIR/strings.xml b/OpenPGP-Keychain/src/main/res/values-fa-rIR/strings.xml
index 6bb115049..3d00a143f 100644
--- a/OpenPGP-Keychain/src/main/res/values-fa-rIR/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-fa-rIR/strings.xml
@@ -23,4 +23,5 @@
<!--Key list-->
<!--Key view-->
<!--Navigation Drawer-->
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml
index d99bbcd7c..4f92f7855 100644
--- a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml
@@ -64,6 +64,8 @@
<string name="btn_clipboard">Presse-papiers</string>
<string name="btn_share">Partager avec...</string>
<string name="btn_lookup_key">Rechercher la clef</string>
+ <string name="btn_encryption_advanced_settings_show">Afficher les paramètres avancés</string>
+ <string name="btn_encryption_advanced_settings_hide">Masquer les paramètres avancés</string>
<!--menu-->
<string name="menu_preferences">Paramètres</string>
<string name="menu_help">Aide</string>
@@ -72,15 +74,17 @@
<string name="menu_import">Importer</string>
<string name="menu_import_from_nfc">Importer avec NFC</string>
<string name="menu_export_keys">Exporter toutes les clefs</string>
+ <string name="menu_export_secret_keys">Exporter toutes les clefs secrètes</string>
<string name="menu_export_key">Exporter vers un fichier</string>
<string name="menu_delete_key">Supprimer la clef</string>
<string name="menu_create_key">Créer une clef</string>
<string name="menu_create_key_expert">Créer une clef (expert)</string>
<string name="menu_search">Rechercher</string>
- <string name="menu_key_server">Importer depuis le serveur de clefs</string>
+ <string name="menu_import_from_key_server">Serveur de clefs</string>
+ <string name="menu_key_server">Serveur de clefs...</string>
<string name="menu_update_key">Mettre à jour depuis le serveur de clefs</string>
<string name="menu_export_key_to_server">Téléverser vers le serveur de clefs</string>
- <string name="menu_share">Partager</string>
+ <string name="menu_share">Partager...</string>
<string name="menu_share_title_fingerprint">Partager l\'empreinte...</string>
<string name="menu_share_title">Partager la clef entière...</string>
<string name="menu_share_default_fingerprint">avec...</string>
@@ -138,12 +142,17 @@
<string name="user_id_no_name">&lt;aucun nom&gt;</string>
<string name="none">&lt;aucune&gt;</string>
<string name="no_key">&lt;pas de clef&gt;</string>
+ <string name="no_email">&lt;aucun courriel&gt;</string>
<string name="unknown_status"></string>
<string name="can_encrypt">peut chiffrer</string>
<string name="can_sign">peut signer</string>
<string name="expired">expiré</string>
<string name="revoked">révoquée</string>
<string name="user_id">ID utilisateur</string>
+ <plurals name="n_contacts">
+ <item quantity="one">1 contact</item>
+ <item quantity="other">%d contacts</item>
+ </plurals>
<plurals name="n_key_servers">
<item quantity="one">%d serveur de clefs</item>
<item quantity="other">%d serveurs de clefs</item>
@@ -199,6 +208,7 @@
<string name="key_deletion_confirmation">Voulez-vous vraiment supprimer la clef %s ?\nVous ne pourrez pas la restituer !</string>
<string name="key_deletion_confirmation_multi">Voulez-vous vraiment supprimer toutes les clefs choisies ?\nCeci est irréversible !</string>
<string name="secret_key_deletion_confirmation">Voulez-vous vraiment supprimer la clef SECRÈTE %s ?\nVous ne pourrez pas la restituer !</string>
+ <string name="also_export_secret_keys">Exporter aussi les clefs secrètes?</string>
<plurals name="keys_added_and_updated_1">
<item quantity="one">%d clef ajoutée avec succès</item>
<item quantity="other">%d clefs ajoutées avec succès</item>
@@ -220,6 +230,7 @@
<string name="keys_exported">%d clefs exportées avec succès.</string>
<string name="no_keys_exported">Aucune clef exportée.</string>
<string name="key_creation_el_gamal_info">Note : seules les sous-clefs prennent en charge ElGamal, et pour ElGamal la taille de clef la plus proche de 1 536, 2 048, 3 072, 4 096 ou 8 192 sera utilisée.</string>
+ <string name="key_creation_weak_rsa_info">Note : générer des clefs RSA d\'une longueur de 1024 bits ou moins est considéré non sécuritaire et est désactivé pour la génération de nouvelles clefs.</string>
<string name="key_not_found">Clef %08X introuvable.</string>
<plurals name="keys_found">
<item quantity="one">%d clef trouvée.</item>
@@ -251,6 +262,7 @@
<string name="error_master_key_must_not_be_el_gamal">la clef maîtresse ne peut être une clef ElGama</string>
<string name="error_unknown_algorithm_choice">choix d\'algorhitme inconnu</string>
<string name="error_user_id_needs_a_name">vous devez spécifier un nom</string>
+ <string name="error_user_id_no_email">aucun courriel trouvé</string>
<string name="error_user_id_needs_an_email_address">vous devez spécifier une adresse courriel</string>
<string name="error_key_needs_a_user_id">vous avez besoin d\'au moins un ID utilisateur</string>
<string name="error_main_user_id_must_not_be_empty">l\'ID utilisateur principal ne doit pas être vide</string>
@@ -287,12 +299,11 @@
<item quantity="other">certaines parties du fichier chargé sont des objets OpenPGP valides mais pas des clefs OpenPGP</item>
</plurals>
<!--progress dialogs, usually ending in '…'-->
- <string name="progress_done">fait.</string>
- <string name="progress_cancel">annuler</string>
+ <string name="progress_done">Terminé.</string>
+ <string name="progress_cancel">Annuler</string>
<string name="progress_saving">sauvegarde...</string>
<string name="progress_importing">importation...</string>
<string name="progress_exporting">exportation...</string>
- <string name="progress_generating">génération de la clef, ceci peut prendre jusqu\'à 3 minutes...</string>
<string name="progress_building_key">assemblage de la clef...</string>
<string name="progress_preparing_master_key">préparation de la clef maîtresse...</string>
<string name="progress_certifying_master_key">certification de la clef maîtresse...</string>
@@ -303,6 +314,10 @@
<item quantity="one">exportation de la clef...</item>
<item quantity="other">exportation des clefs...</item>
</plurals>
+ <plurals name="progress_generating">
+ <item quantity="one">génération de la clef, ceci peut prendre jusqu\'à 3 min...</item>
+ <item quantity="other">génération des clefs, ceci peut prendre jusqu\'à 3 min...</item>
+ </plurals>
<string name="progress_extracting_signature_key">extraction de la clef de signature...</string>
<string name="progress_extracting_key">extraction de la clef...</string>
<string name="progress_preparing_streams">préparation des flux...</string>
@@ -333,6 +348,7 @@
<string name="compression_very_slow">très lent</string>
<!--Help-->
<string name="help_tab_start">Commencer</string>
+ <string name="help_tab_faq">FAQ</string>
<string name="help_tab_nfc_beam">NFC Beam</string>
<string name="help_tab_changelog">Journal des changements</string>
<string name="help_tab_about">À propos de</string>
@@ -394,6 +410,7 @@
<string name="key_list_empty_button_create">créer votre propre clef</string>
<string name="key_list_empty_button_import">Importer des clefs.</string>
<!--Key view-->
+ <string name="key_view_action_edit">Modifier cette clef</string>
<string name="key_view_action_encrypt">Chiffrer vers ce contact</string>
<string name="key_view_action_certify">Certifier la clef de ce contact</string>
<string name="key_view_tab_main">Infos</string>
@@ -407,4 +424,12 @@
<string name="nav_apps">Applis enregistrées</string>
<string name="drawer_open">Ouvrir le tiroir de navigation</string>
<string name="drawer_close">Fermer le tiroir de navigation</string>
+ <string name="edit">Modifier</string>
+ <string name="my_keys">Mes clefs</string>
+ <string name="label_secret_key">Clef secrète</string>
+ <string name="secret_key_yes">disponible</string>
+ <string name="secret_key_no">non disponible</string>
+ <string name="section_uids_to_sign">ID utilisateur pour signer</string>
+ <string name="progress_re_adding_certs">Nouvel application des certificats</string>
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml b/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml
index f9e7074da..b125de448 100644
--- a/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml
@@ -64,6 +64,8 @@
<string name="btn_clipboard">Appunti</string>
<string name="btn_share">Condividi con...</string>
<string name="btn_lookup_key">Chiave di ricerca</string>
+ <string name="btn_encryption_advanced_settings_show">Mostra impostazioni avanzate</string>
+ <string name="btn_encryption_advanced_settings_hide">Nascondi impostazioni avanzate</string>
<!--menu-->
<string name="menu_preferences">Impostazioni</string>
<string name="menu_help">Aiuto</string>
@@ -72,15 +74,17 @@
<string name="menu_import">Importa</string>
<string name="menu_import_from_nfc">Importa tramite NFC</string>
<string name="menu_export_keys">Esporta tutte le chiavi</string>
+ <string name="menu_export_secret_keys">Esporta tutte le chiavi segrete</string>
<string name="menu_export_key">Esporta su un file</string>
<string name="menu_delete_key">Cancella chiave</string>
<string name="menu_create_key">Crea chiave</string>
<string name="menu_create_key_expert">Crea chiave (esperto)</string>
<string name="menu_search">Cerca</string>
- <string name="menu_key_server">Importa dal server delle chiavi</string>
+ <string name="menu_import_from_key_server">Server delle Chiavi</string>
+ <string name="menu_key_server">Server delle Chiavi...</string>
<string name="menu_update_key">Aggiorna dal server delle chiavi</string>
<string name="menu_export_key_to_server">Carica chiave nel server</string>
- <string name="menu_share">Condividi</string>
+ <string name="menu_share">Condividi...</string>
<string name="menu_share_title_fingerprint">Condivi impronta...</string>
<string name="menu_share_title">Condividi intera chiave...</string>
<string name="menu_share_default_fingerprint">con..</string>
@@ -138,12 +142,17 @@
<string name="user_id_no_name">&lt;nessun nome&gt;</string>
<string name="none">&lt;nessuno&gt;</string>
<string name="no_key">&lt;nessuna chiave&gt;</string>
+ <string name="no_email">&lt;Nessuna Email&gt;</string>
<string name="unknown_status"></string>
<string name="can_encrypt">puo\'; codificare</string>
<string name="can_sign">puo\' firmare</string>
<string name="expired">scaduto</string>
<string name="revoked">revocato</string>
<string name="user_id">ID Utente</string>
+ <plurals name="n_contacts">
+ <item quantity="one">1 contatto</item>
+ <item quantity="other">%d contatti</item>
+ </plurals>
<plurals name="n_key_servers">
<item quantity="one">%d server delle chiavi</item>
<item quantity="other">%d server delle chiavi</item>
@@ -199,6 +208,7 @@
<string name="key_deletion_confirmation">Vuoi veramente eliminare la chiave \'%s\'?\nNon potrai annullare!</string>
<string name="key_deletion_confirmation_multi">Vuoi veramente eliminare le chiavi selezionate?\nNon potrai annullare!</string>
<string name="secret_key_deletion_confirmation">Vuoi veramente eliminare la chiave PRIVATA \'%s\'?\nNon potrai annullare!</string>
+ <string name="also_export_secret_keys">Esportare anche le chiavi segrete?</string>
<plurals name="keys_added_and_updated_1">
<item quantity="one">%d chiave aggiunta correttamente</item>
<item quantity="other">%d chiavi aggiunte correttamente</item>
@@ -220,6 +230,7 @@
<string name="keys_exported">%d chiavi esportate correttamente.</string>
<string name="no_keys_exported">Nessuna chiave esportata.</string>
<string name="key_creation_el_gamal_info">Nota: solo le sottochiavi supportano ElGamal, e per ElGamal verra\' usata la grandezza chiave piu\' vicina a 1536, 2048, 3072, 4096 o 8192.</string>
+ <string name="key_creation_weak_rsa_info">Nota: la generazione di chiavi RSA con lunghezza pari a 1024 bit o inferiore è considerata non sicura ed è disabilitata per la generazione di nuove chiavi.</string>
<string name="key_not_found">Impossibile trovare la chiave %08X.</string>
<plurals name="keys_found">
<item quantity="one">Trovata %d chiave.</item>
@@ -251,6 +262,7 @@
<string name="error_master_key_must_not_be_el_gamal">La chiave principale non puo\' essere ElGamal</string>
<string name="error_unknown_algorithm_choice">opzione algoritmo sconosciuta</string>
<string name="error_user_id_needs_a_name">devi specificare un nome</string>
+ <string name="error_user_id_no_email">Nessuna email trovata</string>
<string name="error_user_id_needs_an_email_address">devi specificare un indirizzo email</string>
<string name="error_key_needs_a_user_id">necessario almeno un id utente</string>
<string name="error_main_user_id_must_not_be_empty">id utente principale non puo\' essere vuoto</string>
@@ -287,12 +299,11 @@
<item quantity="other">parti del file caricato sono oggetti OpenPGP validi, ma non chavi OpenPGP</item>
</plurals>
<!--progress dialogs, usually ending in '…'-->
- <string name="progress_done">fatto.</string>
- <string name="progress_cancel">cancella</string>
+ <string name="progress_done">Fatto.</string>
+ <string name="progress_cancel">Annulla</string>
<string name="progress_saving">salvataggio...</string>
<string name="progress_importing">importazione...</string>
<string name="progress_exporting">esportazione...</string>
- <string name="progress_generating">generazione chiave, richiede fino a 3 minuti...</string>
<string name="progress_building_key">fabbricazione chiave...</string>
<string name="progress_preparing_master_key">preparazione chiave principale...</string>
<string name="progress_certifying_master_key">certificazione chiave principale...</string>
@@ -303,6 +314,10 @@
<item quantity="one">esportazione chiave...</item>
<item quantity="other">esportazione chiavi...</item>
</plurals>
+ <plurals name="progress_generating">
+ <item quantity="one">generazione chiave, sono necessari fino a 3 minuti...</item>
+ <item quantity="other">generazione chiavi, sono necessari fino a 3 minuti...</item>
+ </plurals>
<string name="progress_extracting_signature_key">estrazione chiavi di firma...</string>
<string name="progress_extracting_key">estrazione chiave...</string>
<string name="progress_preparing_streams">preparazione flussi...</string>
@@ -333,6 +348,7 @@
<string name="compression_very_slow">molto lento</string>
<!--Help-->
<string name="help_tab_start">Inizia</string>
+ <string name="help_tab_faq">FAQ</string>
<string name="help_tab_nfc_beam">NFC Beam</string>
<string name="help_tab_changelog">Novita\'</string>
<string name="help_tab_about">Info</string>
@@ -394,6 +410,7 @@
<string name="key_list_empty_button_create">creazione della tua chiave</string>
<string name="key_list_empty_button_import">importazione chiavi.</string>
<!--Key view-->
+ <string name="key_view_action_edit">Modifica chiave</string>
<string name="key_view_action_encrypt">Codifica a questo contatto</string>
<string name="key_view_action_certify">Certifica la chiave di questo contatto</string>
<string name="key_view_tab_main">Info</string>
@@ -407,4 +424,12 @@
<string name="nav_apps">App Registrate</string>
<string name="drawer_open">Apri drawer di navigazione</string>
<string name="drawer_close">Chiudi drawer di navigazione</string>
+ <string name="edit">Modifica</string>
+ <string name="my_keys">Le Mie Chiavi</string>
+ <string name="label_secret_key">Chiave Segreta</string>
+ <string name="secret_key_yes">disponibile</string>
+ <string name="secret_key_no">non disponibile</string>
+ <string name="section_uids_to_sign">ID Utente da firmare</string>
+ <string name="progress_re_adding_certs">Riapplicazione certificati</string>
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-ja/strings.xml b/OpenPGP-Keychain/src/main/res/values-ja/strings.xml
index e5ee5ecc0..97f0c6eed 100644
--- a/OpenPGP-Keychain/src/main/res/values-ja/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-ja/strings.xml
@@ -62,8 +62,10 @@
<string name="btn_next">次</string>
<string name="btn_back">戻る</string>
<string name="btn_clipboard">クリップボード</string>
- <string name="btn_share">共有...</string>
+ <string name="btn_share">...で共有</string>
<string name="btn_lookup_key">鍵検出</string>
+ <string name="btn_encryption_advanced_settings_show">拡張設定を表示</string>
+ <string name="btn_encryption_advanced_settings_hide">拡張設定を隠す</string>
<!--menu-->
<string name="menu_preferences">設定</string>
<string name="menu_help">ヘルプ</string>
@@ -72,15 +74,17 @@
<string name="menu_import">インポート</string>
<string name="menu_import_from_nfc">NFCからインポート</string>
<string name="menu_export_keys">すべての鍵のエクスポート</string>
+ <string name="menu_export_secret_keys">すべての秘密鍵のエクスポート</string>
<string name="menu_export_key">ファイルへのエクスポート</string>
<string name="menu_delete_key">鍵の削除</string>
<string name="menu_create_key">鍵の生成</string>
<string name="menu_create_key_expert">鍵の生成(上級)</string>
<string name="menu_search">検索</string>
- <string name="menu_key_server">鍵サーバからのインポート</string>
+ <string name="menu_import_from_key_server">鍵サーバ</string>
+ <string name="menu_key_server">鍵サーバ...</string>
<string name="menu_update_key">鍵サーバからの更新</string>
<string name="menu_export_key_to_server">鍵サーバへのアップロード</string>
- <string name="menu_share">共有</string>
+ <string name="menu_share">共有...</string>
<string name="menu_share_title_fingerprint">指紋の共有...</string>
<string name="menu_share_title">すべての鍵の共有...</string>
<string name="menu_share_default_fingerprint">...(指紋)</string>
@@ -137,12 +141,16 @@
<string name="user_id_no_name">&lt;名前なし&gt;</string>
<string name="none">&lt;無し&gt;</string>
<string name="no_key">&lt;鍵無し&gt;</string>
+ <string name="no_email">&lt;メールなし&gt;</string>
<string name="unknown_status"></string>
<string name="can_encrypt">暗号化可能</string>
<string name="can_sign">署名可能</string>
<string name="expired">期限切れ</string>
<string name="revoked">破棄</string>
<string name="user_id">ユーザーID</string>
+ <plurals name="n_contacts">
+ <item quantity="other">%d個の連絡先</item>
+ </plurals>
<plurals name="n_key_servers">
<item quantity="other">%d の鍵サーバ</item>
</plurals>
@@ -197,6 +205,7 @@
<string name="key_deletion_confirmation">鍵\'%s\'を本当に削除してもよいですか?\nこれは元に戻せません!</string>
<string name="key_deletion_confirmation_multi">選択したすべての鍵を本当に削除してよいですか?\nこれは元に戻せません。</string>
<string name="secret_key_deletion_confirmation">秘密鍵\'%s\'を本当に削除してもよいですか?\nこれは元に戻せません!</string>
+ <string name="also_export_secret_keys">秘密鍵もエクスポートしますか?</string>
<plurals name="keys_added_and_updated_1">
<item quantity="other">%d の鍵を追加しました</item>
</plurals>
@@ -214,6 +223,7 @@
<string name="keys_exported">%d の鍵をエクスポートしました。</string>
<string name="no_keys_exported">鍵をエクスポートしていません。</string>
<string name="key_creation_el_gamal_info">備考: 副鍵として ElGamalだけがサポートされ, ElGamal は鍵サイズとして1536, 2048, 3072, 4096, 8192 だけが使えます。</string>
+ <string name="key_creation_weak_rsa_info">付記: 長さ1024bitかそれ以下で生成されたRSA鍵は安全とはみなされず、新な鍵の生成は無効にされています。</string>
<string name="key_not_found">鍵 %08X は見付かりませんでした。</string>
<plurals name="keys_found">
<item quantity="other">%d の鍵を発見。</item>
@@ -243,6 +253,7 @@
<string name="error_master_key_must_not_be_el_gamal">主鍵を ElGamal にすることはできません</string>
<string name="error_unknown_algorithm_choice">未知のアルゴリズムを選択しています</string>
<string name="error_user_id_needs_a_name">名前を特定する必要があります</string>
+ <string name="error_user_id_no_email">メールが見付かりません</string>
<string name="error_user_id_needs_an_email_address">Eメールアドレスを特定する必要があります</string>
<string name="error_key_needs_a_user_id">最低でも1つのユーザIDが必要です</string>
<string name="error_main_user_id_must_not_be_empty">主ユーザIDは空にすることはできません</string>
@@ -282,7 +293,6 @@
<string name="progress_saving">保存...</string>
<string name="progress_importing">インポート...</string>
<string name="progress_exporting">エクスポート...</string>
- <string name="progress_generating">鍵の生成、3分ほどかかります...</string>
<string name="progress_building_key">鍵の構築中...</string>
<string name="progress_preparing_master_key">主鍵の準備中...</string>
<string name="progress_certifying_master_key">主鍵の検証中...</string>
@@ -292,6 +302,9 @@
<plurals name="progress_exporting_key">
<item quantity="other">鍵のエクスポート...</item>
</plurals>
+ <plurals name="progress_generating">
+ <item quantity="other">鍵の生成中、最大3分ほどかかります...</item>
+ </plurals>
<string name="progress_extracting_signature_key">署名鍵の取り出し中...</string>
<string name="progress_extracting_key">鍵の取り出し中...</string>
<string name="progress_preparing_streams">ストリームの準備中...</string>
@@ -311,7 +324,7 @@
<!--action strings-->
<string name="hint_public_keys">公開鍵の検索</string>
<string name="hint_secret_keys">秘密鍵の検索</string>
- <string name="action_share_key_with">鍵の共有...</string>
+ <string name="action_share_key_with">...で鍵の共有</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_1024">1024</string>
@@ -322,6 +335,7 @@
<string name="compression_very_slow">とても遅い</string>
<!--Help-->
<string name="help_tab_start">開始</string>
+ <string name="help_tab_faq">FAQ</string>
<string name="help_tab_nfc_beam">NFC Beam</string>
<string name="help_tab_changelog">Changelog</string>
<string name="help_tab_about">これについて</string>
@@ -349,7 +363,7 @@
<!--Remote API-->
<string name="api_no_apps">登録されていないアプリケーション!\n\nサードパーティアプリケーションはOpenKeychainにアクセスを要求できます。アクセスを与えた後、それらはここにリストされます。</string>
<string name="api_settings_show_advanced">拡張設定を表示</string>
- <string name="api_settings_hide_advanced">拡張設定を非表示</string>
+ <string name="api_settings_hide_advanced">拡張設定を隠す</string>
<string name="api_settings_no_key">鍵が選択されていない</string>
<string name="api_settings_select_key">鍵の選択</string>
<string name="api_settings_save">保存</string>
@@ -381,6 +395,7 @@
<string name="key_list_empty_button_create">あなた所有の鍵を作る</string>
<string name="key_list_empty_button_import">鍵のインポート。</string>
<!--Key view-->
+ <string name="key_view_action_edit">この鍵の編集</string>
<string name="key_view_action_encrypt">この連絡先を暗号化</string>
<string name="key_view_action_certify">この連絡先の鍵を検証</string>
<string name="key_view_tab_main">情報</string>
@@ -394,4 +409,12 @@
<string name="nav_apps">登録済みのアプリ</string>
<string name="drawer_open">ナビゲーションドロワーを開く</string>
<string name="drawer_close">ナビゲーションドロワーを閉める</string>
+ <string name="edit">編集</string>
+ <string name="my_keys">自分の鍵</string>
+ <string name="label_secret_key">秘密鍵</string>
+ <string name="secret_key_yes">存在する</string>
+ <string name="secret_key_no">存在しない</string>
+ <string name="section_uids_to_sign">署名に使うユーザーID</string>
+ <string name="progress_re_adding_certs">検証を再適用する</string>
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml
index de6ba554d..a7f674ea0 100644
--- a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml
@@ -170,7 +170,6 @@
<string name="error_nfc_needed">Uw apparaat biedt geen ondersteuning voor NFC</string>
<string name="error_nothing_import">Niets te importeren</string>
<!--progress dialogs, usually ending in '…'-->
- <string name="progress_done">gereed.</string>
<string name="progress_saving">opslaan...</string>
<string name="progress_importing">importeren...</string>
<string name="progress_exporting">exporteren...</string>
@@ -236,4 +235,5 @@
<!--Key list-->
<!--Key view-->
<!--Navigation Drawer-->
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-pl/strings.xml b/OpenPGP-Keychain/src/main/res/values-pl/strings.xml
new file mode 100644
index 000000000..afdf72223
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/values-pl/strings.xml
@@ -0,0 +1,450 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+ <!--title-->
+ <string name="title_manage_public_keys">Kontakty</string>
+ <string name="title_manage_secret_keys">Klucze prywatne</string>
+ <string name="title_select_recipients">Wybierz Klucz Publiczny</string>
+ <string name="title_select_secret_key">Wybierz Klucz Prywatny</string>
+ <string name="title_encrypt">Zaszyfruj</string>
+ <string name="title_decrypt">Odszyfruj</string>
+ <string name="title_authentication">Hasło</string>
+ <string name="title_create_key">Utwórz Klucz</string>
+ <string name="title_edit_key">Edytuj Klucz</string>
+ <string name="title_preferences">Właściwości</string>
+ <string name="title_api_registered_apps">Zarejestrowane Aplikacje</string>
+ <string name="title_key_server_preference">Właściwości serwera kluczy</string>
+ <string name="title_change_passphrase">Zmień hasło</string>
+ <string name="title_set_passphrase">Ustaw hasło</string>
+ <string name="title_send_email">Wyślij maila...</string>
+ <string name="title_send_file">Wyślij plik...</string>
+ <string name="title_encrypt_to_file">Zaszyfruj do pliku</string>
+ <string name="title_decrypt_to_file">Odszyfruj do pliku</string>
+ <string name="title_import_keys">Importuj klucze</string>
+ <string name="title_export_key">Eksportuj klucz</string>
+ <string name="title_export_keys">Eksportuj klucze</string>
+ <string name="title_key_not_found">Nie znaleziono klucza</string>
+ <string name="title_key_server_query">Wyślij zapytanie do serwera kluczy</string>
+ <string name="title_send_key">Wyślij do serwera kluczy</string>
+ <string name="title_unknown_signature_key">Nieznany klucz podpisu</string>
+ <string name="title_certify_key">Certyfikuj klucz</string>
+ <string name="title_key_details">Szczegóły klucza</string>
+ <string name="title_help">Pomoc</string>
+ <!--section-->
+ <string name="section_user_ids">Identyfikator użytkownika</string>
+ <string name="section_keys">Klucze</string>
+ <string name="section_general">Ogólne</string>
+ <string name="section_defaults">Domyślne</string>
+ <string name="section_advanced">Zaawansowane</string>
+ <string name="section_master_key">Klucz główny</string>
+ <string name="section_master_user_id">Główny identyfikator użytkownika</string>
+ <string name="section_actions">Działania</string>
+ <string name="section_certification_key">Twój klucz użyty do certyfikacji</string>
+ <string name="section_upload_key">Wyślij klucz</string>
+ <string name="section_key_server">Serwer kluczy</string>
+ <string name="section_encrypt_and_or_sign">Zaszyfruj i/lub podpisz</string>
+ <string name="section_decrypt_verify">Deszyfruj i weryfikuj</string>
+ <!--button-->
+ <string name="btn_sign">Podpisz</string>
+ <string name="btn_certify">Certyfikuj</string>
+ <string name="btn_decrypt">Odszyfruj</string>
+ <string name="btn_decrypt_verify">Deszyfruj i weryfikuj</string>
+ <string name="btn_select_encrypt_keys">Wybierz odbiorców</string>
+ <string name="btn_encrypt_file">Zaszyfruj plik</string>
+ <string name="btn_save">Zapisz</string>
+ <string name="btn_do_not_save">Anuluj</string>
+ <string name="btn_delete">Usuń</string>
+ <string name="btn_no_date">Żaden</string>
+ <string name="btn_okay">Ok</string>
+ <string name="btn_change_passphrase">Zmień hasło</string>
+ <string name="btn_set_passphrase">Ustaw hasło</string>
+ <string name="btn_search">Wyszukaj</string>
+ <string name="btn_export_to_server">Wyślij do serwera kluczy</string>
+ <string name="btn_next">Dalej</string>
+ <string name="btn_back">Wstecz</string>
+ <string name="btn_clipboard">Schowek</string>
+ <string name="btn_share">Podziel się z...</string>
+ <string name="btn_lookup_key">Klucz wyszukiwania</string>
+ <string name="btn_encryption_advanced_settings_show">Pokaż zaawanowane ustawienia</string>
+ <string name="btn_encryption_advanced_settings_hide">Ukryj zaawansowane ustawienia</string>
+ <!--menu-->
+ <string name="menu_preferences">Ustawienia</string>
+ <string name="menu_help">Pomoc</string>
+ <string name="menu_import_from_file">Zaimportuj z pliku</string>
+ <string name="menu_import_from_qr_code">Zaimportuj z kodu QR</string>
+ <string name="menu_import">Import</string>
+ <string name="menu_import_from_nfc">Zaimportuj przy użyciu NFC</string>
+ <string name="menu_export_keys">Eksportuj wszystkie klucze</string>
+ <string name="menu_export_secret_keys">Eksportuj wszystkie klucze prywatne</string>
+ <string name="menu_export_key">Eksportuj do pliku</string>
+ <string name="menu_delete_key">Usuń klucz</string>
+ <string name="menu_create_key">Stwórz klucz</string>
+ <string name="menu_create_key_expert">Stwórz klucz (tryb zaawansowany)</string>
+ <string name="menu_search">Znajdź</string>
+ <string name="menu_import_from_key_server">Serwer kluczy</string>
+ <string name="menu_key_server">Serwer kluczy...</string>
+ <string name="menu_update_key">Aktualizuj z serwera kluczy</string>
+ <string name="menu_export_key_to_server">Wyślij do serwera kluczy</string>
+ <string name="menu_share">Udostepnij...</string>
+ <string name="menu_share_title_fingerprint">Udostepnij odcisk...</string>
+ <string name="menu_share_title">Udostępnij cały klucz...</string>
+ <string name="menu_share_default_fingerprint">z...</string>
+ <string name="menu_share_default">z...</string>
+ <string name="menu_share_qr_code">za pomocą kodu QR</string>
+ <string name="menu_share_qr_code_fingerprint">za pomocą kodu QR</string>
+ <string name="menu_share_nfc">za pomocą NFC</string>
+ <string name="menu_copy_to_clipboard">Kopiuj do schowka</string>
+ <string name="menu_sign_key">Klucz podpisu</string>
+ <string name="menu_beam_preferences">Ustawienia Beam</string>
+ <string name="menu_key_edit_cancel">Anuluj</string>
+ <string name="menu_encrypt_to">Zaszyfruj do...</string>
+ <string name="menu_select_all">Wybierz wszystko</string>
+ <!--label-->
+ <string name="label_sign">Podpis</string>
+ <string name="label_message">Wiadomość</string>
+ <string name="label_file">Plik</string>
+ <string name="label_no_passphrase">Brak hasła</string>
+ <string name="label_passphrase">Hasło</string>
+ <string name="label_passphrase_again">Ponów</string>
+ <string name="label_algorithm">Algorytm</string>
+ <string name="label_ascii_armor">ASCII Armor</string>
+ <string name="label_select_public_keys">Odbiorcy</string>
+ <string name="label_delete_after_encryption">Usuń po zaszyfrowaniu</string>
+ <string name="label_delete_after_decryption">Usuń po odszyfrowaniu</string>
+ <string name="label_share_after_encryption">Udostępnij po zaszyfrowaniu</string>
+ <string name="label_encryption_algorithm">Algorytm szyfrujący</string>
+ <string name="label_hash_algorithm">Algorytm funkcji skrótu</string>
+ <string name="label_asymmetric">Klucz publiczny</string>
+ <string name="label_symmetric">Hasło</string>
+ <string name="label_passphrase_cache_ttl">Bufor haseł</string>
+ <string name="label_message_compression">Kompresja wiadomości</string>
+ <string name="label_file_compression">Kompresja plików</string>
+ <string name="label_force_v3_signature">Wymuś stare podpisy OpenPGPv3</string>
+ <string name="label_key_servers">Serwery kluczy</string>
+ <string name="label_key_id">Identyfikator klucza</string>
+ <string name="label_creation">Utworzenia</string>
+ <string name="label_expiry">Wygaśnięcia</string>
+ <string name="label_usage">Wykorzystanie</string>
+ <string name="label_key_size">Rozmiar klucza</string>
+ <string name="label_main_user_id">Identyfikator głównego użytkownika</string>
+ <string name="label_name">Imię</string>
+ <string name="label_comment">Komentarz</string>
+ <string name="label_email">Adres email</string>
+ <string name="label_sign_user_id">Identyfikator użytkownika podpisu (sign user id)</string>
+ <string name="label_sign_email">Podpisz e-mail</string>
+ <string name="label_send_key">Wyślij klucz do serwera kluczy po certyfikacji</string>
+ <string name="label_fingerprint">Odcisk</string>
+ <string name="select_keys_button_default">Wybierz</string>
+ <string name="expiry_date_dialog_title">Ustaw datę wygaśnięcia</string>
+ <plurals name="select_keys_button">
+ <item quantity="one">wybrano %d</item>
+ <item quantity="few">wybrano %d</item>
+ <item quantity="other">wybrano %d</item>
+ </plurals>
+ <string name="user_id_no_name">&lt;bez nazwy&gt;</string>
+ <string name="none">&lt;żaden&gt;</string>
+ <string name="no_key">&lt;brak klucza&gt;</string>
+ <string name="no_email">&lt;Brak adresu email&gt;</string>
+ <string name="unknown_status"></string>
+ <string name="can_encrypt">może szyfrować</string>
+ <string name="can_sign">może podpisywać</string>
+ <string name="expired">wygasły</string>
+ <string name="revoked">unieważniony</string>
+ <string name="user_id">Identyfikator użytkownika</string>
+ <plurals name="n_contacts">
+ <item quantity="one">1 kontakt</item>
+ <item quantity="few">%d kontakty</item>
+ <item quantity="other">%d kontaktów</item>
+ </plurals>
+ <plurals name="n_key_servers">
+ <item quantity="one">%d serwer kluczy</item>
+ <item quantity="few">%d serwerów kluczy</item>
+ <item quantity="other">%d serwerów kluczy</item>
+ </plurals>
+ <string name="fingerprint">Odcisk:</string>
+ <string name="secret_key">Klucz prywatny:</string>
+ <!--choice-->
+ <string name="choice_none">Żaden</string>
+ <string name="choice_sign_only">Tylko podpisz</string>
+ <string name="choice_encrypt_only">Tylko zaszyfruj</string>
+ <string name="choice_sign_and_encrypt">Podpisz i zaszyfruj</string>
+ <string name="choice_15secs">15 sekund</string>
+ <string name="choice_1min">1 minuta</string>
+ <string name="choice_3mins">3 minuty</string>
+ <string name="choice_5mins">5 minut</string>
+ <string name="choice_10mins">10 minut</string>
+ <string name="choice_20mins">20 minut</string>
+ <string name="choice_40mins">40 minut</string>
+ <string name="choice_1hour">1 godzina</string>
+ <string name="choice_2hours">2 godziny</string>
+ <string name="choice_4hours">4 godziny</string>
+ <string name="choice_8hours">8 godzin</string>
+ <string name="choice_forever">na zawsze</string>
+ <string name="dsa">DSA</string>
+ <string name="elgamal">ElGamal</string>
+ <string name="rsa">RSA</string>
+ <string name="filemanager_title_open">Otwórz...</string>
+ <string name="warning">Ostrzeżenie</string>
+ <string name="error">Błąd</string>
+ <string name="error_message">Błąd: %s</string>
+ <!--sentences-->
+ <string name="wrong_passphrase">Nieprawidłowe hasło.</string>
+ <string name="using_clipboard_content">Użycie zawartości schowka.</string>
+ <string name="set_a_passphrase">Najpierw ustaw hasło.</string>
+ <string name="no_filemanager_installed">Nie zainstalowano żadnego kompatybilnego menadżera plików.</string>
+ <string name="passphrases_do_not_match">Hasła nie pasują do siebie</string>
+ <string name="passphrase_must_not_be_empty">Puste hasła nie są dozwolone.</string>
+ <string name="passphrase_for_symmetric_encryption">Szyfrowanie symetryczne.</string>
+ <string name="passphrase_for">Podaj hasło dla \'%s\'</string>
+ <string name="file_delete_confirmation">Czy jesteś pewien że chcesz usunąć\n%s?</string>
+ <string name="file_delete_successful">Usunięto pomyślnie.</string>
+ <string name="no_file_selected">Najpierw wskaż plik.</string>
+ <string name="decryption_successful">Odszyfrowano pomyślnie.</string>
+ <string name="encryption_successful">Zaszyfrowano pomyślnie.</string>
+ <string name="encryption_to_clipboard_successful">Pomyślnie zaszyfrowano do schowka.</string>
+ <string name="enter_passphrase_twice">Podaj hasło dwukrotnie.</string>
+ <string name="select_encryption_key">Wybierz co najmniej jeden klucz szyfrujący.</string>
+ <string name="select_encryption_or_signature_key">Wybierz co najmniej jeden klucz szyfrujący lub klucz podpisujący.</string>
+ <string name="specify_file_to_encrypt_to">Wskaż, do którego pliku zapisać zaszyfrowane dane.\nOSTRZEŻENIE: Plik zostanie nadpisany, jeżeli istnieje.</string>
+ <string name="specify_file_to_decrypt_to">Wskaż, do którego pliku zapisać odszyfrowane dane.\nOSTRZEŻENIE: Plik zostanie nadpisany, jeżeli istnieje.</string>
+ <string name="specify_file_to_export_to">Wskaż, do którego pliku wyeksportować dane.\nOSTRZEŻENIE: Plik zostanie nadpisany, jeżeli istnieje.</string>
+ <string name="specify_file_to_export_secret_keys_to">Wskaż, do którego pliku zapisać eksportowane dane.\nOSTRZEŻENIE: Masz zamiar zapisać klucze PRYWATNE (tajne)\nOSTRZEŻENIE: Plik zostanie nadpisany, jeżeli istnieje.</string>
+ <string name="key_deletion_confirmation">Czy na pewno chcesz usunąć klucz \'%s\'?\nNie można cofnąć tej operacji!</string>
+ <string name="key_deletion_confirmation_multi">Czy na pewno chcesz usunąć wszystkie zaznaczone klucze?\nTej operacji nie można cofnąć!</string>
+ <string name="secret_key_deletion_confirmation">Czy na pewno chcesz usunąć klucz prywatny \'%s\'?\nNie można cofnąć tej operacji!</string>
+ <string name="also_export_secret_keys">Czy wyeksportować również klucze prywatne?</string>
+ <plurals name="keys_added_and_updated_1">
+ <item quantity="one">Pomyślnie dodano %d klucz</item>
+ <item quantity="few">Pomyślnie dodano %d kluczy</item>
+ <item quantity="other">Pomyślnie dodano %d kluczy</item>
+ </plurals>
+ <plurals name="keys_added_and_updated_2">
+ <item quantity="one">i zaktualizowano %d klucz.</item>
+ <item quantity="few">i zaktualizowano %d kluczy.</item>
+ <item quantity="other">i zaktualizowano %d kluczy.</item>
+ </plurals>
+ <plurals name="keys_added">
+ <item quantity="one">Pomyślnie dodano %d klucz.</item>
+ <item quantity="few">Pomyślnie dodano %d kluczy.</item>
+ <item quantity="other">Pomyślnie dodano %d kluczy.</item>
+ </plurals>
+ <plurals name="keys_updated">
+ <item quantity="one">Pomyślnie zaktualizowano %d klucz.</item>
+ <item quantity="few">Pomyślnie zaktualizowano %d kluczy.</item>
+ <item quantity="other">Pomyślnie zaktualizowano %d kluczy.</item>
+ </plurals>
+ <string name="no_keys_added_or_updated">Nie dodano ani zaktualizowano żadnych kluczy.</string>
+ <string name="key_exported">Pomyślnie wyeksportowano 1 klucz.</string>
+ <string name="keys_exported">Pomyślnie wyeksportowano %d kluczy.</string>
+ <string name="no_keys_exported">Nie wyeksportowano żadnych kluczy.</string>
+ <string name="key_creation_el_gamal_info">Uwaga: algorytm EnGamal jest obsługiwany tylko przez podklucze i użyty zostanie najbliższy rozmiar klucza z podanych: 1536, 2048, 3072, 4096, 8192.</string>
+ <string name="key_creation_weak_rsa_info">Uwaga: generowanie klucza RSA o długości 1024 bity i mniejszej jest uważane za niebezpieczne i wyłączone dla tworzenia nowych kluczy.</string>
+ <string name="key_not_found">Nie można znaleźć klucza %08X.</string>
+ <plurals name="keys_found">
+ <item quantity="one">Znaleziono %d klucz.</item>
+ <item quantity="few">Znaleziono %d kluczy.</item>
+ <item quantity="other">Znaleziono %d kluczy.</item>
+ </plurals>
+ <string name="unknown_signature">Nieznany podpis, naciśnij przycisk, aby wyszukać brakujący klucz.</string>
+ <plurals name="bad_keys_encountered">
+ <item quantity="one">Zignorowano %d niepoprawny klucz prywatny. Prawdopodobnie został wyeksportowany przy uzyciu opcji\n --export-secret-subkeys\nUpewnij się że eksportujesz go z opcją\n --export-secret-keys\nktóra jest poprawna.</item>
+ <item quantity="few">Zignorowano %d niepoprawnych kluczy prywatnych. Prawdopodobnie zostały wyeksportowane przy uzyciu opcji\n --export-secret-subkeys\nUpewnij się że eksportujesz je z opcją\n --export-secret-keys\nktóra jest poprawna.</item>
+ <item quantity="other">zignorowano %d niepoprawnych kluczy prywatnych. Prawdopodobnie zostały wyeksportowane przy uzyciu opcji\n --export-secret-subkeys\nUpewnij się że eksportujesz je z opcją\n --export-secret-keys\nktóra jest poprawna.</item>
+ </plurals>
+ <string name="key_send_success">Pomyślnie wysłano klucz na serwer</string>
+ <string name="key_sign_success">Pomyślnie podpisano klucz</string>
+ <string name="list_empty">Lista jest pusta!</string>
+ <string name="nfc_successfull">Pomyślnie wysłano klucz przez NFC!</string>
+ <string name="key_copied_to_clipboard">Klucz został skopiowany do schowka!</string>
+ <string name="key_has_already_been_signed">Klucz został już wcześniej podpisany!</string>
+ <string name="select_key_to_sign">Wybierz klucz, który zostanie użyty do podpisania!</string>
+ <string name="key_too_big_for_sharing">Klucz ma za duży rozmiar by być udostępniony w ten sposób!</string>
+ <!--errors
+ no punctuation, all lowercase,
+ they will be put after "error_message", e.g. "Error: file not found"-->
+ <string name="error_file_delete_failed">usuwanie \'%s\' zakończone niepowodzeniem</string>
+ <string name="error_file_not_found">plik nie znaleziony</string>
+ <string name="error_no_secret_key_found">nie znaleziono pasującego klucza prywatnego</string>
+ <string name="error_no_known_encryption_found">napotkano nieznany rodzaj szyfrowania</string>
+ <string name="error_external_storage_not_ready">zewnętrzne urządzenie jest niegotowe</string>
+ <string name="error_invalid_email">nieprawidłowy adres email \'%s\'</string>
+ <string name="error_key_size_minimum512bit">klucz musi mieć rozmiar co najmniej 512 bitów</string>
+ <string name="error_master_key_must_not_be_el_gamal">klucz EnGamal nie może być kluczem głównym</string>
+ <string name="error_unknown_algorithm_choice">wybrano nieznany algorytm</string>
+ <string name="error_user_id_needs_a_name">musisz wskazać imię</string>
+ <string name="error_user_id_no_email">nie znaleziono adresu email</string>
+ <string name="error_user_id_needs_an_email_address">musisz wskazać adres email</string>
+ <string name="error_key_needs_a_user_id">potrzeba co najmniej jednego identyfikatora użytkownika</string>
+ <string name="error_main_user_id_must_not_be_empty">główny identyfikator użytkownika nie może być pusty</string>
+ <string name="error_key_needs_master_key">potrzeba co najmniej klucza głównego</string>
+ <string name="error_no_encryption_keys_or_passphrase">nie podano hasła ani klucza szyfrującego</string>
+ <string name="error_signature_failed">podpisywanie nie powiodło się</string>
+ <string name="error_no_signature_passphrase">nie podano hasła</string>
+ <string name="error_no_signature_key">nie podano klucza podpisu</string>
+ <string name="error_invalid_data">nieprawidłowe dane</string>
+ <string name="error_corrupt_data">uszkodzone dane</string>
+ <string name="error_integrity_check_failed">Sprawdzanie spójności zakończone niepowodzeniem! Dane były modyfikowane!</string>
+ <string name="error_no_symmetric_encryption_packet">nie znaleziono pakietu z szyfrowaniem symatrycznym</string>
+ <string name="error_wrong_passphrase">nieprawidłowe hasło</string>
+ <string name="error_saving_keys">błąd przy zapisywaniu kluczy</string>
+ <string name="error_could_not_extract_private_key">nie można wyodrębnić klucza prywatnego</string>
+ <string name="error_only_files_are_supported">Dane binarne pozbawione pliku nie są obsługiwane. To jest wspierane tylko dla akcji ACTION_ENCRYPT_STREAM_AND_RETURN.</string>
+ <string name="error_jelly_bean_needed">Potrzebujesz Androida 4.1 Jelly Bean, aby korzystać z Android NFC Beam!</string>
+ <string name="error_nfc_needed">NCF jest niedostępne na twoim urządzeniu</string>
+ <string name="error_nothing_import">Nie ma nic do zaimportowania!</string>
+ <string name="error_expiry_must_come_after_creation">data wygaśnięcia musi być późniejsza niż data stworzenia</string>
+ <string name="error_can_not_delete_contact">nie możesz usunąć tego kontaktu, ponieważ należy do ciebie.</string>
+ <string name="error_can_not_delete_contacts">nie możesz usunąć tych kontaktów, ponieważ należą do ciebie:\n%s</string>
+ <string name="error_keyserver_insufficient_query">Niewystarczające zapytanie do serwera</string>
+ <string name="error_keyserver_query">Odpytywanie serwera zakończone niepowodzeniem</string>
+ <string name="error_keyserver_too_many_responses">Za dużo odpowiedzi</string>
+ <string name="error_import_file_no_content">Plik jest pusty</string>
+ <string name="error_generic_report_bug">Wystąpił błąd ogólny, proszę zgłoś go autorom OpenKeychain.</string>
+ <plurals name="error_can_not_delete_info">
+ <item quantity="one">Usuń go z ekranu \'Moje klucze\'!</item>
+ <item quantity="few">Usuń je z ekranu \'Moje klucze\'!</item>
+ <item quantity="other">Usuń je z ekranu \'Moje klucze\'!</item>
+ </plurals>
+ <plurals name="error_import_non_pgp_part">
+ <item quantity="one">Część wczytanego pliku jest poprawnym obiektem OpenPGP, ale nie jest kluczem OpenPGP</item>
+ <item quantity="few">Część wczytanego pliku to poprawne obiekty OpenPGP, ale nie są kluczami OpenPGP</item>
+ <item quantity="other">Część wczytanego pliku to poprawne obiekty OpenPGP, ale nie są kluczami OpenPGP</item>
+ </plurals>
+ <!--progress dialogs, usually ending in '…'-->
+ <string name="progress_done">Gotowe.</string>
+ <string name="progress_cancel">Anuluj</string>
+ <string name="progress_saving">zapisywanie...</string>
+ <string name="progress_importing">importowanie...</string>
+ <string name="progress_exporting">eksportowanie...</string>
+ <string name="progress_building_key">budowanie klucza...</string>
+ <string name="progress_preparing_master_key">przygotowywanie klucza glównego...</string>
+ <string name="progress_certifying_master_key">podpisywanie klucza głównego...</string>
+ <string name="progress_building_master_key">budowanie głównego zbioru kluczy...</string>
+ <string name="progress_adding_sub_keys">dodawanie podkluczy...</string>
+ <string name="progress_saving_key_ring">zapisywanie klucza...</string>
+ <plurals name="progress_exporting_key">
+ <item quantity="one">eksportowanie klucza...</item>
+ <item quantity="few">eksportowanie kluczy...</item>
+ <item quantity="other">eksportowanie kluczy...</item>
+ </plurals>
+ <plurals name="progress_generating">
+ <item quantity="one">generowanie klucza, może to potrwać do 3 minut...</item>
+ <item quantity="few">generowanie kluczy, może to potrwać do 3 minut...</item>
+ <item quantity="other">generowanie kluczy, może to potrwać do 3 minut...</item>
+ </plurals>
+ <string name="progress_extracting_signature_key">wyodrębnianie klucza podpisu...</string>
+ <string name="progress_extracting_key">wyodrębnianie klucza...</string>
+ <string name="progress_preparing_streams">przygotowywanie strumieni...</string>
+ <string name="progress_encrypting">szyfrowanie danych...</string>
+ <string name="progress_decrypting">deszyfrowywanie danych...</string>
+ <string name="progress_preparing_signature">przygotowywanie podpisu...</string>
+ <string name="progress_generating_signature">generowanie podpisu...</string>
+ <string name="progress_processing_signature">przetwarzanie podpisu...</string>
+ <string name="progress_verifying_signature">weryfikowanie podpisu...</string>
+ <string name="progress_signing">podpisywanie...</string>
+ <string name="progress_reading_data">czytanie danych...</string>
+ <string name="progress_finding_key">szukanie klucza...</string>
+ <string name="progress_decompressing_data">dekompresja danych...</string>
+ <string name="progress_verifying_integrity">weryfikacja spójności...</string>
+ <string name="progress_deleting_securely">usuwanie \'%s\' bezpiecznie…</string>
+ <string name="progress_querying">odpytywanie...</string>
+ <!--action strings-->
+ <string name="hint_public_keys">Wyszukaj klucze publiczne</string>
+ <string name="hint_secret_keys">Wyszukaj klucze prywatne</string>
+ <string name="action_share_key_with">Udostępnij klucz...</string>
+ <!--key bit length selections-->
+ <string name="key_size_512">512</string>
+ <string name="key_size_1024">1024</string>
+ <string name="key_size_2048">2048</string>
+ <string name="key_size_4096">4096</string>
+ <!--compression-->
+ <string name="compression_fast">szybka</string>
+ <string name="compression_very_slow">bardzo wolna</string>
+ <!--Help-->
+ <string name="help_tab_start">Początek</string>
+ <string name="help_tab_faq">FAQ</string>
+ <string name="help_tab_nfc_beam">NFC Beam</string>
+ <string name="help_tab_changelog">Dziennik zmian</string>
+ <string name="help_tab_about">O programie</string>
+ <string name="help_about_version">Wersja:</string>
+ <!--Import-->
+ <string name="import_import">Zaimportuj wybrane klucze</string>
+ <string name="import_sign_and_upload">Importuj, podpisz i wyślij wybrane klucze</string>
+ <string name="import_from_clipboard">Importuj ze schowka</string>
+ <plurals name="import_qr_code_missing">
+ <item quantity="one">Brakuje kodu QR o identyfikatorze %s</item>
+ <item quantity="few">Brakuje kodów QR o identyfikatorach %s</item>
+ <item quantity="other">Brakuje kodów QR o identyfikatorach %s</item>
+ </plurals>
+ <string name="import_qr_code_start_with_one">Zacznij od kodu QR o identyfikatorze 1</string>
+ <string name="import_qr_code_wrong">Kod QR zniekształcony! Spróbuj jeszcze raz!</string>
+ <string name="import_qr_code_finished">Skanowanie kodu QR zakończone!</string>
+ <string name="import_qr_code_too_short_fingerprint">Odcisk klucza zawarty w tym kodzie QR jest za krótki (&lt; 16 znaków)</string>
+ <string name="import_qr_scan_button">Odczytaj kod QR przy pomocy \'Barcode Scanner\'</string>
+ <string name="import_nfc_text">Aby odbierać klucze przez NFC, urządzenie musi być odblokowane.</string>
+ <string name="import_nfc_help_button">Pomoc</string>
+ <string name="import_clipboard_button">Odczytaj klucz ze schowka</string>
+ <!--Intent labels-->
+ <string name="intent_decrypt_file">Deszyfruj plik korzystając z OpenKeychain</string>
+ <string name="intent_import_key">Importuj klucz korzystając z OpenKeychain</string>
+ <string name="intent_send_encrypt">Zaszyfruj korzystając z OpenKeychain</string>
+ <string name="intent_send_decrypt">Deszyfruj korzystając z OpenKeychain</string>
+ <!--Remote API-->
+ <string name="api_no_apps">Brak zarejestrowanych aplikacji!\n\nZewnętrzne aplikacje mogą żądać dostępu do OpenKeychain. Po przyznaniu dostępu, będa wyświetlone tutaj.</string>
+ <string name="api_settings_show_advanced">Pokaż zaawanowane ustawienia</string>
+ <string name="api_settings_hide_advanced">Ukryj zaawansowane ustawienia</string>
+ <string name="api_settings_no_key">Nie wybrano klucza</string>
+ <string name="api_settings_select_key">Wybierz klucz</string>
+ <string name="api_settings_save">Zapisz</string>
+ <string name="api_settings_cancel">Anuluj</string>
+ <string name="api_settings_revoke">Odwołaj dostęp</string>
+ <string name="api_settings_package_name">Nazwa paczki</string>
+ <string name="api_settings_package_signature">Skrót SHA-256 podpisu paczki</string>
+ <string name="api_register_text">Wyświetlona aplikacja prosi o dostęp do OpenKeychain.\nZezwolić?\n\nOSTRZEZENIE: Jeżeli nie wiesz, czemu wyświetlił się ten komunikat, nie zezwalaj na dostęp! Możesz to również zrobić później, korzystając z ekranu \'Zarejestrowane aplikacje\'.</string>
+ <string name="api_register_allow">Zezwól na dostęp</string>
+ <string name="api_register_disallow">Odmów dostępu</string>
+ <string name="api_register_error_select_key">Wybierz klucz!</string>
+ <string name="api_select_pub_keys_missing_text">Nie znaleziono kluczy publiczych dla tych identyfikatorów użytkownika:</string>
+ <string name="api_select_pub_keys_dublicates_text">Więcej niż jeden klucz publiczny istnieje dla tych identyfikatorów użytkownika:</string>
+ <string name="api_select_pub_keys_text">Proszę przejrzeć listę adresatów!</string>
+ <string name="api_error_wrong_signature">Sprawdzanie podpisu zakończone niepowodzeniem! Czy zainstalowałeś tę aplikację z innego źródła? Jeżeli jesteś pewien, że nie jest to atak, odwołaj rejestrację teg aplikacji w OpenKeychain, a następnie zarejestruj ją ponownie.</string>
+ <!--Share-->
+ <string name="share_qr_code_dialog_title">Udostępnij przez kod QR</string>
+ <string name="share_qr_code_dialog_start">Przejdź przez wszystkiego kody QR korzystając z przycisku \'Nastepny\' i skanuj je pojedynczo.</string>
+ <string name="share_qr_code_dialog_fingerprint_text">Odcisk:</string>
+ <string name="share_qr_code_dialog_progress">Kod QR o identyfikatorze %1$d z %2$d</string>
+ <string name="share_nfc_dialog">Udostępnij przez NFC</string>
+ <!--Key list-->
+ <plurals name="key_list_selected_keys">
+ <item quantity="one">1 klucz wybrany.</item>
+ <item quantity="few">%d kluczy wybranych.</item>
+ <item quantity="other">%d kluczy wybranych.</item>
+ </plurals>
+ <string name="key_list_empty_text1">Żadne klucze nie są jeszcze dostępne...</string>
+ <string name="key_list_empty_text2">Możesz zacząć od</string>
+ <string name="key_list_empty_text3">lub</string>
+ <string name="key_list_empty_button_create">tworzenie własnego klucza</string>
+ <string name="key_list_empty_button_import">importowanie kluczy.</string>
+ <!--Key view-->
+ <string name="key_view_action_edit">Edytuj ten klucz</string>
+ <string name="key_view_action_encrypt">Zaszyfruj do tego kontaktu</string>
+ <string name="key_view_action_certify">Certyfikuj klucz tego kontaktu</string>
+ <string name="key_view_tab_main">Informacje</string>
+ <string name="key_view_tab_certs">Certyfikaty</string>
+ <!--Navigation Drawer-->
+ <string name="nav_contacts">Kontakty</string>
+ <string name="nav_encrypt">Zaszyfruj</string>
+ <string name="nav_decrypt">Deszyfruj</string>
+ <string name="nav_import">importuj klucze</string>
+ <string name="nav_secret_keys">Moje klucze</string>
+ <string name="nav_apps">Zarejestrowane aplikacje</string>
+ <string name="drawer_open">Otwórz panel nawigacji</string>
+ <string name="drawer_close">Zamknij panel nawigacji</string>
+ <string name="edit">Edytuj</string>
+ <string name="my_keys">Moje klucze</string>
+ <string name="label_secret_key">Klucz prywatny</string>
+ <string name="secret_key_yes">dostępny</string>
+ <string name="secret_key_no">niedostepny</string>
+ <string name="section_uids_to_sign">Identyfikator użytkownika do podpisu</string>
+ <string name="progress_re_adding_certs">Ponowne stosowanie certyfikatów</string>
+ <!--hints-->
+</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-pt-rBR/strings.xml b/OpenPGP-Keychain/src/main/res/values-pt-rBR/strings.xml
index 6bb115049..3d00a143f 100644
--- a/OpenPGP-Keychain/src/main/res/values-pt-rBR/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-pt-rBR/strings.xml
@@ -23,4 +23,5 @@
<!--Key list-->
<!--Key view-->
<!--Navigation Drawer-->
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml
index 22f676ccb..55e778bee 100644
--- a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml
@@ -16,6 +16,7 @@
<string name="title_change_passphrase">Изменить пароль</string>
<string name="title_set_passphrase">Задать пароль</string>
<string name="title_send_email">Отправить...</string>
+ <string name="title_send_file">Отправить файл</string>
<string name="title_encrypt_to_file">Зашифровать в файл</string>
<string name="title_decrypt_to_file">Расшифровать в файл</string>
<string name="title_import_keys">Импорт ключей</string>
@@ -63,6 +64,8 @@
<string name="btn_clipboard">Буфер обмена</string>
<string name="btn_share">Поделиться...</string>
<string name="btn_lookup_key">Найти ключ</string>
+ <string name="btn_encryption_advanced_settings_show">Показать расширенные настройки</string>
+ <string name="btn_encryption_advanced_settings_hide">Скрыть расширенные настройки</string>
<!--menu-->
<string name="menu_preferences">Настройки</string>
<string name="menu_help">Помощь</string>
@@ -76,10 +79,8 @@
<string name="menu_create_key">Создать ключ</string>
<string name="menu_create_key_expert">Создать ключ (эксперт)</string>
<string name="menu_search">Поиск</string>
- <string name="menu_key_server">Импорт с сервера ключей</string>
<string name="menu_update_key">Обновить с сервера ключей</string>
<string name="menu_export_key_to_server">Загрузить на сервер ключей</string>
- <string name="menu_share">Отправить...</string>
<string name="menu_share_title_fingerprint">Отправить отпечаток...</string>
<string name="menu_share_title">Отправить ключ...</string>
<string name="menu_share_default_fingerprint">Отправить</string>
@@ -105,6 +106,7 @@
<string name="label_select_public_keys">Получатели</string>
<string name="label_delete_after_encryption">Удалить после шифрования</string>
<string name="label_delete_after_decryption">Удалить после расшифровки</string>
+ <string name="label_share_after_encryption">Отправить после шифрования</string>
<string name="label_encryption_algorithm">Алгоритм шифрования</string>
<string name="label_hash_algorithm">Hash-алгоритм</string>
<string name="label_asymmetric">Публичный ключ</string>
@@ -135,6 +137,7 @@
<string name="user_id_no_name">&lt;нет имени&gt;</string>
<string name="none">&lt;нет&gt;</string>
<string name="no_key">&lt;нет ключа&gt;</string>
+ <string name="no_email">&lt;нет email&gt;</string>
<string name="unknown_status"></string>
<string name="can_encrypt">шифрование</string>
<string name="can_sign">подпись</string>
@@ -254,6 +257,7 @@
<string name="error_master_key_must_not_be_el_gamal">ключ ElGamal не может быть основным</string>
<string name="error_unknown_algorithm_choice">выбран неизвестный алгоритм</string>
<string name="error_user_id_needs_a_name">необходимо указать имя</string>
+ <string name="error_user_id_no_email">email не найден</string>
<string name="error_user_id_needs_an_email_address">необходимо указать email</string>
<string name="error_key_needs_a_user_id">необходим хотя бы один id пользователя</string>
<string name="error_main_user_id_must_not_be_empty">основная запись пользователя не может быть пустой</string>
@@ -279,18 +283,24 @@
<string name="error_keyserver_insufficient_query">Ограничение запроса сервера</string>
<string name="error_keyserver_query">Сбой запроса сервера ключей</string>
<string name="error_keyserver_too_many_responses">Слишком много ответов</string>
+ <string name="error_import_file_no_content">Файл пуст</string>
+ <string name="error_generic_report_bug">Выявлена ошибка. Пожалуйста, сообщите о ней разработчику.</string>
<plurals name="error_can_not_delete_info">
<item quantity="one">Пожалуйста, удалите его в разделе \'Мои ключи\'!</item>
<item quantity="few">Пожалуйста, удалите их в разделе \'Мои ключи\'!</item>
<item quantity="other">Пожалуйста, удалите их в разделе \'Мои ключи\'!</item>
</plurals>
+ <plurals name="error_import_non_pgp_part">
+ <item quantity="one">часть загруженного файла содержит данные OpenPGP, но это не ключ</item>
+ <item quantity="few">части загруженного файла содержат данные OpenPGP, но это не ключ</item>
+ <item quantity="other">части загруженного файла содержат данные OpenPGP, но это не ключ</item>
+ </plurals>
<!--progress dialogs, usually ending in '…'-->
- <string name="progress_done">готово.</string>
- <string name="progress_cancel">отмена</string>
+ <string name="progress_done">Готово.</string>
+ <string name="progress_cancel">Отмена</string>
<string name="progress_saving">сохранение...</string>
<string name="progress_importing">импорт...</string>
<string name="progress_exporting">экспорт...</string>
- <string name="progress_generating">создание ключа. это может занять до 3 минут...</string>
<string name="progress_building_key">создание ключа...</string>
<string name="progress_preparing_master_key">подготовка основного ключа...</string>
<string name="progress_certifying_master_key">сертификация основного ключа...</string>
@@ -302,6 +312,11 @@
<item quantity="few">экспорт ключей...</item>
<item quantity="other">экспорт ключей...</item>
</plurals>
+ <plurals name="progress_generating">
+ <item quantity="one">создание ключа. это может занять до 3 минут...</item>
+ <item quantity="few">создание ключей. это может занять до 3 минут...</item>
+ <item quantity="other">создание ключей. это может занять до 3 минут...</item>
+ </plurals>
<string name="progress_extracting_signature_key">извлечение подписи ключа...</string>
<string name="progress_extracting_key">извлечение ключа...</string>
<string name="progress_preparing_streams">подготовка к передаче...</string>
@@ -408,4 +423,5 @@
<string name="nav_apps">Связанные приложения</string>
<string name="drawer_open">Открыть панель навигации</string>
<string name="drawer_close">Закрыть панель навигации</string>
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-sl-rSI/strings.xml b/OpenPGP-Keychain/src/main/res/values-sl-rSI/strings.xml
index 6bb115049..3d00a143f 100644
--- a/OpenPGP-Keychain/src/main/res/values-sl-rSI/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-sl-rSI/strings.xml
@@ -23,4 +23,5 @@
<!--Key list-->
<!--Key view-->
<!--Navigation Drawer-->
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml
index 5bb5225b5..174d8538f 100644
--- a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml
@@ -95,7 +95,6 @@
<string name="error_key_size_minimum512bit">anahtar uzunluğu en az 512bit olmalı</string>
<string name="error_corrupt_data">bozuk veri</string>
<!--progress dialogs, usually ending in '…'-->
- <string name="progress_done">bitti.</string>
<string name="progress_saving">kaydediliyor...</string>
<string name="progress_importing">alıyor...</string>
<string name="progress_exporting">veriyor...</string>
@@ -135,4 +134,5 @@
<!--Key list-->
<!--Key view-->
<!--Navigation Drawer-->
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml
index 7ccb661d3..58ac643af 100644
--- a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml
@@ -64,6 +64,8 @@
<string name="btn_clipboard">Буфер обміну</string>
<string name="btn_share">Поділитися через…</string>
<string name="btn_lookup_key">Шукати ключ</string>
+ <string name="btn_encryption_advanced_settings_show">Показати додаткові налаштування</string>
+ <string name="btn_encryption_advanced_settings_hide">Приховати додаткові налаштування</string>
<!--menu-->
<string name="menu_preferences">Параметри</string>
<string name="menu_help">Довідка</string>
@@ -72,15 +74,17 @@
<string name="menu_import">Імпорт</string>
<string name="menu_import_from_nfc">Імпорт з NFC</string>
<string name="menu_export_keys">Експортувати усі ключі</string>
+ <string name="menu_export_secret_keys">Експортувати усі секретні ключі</string>
<string name="menu_export_key">Експорт до файлу</string>
<string name="menu_delete_key">Вилучити ключ</string>
<string name="menu_create_key">Створити ключ</string>
<string name="menu_create_key_expert">Створити ключ (експерт)</string>
<string name="menu_search">Пошук</string>
- <string name="menu_key_server">Імпорт з сервера ключів</string>
+ <string name="menu_import_from_key_server">Сервер ключів</string>
+ <string name="menu_key_server">Сервер ключів…</string>
<string name="menu_update_key">Оновити з сервера ключів</string>
<string name="menu_export_key_to_server">Завантажити на сервер ключів</string>
- <string name="menu_share">Поділитися</string>
+ <string name="menu_share">Поділитися…</string>
<string name="menu_share_title_fingerprint">Поділитися відбитком…</string>
<string name="menu_share_title">Поділитися цілим ключем…</string>
<string name="menu_share_default_fingerprint">з…</string>
@@ -139,12 +143,18 @@
<string name="user_id_no_name">&lt;без імені&gt;</string>
<string name="none">&lt;жоден&gt;</string>
<string name="no_key">&lt;без ключа&gt;</string>
+ <string name="no_email">&lt;Немає ел. пошти&gt;</string>
<string name="unknown_status"></string>
<string name="can_encrypt">можна зашифрувати</string>
<string name="can_sign">можна підписати</string>
<string name="expired">закінчився</string>
<string name="revoked">скасовано</string>
<string name="user_id">ІД користувача</string>
+ <plurals name="n_contacts">
+ <item quantity="one">1 контакт</item>
+ <item quantity="few">%d контакти</item>
+ <item quantity="other">%d контактів</item>
+ </plurals>
<plurals name="n_key_servers">
<item quantity="one">%d сервер ключів</item>
<item quantity="few">%d сервери ключів</item>
@@ -201,6 +211,7 @@
<string name="key_deletion_confirmation">Ви справді хочете вилучити ключ \'%s\'?\nВи не зможете це відмінити!</string>
<string name="key_deletion_confirmation_multi">Ви справді хочете вилучити усі вибрані ключі?\nВи не зможете це відмінити!</string>
<string name="secret_key_deletion_confirmation">Ви справді хочете вилучити секретний ключ \'%s\'?\nВи не зможете це відмінити!</string>
+ <string name="also_export_secret_keys">Також експортувати секретні ключі?</string>
<plurals name="keys_added_and_updated_1">
<item quantity="one">Успішно додано %d ключ</item>
<item quantity="few">Успішно додано %d ключі</item>
@@ -226,6 +237,7 @@
<string name="keys_exported">Успішно експортовано %d ключів.</string>
<string name="no_keys_exported">Жодного ключа не експортовано.</string>
<string name="key_creation_el_gamal_info">Примітка: тільки підключі підтримують ElGamal, а для ElGamal буде використаний найближчий розмір ключа з 1536, 2048, 3072, 4096, або 8192.</string>
+ <string name="key_creation_weak_rsa_info">Примітка: генерація ключа RSA з довжиною 1024 біти і менше вважається небезпечною і вона вимкнена для генерації нових ключів.</string>
<string name="key_not_found">Не можливо знайти ключ %08X.</string>
<plurals name="keys_found">
<item quantity="one">Знайдено %d ключ.</item>
@@ -259,6 +271,7 @@
<string name="error_master_key_must_not_be_el_gamal">основний ключ не може бути ключем ElGamal</string>
<string name="error_unknown_algorithm_choice">вибір невідомого алгоритму</string>
<string name="error_user_id_needs_a_name">вам потрібно вказати назву</string>
+ <string name="error_user_id_no_email">жодного листа не знайдено</string>
<string name="error_user_id_needs_an_email_address">вам потрібно вказати електронну адресу</string>
<string name="error_key_needs_a_user_id">потрібний хоча б один ІД користувача</string>
<string name="error_main_user_id_must_not_be_empty">ІД основного користувача не має бути порожнім</string>
@@ -297,12 +310,11 @@
<item quantity="other">частин завантаженого файлу є вірним об\'єктом OpenPGP, але не ключем OpenPGP</item>
</plurals>
<!--progress dialogs, usually ending in '…'-->
- <string name="progress_done">готово.</string>
- <string name="progress_cancel">cкасувати</string>
+ <string name="progress_done">Готово.</string>
+ <string name="progress_cancel">Скасувати</string>
<string name="progress_saving">збереження…</string>
<string name="progress_importing">імпортується…</string>
<string name="progress_exporting">експортується…</string>
- <string name="progress_generating">генерується ключ, вона може тривати до 3 хвилин…</string>
<string name="progress_building_key">будується ключ…</string>
<string name="progress_preparing_master_key">підготовка основного ключа…</string>
<string name="progress_certifying_master_key">сертифікація основного ключа…</string>
@@ -314,6 +326,11 @@
<item quantity="few">експортуються ключі…</item>
<item quantity="other">експортуються ключі…</item>
</plurals>
+ <plurals name="progress_generating">
+ <item quantity="one">генерується ключ, це може тривати до 3 хвилини</item>
+ <item quantity="few">генеруються ключі, це може тривати до 3 хвилини</item>
+ <item quantity="other">генеруються ключі, це може тривати до 3 хвилини</item>
+ </plurals>
<string name="progress_extracting_signature_key">видобування ключа підпису…</string>
<string name="progress_extracting_key">видобувається ключа…</string>
<string name="progress_preparing_streams">підготовка потоків…</string>
@@ -344,6 +361,7 @@
<string name="compression_very_slow">дуже повільне</string>
<!--Help-->
<string name="help_tab_start">Початок</string>
+ <string name="help_tab_faq">ЧАП</string>
<string name="help_tab_nfc_beam">NFC промінь</string>
<string name="help_tab_changelog">Журнал змін</string>
<string name="help_tab_about">Про</string>
@@ -407,6 +425,7 @@
<string name="key_list_empty_button_create">створюється ваш власний ключ</string>
<string name="key_list_empty_button_import">імпортуюся ключі.</string>
<!--Key view-->
+ <string name="key_view_action_edit">Редагувати цей ключ</string>
<string name="key_view_action_encrypt">Зашифрувати у цей контакт</string>
<string name="key_view_action_certify">Сертифікувати ключ цього контакту</string>
<string name="key_view_tab_main">Інформація</string>
@@ -420,4 +439,12 @@
<string name="nav_apps">Зареєстровані програми</string>
<string name="drawer_open">Відкрити панель навігації</string>
<string name="drawer_close">Закрити панель навігації</string>
+ <string name="edit">Редагувати</string>
+ <string name="my_keys">Мої ключі</string>
+ <string name="label_secret_key">Секретний ключ</string>
+ <string name="secret_key_yes">доступний</string>
+ <string name="secret_key_no">недоступний</string>
+ <string name="section_uids_to_sign">ІД користувача для реєстрації</string>
+ <string name="progress_re_adding_certs">Перезастосування сертифікатів</string>
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-zh-rTW/strings.xml b/OpenPGP-Keychain/src/main/res/values-zh-rTW/strings.xml
new file mode 100644
index 000000000..3d00a143f
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/values-zh-rTW/strings.xml
@@ -0,0 +1,27 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+ <!--title-->
+ <!--section-->
+ <!--button-->
+ <!--menu-->
+ <!--label-->
+ <string name="unknown_status"></string>
+ <!--choice-->
+ <!--sentences-->
+ <!--errors
+ no punctuation, all lowercase,
+ they will be put after "error_message", e.g. "Error: file not found"-->
+ <!--progress dialogs, usually ending in '…'-->
+ <!--action strings-->
+ <!--key bit length selections-->
+ <!--compression-->
+ <!--Help-->
+ <!--Import-->
+ <!--Intent labels-->
+ <!--Remote API-->
+ <!--Share-->
+ <!--Key list-->
+ <!--Key view-->
+ <!--Navigation Drawer-->
+ <!--hints-->
+</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-zh/strings.xml b/OpenPGP-Keychain/src/main/res/values-zh/strings.xml
index 80413d589..244e7e57b 100644
--- a/OpenPGP-Keychain/src/main/res/values-zh/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-zh/strings.xml
@@ -1,6 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<!--title-->
+ <string name="title_manage_public_keys">聯絡人</string>
<string name="title_select_recipients">选择公钥</string>
<string name="title_select_secret_key">选择私钥</string>
<string name="title_encrypt">加密</string>
@@ -50,7 +51,6 @@
<string name="menu_create_key">创建密钥</string>
<string name="menu_create_key_expert">创建密钥(专家)</string>
<string name="menu_search">搜索</string>
- <string name="menu_share">分享</string>
<string name="menu_copy_to_clipboard">复制到剪贴板</string>
<string name="menu_sign_key">签署密钥</string>
<string name="menu_key_edit_cancel">取消</string>
@@ -135,7 +135,6 @@
<string name="error_corrupt_data">损坏的数据</string>
<string name="error_wrong_passphrase">错误的密语</string>
<!--progress dialogs, usually ending in '…'-->
- <string name="progress_done">完成。</string>
<string name="progress_saving">保存...</string>
<string name="progress_importing">导入中...</string>
<string name="progress_exporting">导出中...</string>
@@ -187,4 +186,5 @@
<string name="nav_decrypt">解密</string>
<string name="nav_import">导入密钥</string>
<string name="nav_secret_keys">我的密钥</string>
+ <!--hints-->
</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values/attr.xml b/OpenPGP-Keychain/src/main/res/values/attr.xml
new file mode 100644
index 000000000..86622b3e0
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/values/attr.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <declare-styleable name="FoldableLinearLayout">
+ <attr name="foldedLabel" format="string" />
+ <attr name="unFoldedLabel" format="string" />
+ <attr name="foldedIcon" format="string" />
+ <attr name="unFoldedIcon" format="string" />
+ </declare-styleable>
+
+</resources> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml
index 9b4ab0747..5bf7ca8ca 100644
--- a/OpenPGP-Keychain/src/main/res/values/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values/strings.xml
@@ -220,6 +220,8 @@
<string name="key_deletion_confirmation">Do you really want to delete the key \'%s\'?\nYou can\'t undo this!</string>
<string name="key_deletion_confirmation_multi">Do you really want to delete all selected keys?\nYou can\'t undo this!</string>
<string name="secret_key_deletion_confirmation">Do you really want to delete the SECRET key \'%s\'?\nYou can\'t undo this!</string>
+ <string name="public_key_deletetion_confirmation">Do you really want to delete the PUBLIC key \'%s\'?\nYou can\'t undo this!</string>
+ <string name="secret_key_delete_text">Delete Secret Keys ?</string>
<string name="also_export_secret_keys">Also export secret keys?</string>
<plurals name="keys_added_and_updated_1">
@@ -410,6 +412,8 @@
<!-- Remote API -->
<string name="api_no_apps">No registered applications!\n\nThird-party applications can request access to OpenKeychain. After granting access, they will be listed here.</string>
+ <string name="api_settings_show_info">Show advanced information</string>
+ <string name="api_settings_hide_info">Hide advanced information</string>
<string name="api_settings_show_advanced">Show advanced settings</string>
<string name="api_settings_hide_advanced">Hide advanced settings</string>
<string name="api_settings_no_key">No key selected</string>
@@ -419,6 +423,8 @@
<string name="api_settings_revoke">Revoke access</string>
<string name="api_settings_package_name">Package Name</string>
<string name="api_settings_package_signature">SHA-256 of Package Signature</string>
+ <string name="api_settings_accounts">Accounts</string>
+ <string name="api_settings_accounts_empty">No accounts attached to this application.</string>
<string name="api_register_text">The displayed application requests access to OpenKeychain.\nAllow access?\n\nWARNING: If you do not know why this screen appeared, disallow access! You can revoke access later using the \'Registered Applications\' screen.</string>
<string name="api_register_allow">Allow access</string>
<string name="api_register_disallow">Disallow access</string>
@@ -471,4 +477,7 @@
<string name="section_uids_to_sign">User IDs to sign</string>
<string name="progress_re_adding_certs">Reapplying certificates</string>
+ <!-- hints -->
+ <string name="encrypt_content_edit_text_hint">Write message here to encrypt…</string>
+
</resources>