aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Breitmoser <valodim@mugenguild.com>2014-03-12 23:45:21 +0100
committerVincent Breitmoser <valodim@mugenguild.com>2014-03-12 23:45:21 +0100
commita9c9b6132c7b122f8155ce9fc6c21c89e5b8c298 (patch)
tree78671569d3e84f5ed3db638a194981bc7c053a88
parentedb98c67f4031b8c3c1d43b49bba733171119be2 (diff)
parent69f5bf6b577234053e700a43a4a7ba721e827c6a (diff)
downloadopen-keychain-a9c9b6132c7b122f8155ce9fc6c21c89e5b8c298.tar.gz
open-keychain-a9c9b6132c7b122f8155ce9fc6c21c89e5b8c298.tar.bz2
open-keychain-a9c9b6132c7b122f8155ce9fc6c21c89e5b8c298.zip
Merge branch 'master' into certs
Conflicts: OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
-rw-r--r--.travis.yml2
-rw-r--r--OpenPGP-Keychain-API/build.gradle2
-rw-r--r--OpenPGP-Keychain-API/example-app/build.gradle7
-rw-r--r--OpenPGP-Keychain-API/example-app/src/main/java/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java4
-rw-r--r--OpenPGP-Keychain-API/gradle/wrapper/gradle-wrapper.properties4
-rw-r--r--OpenPGP-Keychain-API/libraries/openkeychain-api-library/.gitignore (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/.gitignore)0
-rw-r--r--OpenPGP-Keychain-API/libraries/openkeychain-api-library/AndroidManifest.xml (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/AndroidManifest.xml)0
-rw-r--r--OpenPGP-Keychain-API/libraries/openkeychain-api-library/LICENSE (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/LICENSE)0
-rw-r--r--OpenPGP-Keychain-API/libraries/openkeychain-api-library/build.gradle (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/build.gradle)4
-rw-r--r--OpenPGP-Keychain-API/libraries/openkeychain-api-library/build.xml92
-rw-r--r--OpenPGP-Keychain-API/libraries/openkeychain-api-library/proguard-project.txt20
-rw-r--r--OpenPGP-Keychain-API/libraries/openkeychain-api-library/project.properties (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/project.properties)0
-rw-r--r--OpenPGP-Keychain-API/libraries/openkeychain-api-library/src/org/sufficientlysecure/keychain/api/OpenKeychainIntents.java (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/sufficientlysecure/keychain/api/OpenKeychainIntents.java)0
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/.gitignore29
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/AndroidManifest.xml13
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/LICENSE202
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/build.gradle35
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/build.xml92
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/proguard-project.txt20
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/project.properties15
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-hdpi/ic_action_cancel_launchersize.png (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-hdpi/ic_action_cancel_launchersize.png)bin1520 -> 1520 bytes
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-hdpi/ic_action_cancel_launchersize_light.png (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-hdpi/ic_action_cancel_launchersize_light.png)bin1940 -> 1940 bytes
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-mdpi/ic_action_cancel_launchersize.png (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-mdpi/ic_action_cancel_launchersize.png)bin1032 -> 1032 bytes
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-mdpi/ic_action_cancel_launchersize_light.png (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-mdpi/ic_action_cancel_launchersize_light.png)bin1098 -> 1098 bytes
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize.png (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize.png)bin1570 -> 1570 bytes
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize_light.png (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize_light.png)bin2039 -> 2039 bytes
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize.png (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize.png)bin2345 -> 2345 bytes
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize_light.png (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize_light.png)bin2404 -> 2404 bytes
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/res/values/strings.xml (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/res/values/strings.xml)0
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl)0
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/OpenPgpError.java (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpError.java)0
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java)18
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java)130
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java)2
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java)0
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java)0
-rw-r--r--OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java (renamed from OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java)0
-rw-r--r--OpenPGP-Keychain-API/settings.gradle3
-rw-r--r--OpenPGP-Keychain/build.gradle5
-rw-r--r--OpenPGP-Keychain/src/main/AndroidManifest.xml43
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java1
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java46
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java41
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java20
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java8
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java6
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java206
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java88
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java3
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java80
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java138
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java12
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java5
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java64
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java57
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java78
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java5
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java183
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java8
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java63
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java57
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java95
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java13
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java86
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java29
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java211
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java300
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java8
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java180
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java86
-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.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java27
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/HighlightQueryCursorAdapter.java66
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java65
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java5
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java39
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java11
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java3
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java9
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java1
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java12
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java23
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java1
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java52
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java111
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java17
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java6
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java12
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_save.pngbin0 -> 398 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_search.pngbin0 -> 702 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_secure.pngbin0 -> 394 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_select_all.pngbin0 -> 507 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_save.pngbin0 -> 359 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_search.pngbin0 -> 2349 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_secure.pngbin0 -> 317 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_select_all.pngbin0 -> 292 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_save.pngbin0 -> 451 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_search.pngbin0 -> 900 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_secure.pngbin0 -> 510 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_select_all.pngbin0 -> 351 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_save.pngbin0 -> 500 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_search.pngbin0 -> 1153 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_secure.pngbin0 -> 624 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_select_all.pngbin0 -> 563 bytes
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/api_app_error_message.xml1
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/api_app_select_pub_keys_activity.xml1
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/drawer_list.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/edit_key_activity.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/edit_key_key_item.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/edit_key_user_id_item.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/encrypt_activity.xml119
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/import_keys_list_entry.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/key_list_fragment.xml141
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/key_list_item.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/key_server_export.xml1
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/passphrase_repeat_dialog.xml8
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/select_key_item.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/select_secret_key_layout_fragment.xml28
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml2
-rw-r--r--OpenPGP-Keychain/src/main/res/menu/key_list.xml11
-rw-r--r--OpenPGP-Keychain/src/main/res/menu/key_list_multi.xml11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-de/help_about.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html2
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-el/help_about.html45
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-el/help_changelog.html108
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-el/help_nfc_beam.html12
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-el/help_start.html19
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-el/nfc_beam_share.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_about.html45
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_changelog.html108
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_nfc_beam.html12
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_start.html19
-rw-r--r--OpenPGP-Keychain/src/main/res/raw-fa-rIR/nfc_beam_share.html11
-rw-r--r--OpenPGP-Keychain/src/main/res/values-de/strings.xml7
-rw-r--r--OpenPGP-Keychain/src/main/res/values-el/strings.xml53
-rw-r--r--OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml1
-rw-r--r--OpenPGP-Keychain/src/main/res/values-es/strings.xml16
-rw-r--r--OpenPGP-Keychain/src/main/res/values-fa-rIR/strings.xml26
-rw-r--r--OpenPGP-Keychain/src/main/res/values-fr/strings.xml24
-rw-r--r--OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml24
-rw-r--r--OpenPGP-Keychain/src/main/res/values-ja/strings.xml23
-rw-r--r--OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml1
-rw-r--r--OpenPGP-Keychain/src/main/res/values-ru/strings.xml5
-rw-r--r--OpenPGP-Keychain/src/main/res/values-uk/strings.xml25
-rw-r--r--OpenPGP-Keychain/src/main/res/values-zh/strings.xml30
-rw-r--r--OpenPGP-Keychain/src/main/res/values/arrays.xml4
-rw-r--r--OpenPGP-Keychain/src/main/res/values/strings.xml25
-rw-r--r--OpenPGP-Keychain/src/main/res/xml/adv_preferences.xml (renamed from OpenPGP-Keychain/src/main/res/xml/preferences.xml)17
-rw-r--r--OpenPGP-Keychain/src/main/res/xml/gen_preferences.xml32
-rw-r--r--OpenPGP-Keychain/src/main/res/xml/preference_headers.xml25
-rw-r--r--OpenPGP-Keychain/src/main/res/xml/preference_headers_legacy.xml29
-rw-r--r--README.md21
-rw-r--r--build.gradle4
-rw-r--r--gradle/wrapper/gradle-wrapper.properties4
-rw-r--r--libraries/Android-AppMsg/library/build.gradle2
-rw-r--r--libraries/AndroidBootstrap/build.gradle4
-rw-r--r--libraries/HtmlTextView/build.gradle4
-rw-r--r--libraries/HtmlTextView/project.properties2
-rw-r--r--libraries/StickyListHeaders/library/build.gradle2
-rw-r--r--libraries/zxing-android-integration/build.gradle2
-rw-r--r--libraries/zxing/build.gradle2
-rw-r--r--settings.gradle3
-rwxr-xr-xtools/checkstyle1
-rw-r--r--tools/checkstyle.xml356
178 files changed, 3767 insertions, 1187 deletions
diff --git a/.travis.yml b/.travis.yml
index 28827f332..54db1a965 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,7 +10,7 @@ before_install:
- export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
# Install required Android components.
- - echo "y" | android update sdk -a --filter build-tools-19.0.1,android-19,platform-tools,extra-android-support,extra-android-m2repository,android-17 --no-ui --force
+ - echo "y" | android update sdk -a --filter build-tools-19.0.3,android-19,platform-tools,extra-android-support,extra-android-m2repository --no-ui --force
install: echo "Installation done"
script: gradle assemble -S -q
diff --git a/OpenPGP-Keychain-API/build.gradle b/OpenPGP-Keychain-API/build.gradle
index 2e41492a3..0ce5dc8c0 100644
--- a/OpenPGP-Keychain-API/build.gradle
+++ b/OpenPGP-Keychain-API/build.gradle
@@ -1,3 +1,3 @@
task wrapper(type: Wrapper) {
gradleVersion = '1.10'
-} \ No newline at end of file
+}
diff --git a/OpenPGP-Keychain-API/example-app/build.gradle b/OpenPGP-Keychain-API/example-app/build.gradle
index 1f8854431..e7a25e689 100644
--- a/OpenPGP-Keychain-API/example-app/build.gradle
+++ b/OpenPGP-Keychain-API/example-app/build.gradle
@@ -5,7 +5,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:0.8.3'
+ classpath 'com.android.tools.build:gradle:0.9.0'
}
}
@@ -13,12 +13,13 @@ apply plugin: 'android'
dependencies {
compile 'com.android.support:support-v4:19.0.1'
- compile project(':libraries:keychain-api-library')
+ compile project(':libraries:openpgp-api-library')
+ compile project(':libraries:openkeychain-api-library')
}
android {
compileSdkVersion 19
- buildToolsVersion "19.0.1"
+ buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 9
diff --git a/OpenPGP-Keychain-API/example-app/src/main/java/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java b/OpenPGP-Keychain-API/example-app/src/main/java/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java
index 4d143ade6..a660b1c9a 100644
--- a/OpenPGP-Keychain-API/example-app/src/main/java/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java
+++ b/OpenPGP-Keychain-API/example-app/src/main/java/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java
@@ -202,7 +202,7 @@ public class OpenPgpProviderActivity extends Activity {
break;
}
case OpenPgpApi.RESULT_CODE_ERROR: {
- OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERRORS);
+ OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR);
handleError(error);
break;
}
@@ -234,7 +234,7 @@ public class OpenPgpProviderActivity extends Activity {
}
public void signAndEncrypt(Intent data) {
- data.setAction(OpenPgpApi.ACTION_SIGN_AND_ENCTYPT);
+ data.setAction(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT);
data.putExtra(OpenPgpApi.EXTRA_USER_IDS, mEncryptUserIds.getText().toString().split(","));
data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
diff --git a/OpenPGP-Keychain-API/gradle/wrapper/gradle-wrapper.properties b/OpenPGP-Keychain-API/gradle/wrapper/gradle-wrapper.properties
index 932184188..d8e0b5b29 100644
--- a/OpenPGP-Keychain-API/gradle/wrapper/gradle-wrapper.properties
+++ b/OpenPGP-Keychain-API/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Fri Feb 14 01:26:40 CET 2014
+#Thu Mar 06 22:23:44 CET 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/.gitignore b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/.gitignore
index aa8bb5760..aa8bb5760 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/.gitignore
+++ b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/.gitignore
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/AndroidManifest.xml b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/AndroidManifest.xml
index 768922c22..768922c22 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/AndroidManifest.xml
+++ b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/AndroidManifest.xml
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/LICENSE b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/LICENSE
index d64569567..d64569567 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/LICENSE
+++ b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/LICENSE
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/build.gradle b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/build.gradle
index 1d5911783..98c9a3bd6 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/build.gradle
+++ b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/build.gradle
@@ -5,7 +5,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:0.8.3'
+ classpath 'com.android.tools.build:gradle:0.9.0'
}
}
@@ -13,7 +13,7 @@ apply plugin: 'android-library'
android {
compileSdkVersion 19
- buildToolsVersion '19.0.1'
+ buildToolsVersion '19.0.3'
// NOTE: We are using the old folder structure to also support Eclipse
sourceSets {
diff --git a/OpenPGP-Keychain-API/libraries/openkeychain-api-library/build.xml b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/build.xml
new file mode 100644
index 000000000..48ebf198c
--- /dev/null
+++ b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/build.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="keychain-api-library" default="help">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <property file="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="ant.properties" />
+
+ <!-- if sdk.dir was not set from one of the property file, then
+ get it from the ANDROID_HOME env var.
+ This must be done before we load project.properties since
+ the proguard config can use sdk.dir -->
+ <property environment="env" />
+ <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+ <isset property="env.ANDROID_HOME" />
+ </condition>
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <loadproperties srcFile="project.properties" />
+
+ <!-- quick check on sdk.dir -->
+ <fail
+ message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+ unless="sdk.dir"
+ />
+
+ <!--
+ Import per project custom build rules if present at the root of the project.
+ This is the place to put custom intermediary targets such as:
+ -pre-build
+ -pre-compile
+ -post-compile (This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir})
+ -post-package
+ -post-build
+ -pre-clean
+ -->
+ <import file="custom_rules.xml" optional="true" />
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: 1 -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/OpenPGP-Keychain-API/libraries/openkeychain-api-library/proguard-project.txt b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/proguard-project.txt
new file mode 100644
index 000000000..f2fe1559a
--- /dev/null
+++ b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/project.properties b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/project.properties
index 91d2b0246..91d2b0246 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/project.properties
+++ b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/project.properties
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/sufficientlysecure/keychain/api/OpenKeychainIntents.java b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/src/org/sufficientlysecure/keychain/api/OpenKeychainIntents.java
index 15aceb534..15aceb534 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/sufficientlysecure/keychain/api/OpenKeychainIntents.java
+++ b/OpenPGP-Keychain-API/libraries/openkeychain-api-library/src/org/sufficientlysecure/keychain/api/OpenKeychainIntents.java
diff --git a/OpenPGP-Keychain-API/libraries/openpgp-api-library/.gitignore b/OpenPGP-Keychain-API/libraries/openpgp-api-library/.gitignore
new file mode 100644
index 000000000..aa8bb5760
--- /dev/null
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/.gitignore
@@ -0,0 +1,29 @@
+#Android specific
+bin
+gen
+obj
+lint.xml
+local.properties
+release.properties
+ant.properties
+*.class
+*.apk
+
+#Gradle
+.gradle
+build
+gradle.properties
+
+#Maven
+target
+pom.xml.*
+
+#Eclipse
+.project
+.classpath
+.settings
+.metadata
+
+#IntelliJ IDEA
+.idea
+*.iml
diff --git a/OpenPGP-Keychain-API/libraries/openpgp-api-library/AndroidManifest.xml b/OpenPGP-Keychain-API/libraries/openpgp-api-library/AndroidManifest.xml
new file mode 100644
index 000000000..98cb89faa
--- /dev/null
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/AndroidManifest.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.openintents.openpgp"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="9"
+ android:targetSdkVersion="19" />
+
+ <application/>
+
+</manifest> \ No newline at end of file
diff --git a/OpenPGP-Keychain-API/libraries/openpgp-api-library/LICENSE b/OpenPGP-Keychain-API/libraries/openpgp-api-library/LICENSE
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/OpenPGP-Keychain-API/libraries/openpgp-api-library/build.gradle b/OpenPGP-Keychain-API/libraries/openpgp-api-library/build.gradle
new file mode 100644
index 000000000..98c9a3bd6
--- /dev/null
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/build.gradle
@@ -0,0 +1,35 @@
+// please leave this here, so this library builds on its own
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.9.0'
+ }
+}
+
+apply plugin: 'android-library'
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion '19.0.3'
+
+ // NOTE: We are using the old folder structure to also support Eclipse
+ sourceSets {
+ main {
+ manifest.srcFile 'AndroidManifest.xml'
+ java.srcDirs = ['src']
+ resources.srcDirs = ['src']
+ aidl.srcDirs = ['src']
+ renderscript.srcDirs = ['src']
+ res.srcDirs = ['res']
+ assets.srcDirs = ['assets']
+ }
+ }
+
+ // Do not abort build if lint finds errors
+ lintOptions {
+ abortOnError false
+ }
+}
diff --git a/OpenPGP-Keychain-API/libraries/openpgp-api-library/build.xml b/OpenPGP-Keychain-API/libraries/openpgp-api-library/build.xml
new file mode 100644
index 000000000..48ebf198c
--- /dev/null
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/build.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="keychain-api-library" default="help">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <property file="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="ant.properties" />
+
+ <!-- if sdk.dir was not set from one of the property file, then
+ get it from the ANDROID_HOME env var.
+ This must be done before we load project.properties since
+ the proguard config can use sdk.dir -->
+ <property environment="env" />
+ <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+ <isset property="env.ANDROID_HOME" />
+ </condition>
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <loadproperties srcFile="project.properties" />
+
+ <!-- quick check on sdk.dir -->
+ <fail
+ message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+ unless="sdk.dir"
+ />
+
+ <!--
+ Import per project custom build rules if present at the root of the project.
+ This is the place to put custom intermediary targets such as:
+ -pre-build
+ -pre-compile
+ -post-compile (This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir})
+ -post-package
+ -post-build
+ -pre-clean
+ -->
+ <import file="custom_rules.xml" optional="true" />
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: 1 -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/OpenPGP-Keychain-API/libraries/openpgp-api-library/proguard-project.txt b/OpenPGP-Keychain-API/libraries/openpgp-api-library/proguard-project.txt
new file mode 100644
index 000000000..f2fe1559a
--- /dev/null
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/OpenPGP-Keychain-API/libraries/openpgp-api-library/project.properties b/OpenPGP-Keychain-API/libraries/openpgp-api-library/project.properties
new file mode 100644
index 000000000..91d2b0246
--- /dev/null
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/project.properties
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-19
+android.library=true
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-hdpi/ic_action_cancel_launchersize.png b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-hdpi/ic_action_cancel_launchersize.png
index 71b9118dc..71b9118dc 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-hdpi/ic_action_cancel_launchersize.png
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-hdpi/ic_action_cancel_launchersize.png
Binary files differ
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-hdpi/ic_action_cancel_launchersize_light.png b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-hdpi/ic_action_cancel_launchersize_light.png
index 73b1d08f3..73b1d08f3 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-hdpi/ic_action_cancel_launchersize_light.png
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-hdpi/ic_action_cancel_launchersize_light.png
Binary files differ
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-mdpi/ic_action_cancel_launchersize.png b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-mdpi/ic_action_cancel_launchersize.png
index 270abf45f..270abf45f 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-mdpi/ic_action_cancel_launchersize.png
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-mdpi/ic_action_cancel_launchersize.png
Binary files differ
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-mdpi/ic_action_cancel_launchersize_light.png b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-mdpi/ic_action_cancel_launchersize_light.png
index d841821c8..d841821c8 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-mdpi/ic_action_cancel_launchersize_light.png
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-mdpi/ic_action_cancel_launchersize_light.png
Binary files differ
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize.png b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize.png
index 1e3571fa5..1e3571fa5 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize.png
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize.png
Binary files differ
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize_light.png b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize_light.png
index d505046b4..d505046b4 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize_light.png
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize_light.png
Binary files differ
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize.png b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize.png
index 52044601e..52044601e 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize.png
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize.png
Binary files differ
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize_light.png b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize_light.png
index d6fb86bdd..d6fb86bdd 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize_light.png
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize_light.png
Binary files differ
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/values/strings.xml b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/values/strings.xml
index 0119831cc..0119831cc 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/values/strings.xml
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/res/values/strings.xml
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl
index 7ee79d6ab..7ee79d6ab 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpError.java b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/OpenPgpError.java
index 4dd2cc641..4dd2cc641 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpError.java
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/OpenPgpError.java
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java
index 431d4be24..cb220cf6d 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java
@@ -38,24 +38,40 @@ public class OpenPgpSignatureResult implements Parcelable {
return status;
}
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
public boolean isSignatureOnly() {
return signatureOnly;
}
+ public void setSignatureOnly(boolean signatureOnly) {
+ this.signatureOnly = signatureOnly;
+ }
+
public String getUserId() {
return userId;
}
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
public long getKeyId() {
return keyId;
}
+ public void setKeyId(long keyId) {
+ this.keyId = keyId;
+ }
+
public OpenPgpSignatureResult() {
}
public OpenPgpSignatureResult(int signatureStatus, String signatureUserId,
- boolean signatureOnly, long keyId) {
+ boolean signatureOnly, long keyId) {
this.status = signatureStatus;
this.signatureOnly = signatureOnly;
this.userId = signatureUserId;
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java
index ed1a7540a..f768a1685 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java
@@ -16,119 +16,146 @@
package org.openintents.openpgp.util;
+import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.util.Log;
-
import org.openintents.openpgp.IOpenPgpService;
import org.openintents.openpgp.OpenPgpError;
-
import java.io.InputStream;
import java.io.OutputStream;
public class OpenPgpApi {
- //TODO: fix this documentation
+ public static final String TAG = "OpenPgp API";
+
+ public static final int API_VERSION = 2;
+ public static final String SERVICE_INTENT = "org.openintents.openpgp.IOpenPgpService";
+
/**
* General extras
* --------------
*
- * Intent extras:
- * int api_version (required)
- * boolean ascii_armor (request ascii armor for ouput)
+ * required extras:
+ * int EXTRA_API_VERSION (always required)
*
- * returned Bundle:
- * int result_code (0, 1, or 2 (see OpenPgpApi))
- * OpenPgpError error (if result_code == 0)
- * Intent intent (if result_code == 2)
+ * returned extras:
+ * int RESULT_CODE (RESULT_CODE_ERROR, RESULT_CODE_SUCCESS or RESULT_CODE_USER_INTERACTION_REQUIRED)
+ * OpenPgpError RESULT_ERROR (if RESULT_CODE == RESULT_CODE_ERROR)
+ * PendingIntent RESULT_INTENT (if RESULT_CODE == RESULT_CODE_USER_INTERACTION_REQUIRED)
*/
/**
* Sign only
*
- * optional params:
- * String passphrase (for key passphrase)
+ * optional extras:
+ * boolean EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for ouput)
+ * String EXTRA_PASSPHRASE (key passphrase)
*/
+ public static final String ACTION_SIGN = "org.openintents.openpgp.action.SIGN";
/**
* Encrypt
*
- * Intent extras:
- * long[] key_ids
+ * required extras:
+ * String[] EXTRA_USER_IDS (=emails of recipients, if more than one key has a user_id, a PendingIntent is returned via RESULT_INTENT)
* or
- * String[] user_ids (= emails of recipients) (if more than one key has this user_id, a PendingIntent is returned)
+ * long[] EXTRA_KEY_IDS
*
* optional extras:
- * String passphrase (for key passphrase)
+ * boolean EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for ouput)
+ * String EXTRA_PASSPHRASE (key passphrase)
*/
+ public static final String ACTION_ENCRYPT = "org.openintents.openpgp.action.ENCRYPT";
/**
* Sign and encrypt
*
- * Intent extras:
- * same as in encrypt()
+ * required extras:
+ * String[] EXTRA_USER_IDS (=emails of recipients, if more than one key has a user_id, a PendingIntent is returned via RESULT_INTENT)
+ * or
+ * long[] EXTRA_KEY_IDS
+ *
+ * optional extras:
+ * boolean EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for ouput)
+ * String EXTRA_PASSPHRASE (key passphrase)
*/
+ public static final String ACTION_SIGN_AND_ENCRYPT = "org.openintents.openpgp.action.SIGN_AND_ENCRYPT";
/**
- * Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted,
+ * Decrypts and verifies given input stream. This methods handles encrypted-only, signed-and-encrypted,
* and also signed-only input.
*
- * returned Bundle:
- * OpenPgpSignatureResult signature_result
+ * If OpenPgpSignatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY
+ * in addition a PendingIntent is returned via RESULT_INTENT to download missing keys.
+ *
+ * optional extras:
+ * boolean EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for ouput)
+ *
+ * returned extras:
+ * OpenPgpSignatureResult RESULT_SIGNATURE
*/
+ public static final String ACTION_DECRYPT_VERIFY = "org.openintents.openpgp.action.DECRYPT_VERIFY";
/**
- * Retrieves key ids based on given user ids (=emails)
+ * Get key ids based on given user ids (=emails)
*
- * Intent extras:
- * String[] user_ids
+ * required extras:
+ * String[] EXTRA_USER_IDS
*
- * returned Bundle:
- * long[] key_ids
+ * returned extras:
+ * long[] EXTRA_KEY_IDS
*/
-
- public static final String TAG = "OpenPgp API";
-
- public static final int API_VERSION = 2;
- public static final String SERVICE_INTENT = "org.openintents.openpgp.IOpenPgpService";
-
- public static final String ACTION_SIGN = "org.openintents.openpgp.action.SIGN";
- public static final String ACTION_ENCRYPT = "org.openintents.openpgp.action.ENCRYPT";
- public static final String ACTION_SIGN_AND_ENCTYPT = "org.openintents.openpgp.action.SIGN_AND_ENCRYPT";
- public static final String ACTION_DECRYPT_VERIFY = "org.openintents.openpgp.action.DECRYPT_VERIFY";
- public static final String ACTION_DOWNLOAD_KEYS = "org.openintents.openpgp.action.DOWNLOAD_KEYS";
public static final String ACTION_GET_KEY_IDS = "org.openintents.openpgp.action.GET_KEY_IDS";
- /* Bundle params */
+ /**
+ * This action returns RESULT_CODE_SUCCESS if the OpenPGP Provider already has the key
+ * corresponding to the given key id in its database.
+ *
+ * It returns RESULT_CODE_USER_INTERACTION_REQUIRED if the Provider does not have the key.
+ * The PendingIntent from RESULT_INTENT can be used to retrieve those from a keyserver.
+ *
+ * required extras:
+ * long EXTRA_KEY_ID
+ */
+ public static final String ACTION_GET_KEY = "org.openintents.openpgp.action.GET_KEY";
+
+ /* Intent extras */
public static final String EXTRA_API_VERSION = "api_version";
- // SIGN, ENCRYPT, SIGN_ENCRYPT, DECRYPT_VERIFY
+ // SIGN, ENCRYPT, SIGN_AND_ENCRYPT, DECRYPT_VERIFY
// request ASCII Armor for output
// OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
public static final String EXTRA_REQUEST_ASCII_ARMOR = "ascii_armor";
- // ENCRYPT, SIGN_ENCRYPT
+ // ENCRYPT, SIGN_AND_ENCRYPT
public static final String EXTRA_USER_IDS = "user_ids";
public static final String EXTRA_KEY_IDS = "key_ids";
- // optional parameter:
+ // optional extras:
public static final String EXTRA_PASSPHRASE = "passphrase";
- /* Service Bundle returns */
+ // GET_KEY
+ public static final String EXTRA_KEY_ID = "key_id";
+
+ /* Service Intent returns */
public static final String RESULT_CODE = "result_code";
- public static final String RESULT_SIGNATURE = "signature";
- public static final String RESULT_ERRORS = "error";
- public static final String RESULT_INTENT = "intent";
- // get actual error object from RESULT_ERRORS
+ // get actual error object from RESULT_ERROR
public static final int RESULT_CODE_ERROR = 0;
// success!
public static final int RESULT_CODE_SUCCESS = 1;
- // executeServiceMethod intent and do it again with intent
+ // get PendingIntent from RESULT_INTENT, start PendingIntent with startIntentSenderForResult,
+ // and execute service method again in onActivityResult
public static final int RESULT_CODE_USER_INTERACTION_REQUIRED = 2;
+ public static final String RESULT_ERROR = "error";
+ public static final String RESULT_INTENT = "intent";
+
+ // DECRYPT_VERIFY
+ public static final String RESULT_SIGNATURE = "signature";
IOpenPgpService mService;
Context mContext;
@@ -166,6 +193,7 @@ public class OpenPgpApi {
}
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void executeApiAsync(Intent data, InputStream is, OutputStream os, IOpenPgpCallback callback) {
OpenPgpAsyncTask task = new OpenPgpAsyncTask(data, is, os, callback);
@@ -188,13 +216,13 @@ public class OpenPgpApi {
result = mService.execute(data, null, null);
return result;
} else {
- // send the input and output pfds
+ // pipe the input and output
ParcelFileDescriptor input = ParcelFileDescriptorUtil.pipeFrom(is,
new ParcelFileDescriptorUtil.IThreadListener() {
@Override
public void onThreadFinished(Thread thread) {
- Log.d(OpenPgpApi.TAG, "Copy to service finished");
+ //Log.d(OpenPgpApi.TAG, "Copy to service finished");
}
});
ParcelFileDescriptor output = ParcelFileDescriptorUtil.pipeTo(os,
@@ -202,7 +230,7 @@ public class OpenPgpApi {
@Override
public void onThreadFinished(Thread thread) {
- Log.d(OpenPgpApi.TAG, "Service finished writing!");
+ //Log.d(OpenPgpApi.TAG, "Service finished writing!");
}
});
@@ -222,7 +250,7 @@ public class OpenPgpApi {
Log.e(OpenPgpApi.TAG, "Exception", e);
Intent result = new Intent();
result.putExtra(RESULT_CODE, RESULT_CODE_ERROR);
- result.putExtra(RESULT_ERRORS,
+ result.putExtra(RESULT_ERROR,
new OpenPgpError(OpenPgpError.CLIENT_SIDE_ERROR, e.getMessage()));
return result;
}
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java
index ecc2b8ec1..cf5864620 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java
@@ -31,7 +31,7 @@ import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.TextView;
-import org.sufficientlysecure.keychain.api.R;
+import org.openintents.openpgp.R;
import java.util.ArrayList;
import java.util.List;
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java
index c80656c52..c80656c52 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java
index 67fe86291..67fe86291 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java
diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java
index 58c62110d..58c62110d 100644
--- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java
+++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java
diff --git a/OpenPGP-Keychain-API/settings.gradle b/OpenPGP-Keychain-API/settings.gradle
index 4df1d7b4f..a819a021b 100644
--- a/OpenPGP-Keychain-API/settings.gradle
+++ b/OpenPGP-Keychain-API/settings.gradle
@@ -1,2 +1,3 @@
include ':example-app'
-include ':libraries:keychain-api-library' \ No newline at end of file
+include ':libraries:openpgp-api-library'
+include ':libraries:openkeychain-api-library' \ No newline at end of file
diff --git a/OpenPGP-Keychain/build.gradle b/OpenPGP-Keychain/build.gradle
index 1e48d8bcd..6338774eb 100644
--- a/OpenPGP-Keychain/build.gradle
+++ b/OpenPGP-Keychain/build.gradle
@@ -3,7 +3,8 @@ apply plugin: 'android'
dependencies {
compile 'com.android.support:support-v4:19.0.1'
compile 'com.android.support:appcompat-v7:19.0.1'
- compile project(':OpenPGP-Keychain-API:libraries:keychain-api-library')
+ compile project(':OpenPGP-Keychain-API:libraries:openpgp-api-library')
+ compile project(':OpenPGP-Keychain-API:libraries:openkeychain-api-library')
compile project(':libraries:HtmlTextView')
compile project(':libraries:StickyListHeaders:library')
compile project(':libraries:AndroidBootstrap')
@@ -18,7 +19,7 @@ dependencies {
android {
compileSdkVersion 19
- buildToolsVersion "19.0.1"
+ buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 9
diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml
index 250d3edbe..bd45def24 100644
--- a/OpenPGP-Keychain/src/main/AndroidManifest.xml
+++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml
@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.sufficientlysecure.keychain"
android:installLocation="auto"
- android:versionCode="23101"
- android:versionName="2.3.1 beta1">
+ android:versionCode="23104"
+ android:versionName="2.3.1 beta4">
<!--
General remarks
@@ -22,7 +22,8 @@
Remarks about the ugly android:pathPattern:
- We are matching all files with a specific file ending.
This is done in an ugly way because of Android limitations.
- Read http://stackoverflow.com/questions/1733195/android-intent-filter-for-a-particular-file-extension and http://stackoverflow.com/questions/3400072/pathpattern-to-match-file-extension-does-not-work-if-a-period-exists-elsewhere-i/8599921
+ Read http://stackoverflow.com/questions/1733195/android-intent-filter-for-a-particular-file-extension
+ and http://stackoverflow.com/questions/3400072/pathpattern-to-match-file-extension-does-not-work-if-a-period-exists-elsewhere-i/8599921
for more information.
- Do _not_ set mimeType for gpg!
Cyanogenmod's file manager will only show Keychain for gpg files if no mimeType is set!
@@ -49,6 +50,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.NFC" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<!-- android:allowBackup="false": Don't allow backup over adb backup or other apps! -->
<application
@@ -106,30 +108,12 @@
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_select_recipients"
android:launchMode="singleTop">
-
- <!-- <intent-filter> -->
- <!-- <action android:name="android.intent.action.SEARCH" /> -->
- <!-- </intent-filter> -->
-
-
- <!-- <meta-data -->
- <!-- android:name="android.app.searchable" -->
- <!-- android:resource="@xml/searchable_public_keys" /> -->
</activity>
<activity
android:name=".ui.SelectSecretKeyActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_select_secret_key"
android:launchMode="singleTop">
-
- <!-- <intent-filter> -->
- <!-- <action android:name="android.intent.action.SEARCH" /> -->
- <!-- </intent-filter> -->
-
-
- <!-- <meta-data -->
- <!-- android:name="android.app.searchable" -->
- <!-- android:resource="@xml/searchable_secret_keys" /> -->
</activity>
<activity
android:name=".ui.EncryptActivity"
@@ -261,7 +245,16 @@
<activity
android:name=".ui.PreferencesActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
- android:label="@string/title_preferences" />
+ android:label="@string/title_preferences" >
+ <intent-filter>
+ <action android:name="org.sufficientlysecure.keychain.ui.PREFS_GEN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="org.sufficientlysecure.keychain.ui.PREFS_ADV" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
<activity
android:name=".ui.PreferencesKeyServerActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
@@ -439,10 +432,6 @@
<!--<intent-filter>-->
<!--<action android:name="org.sufficientlysecure.keychain.service.remote.IExtendedApiService" />-->
<!--</intent-filter>-->
-
- <!--<meta-data-->
- <!--android:name="api_version"-->
- <!--android:value="1" />-->
<!--</service>-->
<!-- TODO: authority! Make this API with content provider uris -->
@@ -452,4 +441,4 @@
<!-- android:permission="org.sufficientlysecure.keychain.permission.ACCESS_API" /> -->
</application>
-</manifest> \ No newline at end of file
+</manifest>
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 c1809e4e1..34a3de8d5 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
@@ -43,6 +43,8 @@ public final class Constants {
public static final class path {
public static final String APP_DIR = Environment.getExternalStorageDirectory()
+ "/OpenPGP-Keychain";
+ public static final String APP_DIR_FILE_SEC = APP_DIR + "/secexport.asc";
+ public static final String APP_DIR_FILE_PUB = APP_DIR + "/pubexport.asc";
}
public static final class pref {
@@ -51,7 +53,7 @@ public final class Constants {
public static final String DEFAULT_ASCII_ARMOUR = "defaultAsciiArmour";
public static final String DEFAULT_MESSAGE_COMPRESSION = "defaultMessageCompression";
public static final String DEFAULT_FILE_COMPRESSION = "defaultFileCompression";
- public static final String PASS_PHRASE_CACHE_TTL = "passPhraseCacheTtl";
+ public static final String PASS_PHRASE_CACHE_TTL = "passphraseCacheTtl";
public static final String LANGUAGE = "language";
public static final String FORCE_V3_SIGNATURES = "forceV3Signatures";
public static final String KEY_SERVERS = "keyServers";
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java
index a1571e491..1d79edd43 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java
@@ -30,7 +30,7 @@ public final class Id {
public static final class menu {
public static final class option {
- public static final int new_pass_phrase = 0x21070001;
+ public static final int new_passphrase = 0x21070001;
public static final int create = 0x21070002;
public static final int about = 0x21070003;
public static final int manage_public_keys = 0x21070004;
@@ -85,12 +85,12 @@ public final class Id {
}
public static final class dialog {
- public static final int pass_phrase = 0x21070001;
+ public static final int passphrase = 0x21070001;
public static final int encrypting = 0x21070002;
public static final int decrypting = 0x21070003;
- public static final int new_pass_phrase = 0x21070004;
- public static final int pass_phrases_do_not_match = 0x21070005;
- public static final int no_pass_phrase = 0x21070006;
+ public static final int new_passphrase = 0x21070004;
+ public static final int passphrases_do_not_match = 0x21070005;
+ public static final int no_passphrase = 0x21070006;
public static final int saving = 0x21070007;
public static final int delete_key = 0x21070008;
public static final int import_keys = 0x21070009;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java
index 032af4c71..3164de7d1 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java
@@ -59,7 +59,6 @@ public class ClipboardReflection {
* Wrapper around ClipboardManager based on Android version using Reflection API
*
* @param context
- * @param text
*/
public static CharSequence getClipboardText(Context context) {
Object clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java
index b55075e6c..24e8ff4c7 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java
@@ -56,28 +56,33 @@ public class ActionBarHelper {
* Sets custom view on ActionBar for Done/Cancel activities
*
* @param actionBar
- * @param doneText
- * @param doneOnClickListener
- * @param cancelText
- * @param cancelOnClickListener
+ * @param firstText
+ * @param firstDrawableId
+ * @param firstOnClickListener
+ * @param secondText
+ * @param secondDrawableId
+ * @param secondOnClickListener
*/
- public static void setDoneCancelView(ActionBar actionBar, int doneText,
- OnClickListener doneOnClickListener, int cancelText,
- OnClickListener cancelOnClickListener) {
+ public static void setTwoButtonView(ActionBar actionBar, int firstText, int firstDrawableId,
+ OnClickListener firstOnClickListener, int secondText, int secondDrawableId,
+ OnClickListener secondOnClickListener) {
- // Inflate a "Done"/"Cancel" custom action bar view
+ // Inflate the custom action bar view
final LayoutInflater inflater = (LayoutInflater) actionBar.getThemedContext()
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
final View customActionBarView = inflater.inflate(
R.layout.actionbar_custom_view_done_cancel, null);
- ((TextView) customActionBarView.findViewById(R.id.actionbar_done_text)).setText(doneText);
+ TextView firstTextView = ((TextView) customActionBarView.findViewById(R.id.actionbar_done_text));
+ firstTextView.setText(firstText);
+ firstTextView.setCompoundDrawablesWithIntrinsicBounds(firstDrawableId, 0, 0, 0);
customActionBarView.findViewById(R.id.actionbar_done).setOnClickListener(
- doneOnClickListener);
- ((TextView) customActionBarView.findViewById(R.id.actionbar_cancel_text))
- .setText(cancelText);
+ firstOnClickListener);
+ TextView secondTextView = ((TextView) customActionBarView.findViewById(R.id.actionbar_cancel_text));
+ secondTextView.setText(secondText);
+ secondTextView.setCompoundDrawablesWithIntrinsicBounds(secondDrawableId, 0, 0, 0);
customActionBarView.findViewById(R.id.actionbar_cancel).setOnClickListener(
- cancelOnClickListener);
+ secondOnClickListener);
// Show the custom action bar view and hide the normal Home icon and title.
actionBar.setDisplayShowTitleEnabled(false);
@@ -91,20 +96,22 @@ public class ActionBarHelper {
* Sets custom view on ActionBar for Done activities
*
* @param actionBar
- * @param doneText
- * @param doneOnClickListener
+ * @param firstText
+ * @param firstOnClickListener
*/
- public static void setDoneView(ActionBar actionBar, int doneText,
- OnClickListener doneOnClickListener) {
+ public static void setOneButtonView(ActionBar actionBar, int firstText, int firstDrawableId,
+ OnClickListener firstOnClickListener) {
// Inflate a "Done" custom action bar view to serve as the "Up" affordance.
final LayoutInflater inflater = (LayoutInflater) actionBar.getThemedContext()
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
final View customActionBarView = inflater
.inflate(R.layout.actionbar_custom_view_done, null);
- ((TextView) customActionBarView.findViewById(R.id.actionbar_done_text)).setText(doneText);
+ TextView firstTextView = ((TextView) customActionBarView.findViewById(R.id.actionbar_done_text));
+ firstTextView.setText(firstText);
+ firstTextView.setCompoundDrawablesWithIntrinsicBounds(firstDrawableId, 0, 0, 0);
customActionBarView.findViewById(R.id.actionbar_done).setOnClickListener(
- doneOnClickListener);
+ firstOnClickListener);
// Show the custom action bar view and hide the normal Home icon and title.
actionBar.setDisplayShowTitleEnabled(false);
@@ -112,5 +119,4 @@ public class ActionBarHelper {
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setCustomView(customActionBarView);
}
-
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java
new file mode 100644
index 000000000..f8ed21816
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sufficientlysecure.keychain.helper;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.Context;
+import android.util.Patterns;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class ContactHelper {
+
+ public static final List<String> getMailAccounts(Context context) {
+ final Account[] accounts = AccountManager.get(context).getAccounts();
+ final Set<String> emailSet = new HashSet<String>();
+ for (Account account : accounts) {
+ if (Patterns.EMAIL_ADDRESS.matcher(account.name).matches()) {
+ emailSet.add(account.name);
+ }
+ }
+ return new ArrayList<String>(emailSet);
+ }
+}
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 21676a2a7..19dfccbde 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
@@ -20,7 +20,6 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
@@ -63,7 +62,7 @@ public class ExportHelper {
/**
* Show dialog where to export keys
*/
- public void showExportKeysDialog(final Uri dataUri, final int keyType,
+ public void showExportKeysDialog(final long[] rowIds, final int keyType,
final String exportFilename) {
mExportFilename = exportFilename;
@@ -75,7 +74,7 @@ public class ExportHelper {
Bundle data = message.getData();
mExportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME);
- exportKeys(dataUri, keyType);
+ exportKeys(rowIds, keyType);
}
}
};
@@ -86,7 +85,7 @@ public class ExportHelper {
DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
public void run() {
String title = null;
- if (dataUri == null) {
+ if (rowIds == null) {
// export all keys
title = activity.getString(R.string.title_export_keys);
} else {
@@ -112,7 +111,7 @@ public class ExportHelper {
/**
* Export keys
*/
- public void exportKeys(Uri dataUri, int keyType) {
+ public void exportKeys(long[] rowIds, int keyType) {
Log.d(Constants.TAG, "exportKeys started");
// Send all information needed to service to export key in other thread
@@ -126,20 +125,17 @@ public class ExportHelper {
data.putString(KeychainIntentService.EXPORT_FILENAME, mExportFilename);
data.putInt(KeychainIntentService.EXPORT_KEY_TYPE, keyType);
- if (dataUri == null) {
+ if (rowIds == null) {
data.putBoolean(KeychainIntentService.EXPORT_ALL, true);
} else {
- // TODO: put data uri into service???
- long keyRingMasterKeyId = ProviderHelper.getMasterKeyId(activity, dataUri);
-
- data.putLong(KeychainIntentService.EXPORT_KEY_RING_MASTER_KEY_ID, keyRingMasterKeyId);
+ data.putLongArray(KeychainIntentService.EXPORT_KEY_RING_ROW_ID, rowIds);
}
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after exporting is done in ApgService
KeychainIntentServiceHandler exportHandler = new KeychainIntentServiceHandler(activity,
- R.string.progress_exporting, ProgressDialog.STYLE_HORIZONTAL) {
+ activity.getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -160,7 +156,7 @@ public class ExportHelper {
Toast.makeText(activity, toastMessage, Toast.LENGTH_SHORT).show();
}
- };
+ }
};
// Create a new Messenger for the communication back
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 639ab17b8..34d90a17f 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
@@ -17,8 +17,6 @@
package org.sufficientlysecure.keychain.helper;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Set;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java
index 493f25707..f18a290b3 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java
@@ -144,8 +144,8 @@ public class Preferences {
Constants.defaults.KEY_SERVERS);
Vector<String> servers = new Vector<String>();
String chunks[] = rawData.split(",");
- for (int i = 0; i < chunks.length; ++i) {
- String tmp = chunks[i].trim();
+ for (String c : chunks) {
+ String tmp = c.trim();
if (tmp.length() > 0) {
servers.add(tmp);
}
@@ -156,8 +156,8 @@ public class Preferences {
public void setKeyServers(String[] value) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
String rawData = "";
- for (int i = 0; i < value.length; ++i) {
- String tmp = value[i].trim();
+ for (String v : value) {
+ String tmp = v.trim();
if (tmp.length() == 0) {
continue;
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java
index ca97cbd9f..b268de3a6 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java
@@ -78,7 +78,7 @@ public class PgpConversionHelper {
*
* Singles keys are encoded as keyRings with one single key in it by Bouncy Castle
*
- * @param keysBytes
+ * @param keyBytes
* @return
*/
public static PGPSecretKey BytesToPGPSecretKey(byte[] keyBytes) {
@@ -149,7 +149,7 @@ public class PgpConversionHelper {
/**
* Convert from PGPSecretKey to byte[]
*
- * @param keysBytes
+ * @param key
* @return
*/
public static byte[] PGPSecretKeyToBytes(PGPSecretKey key) {
@@ -165,7 +165,7 @@ public class PgpConversionHelper {
/**
* Convert from PGPSecretKeyRing to byte[]
*
- * @param keysBytes
+ * @param keyRing
* @return
*/
public static byte[] PGPSecretKeyRingToBytes(PGPSecretKeyRing keyRing) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
index fb97f3a5c..252be1036 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
@@ -18,8 +18,8 @@
package org.sufficientlysecure.keychain.pgp;
import android.content.Context;
-import android.os.Bundle;
+import org.openintents.openpgp.OpenPgpSignatureResult;
import org.spongycastle.bcpg.ArmoredInputStream;
import org.spongycastle.bcpg.SignatureSubpacketTags;
import org.spongycastle.openpgp.PGPCompressedData;
@@ -36,6 +36,7 @@ import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
+import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureList;
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
@@ -53,7 +54,7 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
+import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
@@ -75,9 +76,10 @@ public class PgpDecryptVerify {
private InputData data;
private OutputStream outStream;
- private ProgressDialogUpdater progress;
- boolean assumeSymmetric;
- String passphrase;
+ private ProgressDialogUpdater progressDialogUpdater;
+ private boolean assumeSymmetric;
+ private String passphrase;
+ private long enforcedKeyId;
private PgpDecryptVerify(Builder builder) {
// private Constructor can only be called from Builder
@@ -85,9 +87,10 @@ public class PgpDecryptVerify {
this.data = builder.data;
this.outStream = builder.outStream;
- this.progress = builder.progress;
+ this.progressDialogUpdater = builder.progressDialogUpdater;
this.assumeSymmetric = builder.assumeSymmetric;
this.passphrase = builder.passphrase;
+ this.enforcedKeyId = builder.enforcedKeyId;
}
public static class Builder {
@@ -97,9 +100,10 @@ public class PgpDecryptVerify {
private OutputStream outStream;
// optional
- private ProgressDialogUpdater progress = null;
+ private ProgressDialogUpdater progressDialogUpdater = null;
private boolean assumeSymmetric = false;
private String passphrase = "";
+ private long enforcedKeyId = 0;
public Builder(Context context, InputData data, OutputStream outStream) {
this.context = context;
@@ -107,8 +111,8 @@ public class PgpDecryptVerify {
this.outStream = outStream;
}
- public Builder progress(ProgressDialogUpdater progress) {
- this.progress = progress;
+ public Builder progressDialogUpdater(ProgressDialogUpdater progressDialogUpdater) {
+ this.progressDialogUpdater = progressDialogUpdater;
return this;
}
@@ -122,20 +126,32 @@ public class PgpDecryptVerify {
return this;
}
+ /**
+ * Allow this key id alone for decryption.
+ * This means only ciphertexts encrypted for this private key can be decrypted.
+ *
+ * @param enforcedKeyId
+ * @return
+ */
+ public Builder enforcedKeyId(long enforcedKeyId) {
+ this.enforcedKeyId = enforcedKeyId;
+ return this;
+ }
+
public PgpDecryptVerify build() {
return new PgpDecryptVerify(this);
}
}
public void updateProgress(int message, int current, int total) {
- if (progress != null) {
- progress.setProgress(message, current, total);
+ if (progressDialogUpdater != null) {
+ progressDialogUpdater.setProgress(message, current, total);
}
}
public void updateProgress(int current, int total) {
- if (progress != null) {
- progress.setProgress(current, total);
+ if (progressDialogUpdater != null) {
+ progressDialogUpdater.setProgress(current, total);
}
}
@@ -177,9 +193,8 @@ public class PgpDecryptVerify {
* @throws PGPException
* @throws SignatureException
*/
- public Bundle execute()
+ public PgpDecryptVerifyResult execute()
throws IOException, PgpGeneralException, PGPException, SignatureException {
-
// automatically works with ascii armor input and binary
InputStream in = PGPUtil.getDecoderStream(data.getInputStream());
if (in instanceof ArmoredInputStream) {
@@ -207,9 +222,9 @@ public class PgpDecryptVerify {
* @throws PGPException
* @throws SignatureException
*/
- private Bundle decryptVerify(InputStream in)
+ private PgpDecryptVerifyResult decryptVerify(InputStream in)
throws IOException, PgpGeneralException, PGPException, SignatureException {
- Bundle returnData = new Bundle();
+ PgpDecryptVerifyResult returnData = new PgpDecryptVerifyResult();
PGPObjectFactory pgpF = new PGPObjectFactory(in);
PGPEncryptedDataList enc;
@@ -277,9 +292,40 @@ public class PgpDecryptVerify {
PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, encData.getKeyID());
if (secretKey != null) {
+ // secret key exists in database
+
+ // allow only a specific key for decryption?
+ if (enforcedKeyId != 0) {
+ // TODO: improve this code! get master key directly!
+ PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, encData.getKeyID());
+ long masterKeyId = PgpKeyHelper.getMasterKey(secretKeyRing).getKeyID();
+ Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID());
+ Log.d(Constants.TAG, "enforcedKeyId: " + enforcedKeyId);
+ Log.d(Constants.TAG, "masterKeyId: " + masterKeyId);
+
+ if (enforcedKeyId != masterKeyId) {
+ throw new PgpGeneralException(context.getString(R.string.error_no_secret_key_found));
+ }
+ }
+
pbe = encData;
+
+ // if no passphrase was explicitly set try to get it from the cache service
+ if (passphrase == null) {
+ // returns "" if key has no passphrase
+ passphrase = PassphraseCacheService.getCachedPassphrase(context, encData.getKeyID());
+
+ // if passphrase was not cached, return here indicating that a passphrase is missing!
+ if (passphrase == null) {
+ returnData.setKeyPassphraseNeeded(true);
+ return returnData;
+ }
+ }
+
break;
}
+
+
}
}
@@ -289,7 +335,7 @@ public class PgpDecryptVerify {
currentProgress += 5;
updateProgress(R.string.progress_extracting_key, currentProgress, 100);
- PGPPrivateKey privateKey = null;
+ PGPPrivateKey privateKey;
try {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
@@ -317,6 +363,7 @@ public class PgpDecryptVerify {
PGPObjectFactory plainFact = new PGPObjectFactory(clear);
Object dataChunk = plainFact.nextObject();
PGPOnePassSignature signature = null;
+ OpenPgpSignatureResult signatureResult = null;
PGPPublicKey signatureKey = null;
int signatureIndex = -1;
@@ -334,7 +381,7 @@ public class PgpDecryptVerify {
if (dataChunk instanceof PGPOnePassSignatureList) {
updateProgress(R.string.progress_processing_signature, currentProgress, 100);
- returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true);
+ signatureResult = new OpenPgpSignatureResult();
PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk;
for (int i = 0; i < sigList.size(); ++i) {
signature = sigList.get(i);
@@ -354,12 +401,12 @@ public class PgpDecryptVerify {
if (signKeyRing != null) {
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
}
- returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId);
+ signatureResult.setUserId(userId);
break;
}
}
- returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId);
+ signatureResult.setKeyId(signatureKeyId);
if (signature != null) {
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider()
@@ -367,7 +414,7 @@ public class PgpDecryptVerify {
signature.init(contentVerifierBuilderProvider, signatureKey);
} else {
- returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true);
+ signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY);
}
dataChunk = plainFact.nextObject();
@@ -405,8 +452,7 @@ public class PgpDecryptVerify {
try {
signature.update(buffer, 0, n);
} catch (SignatureException e) {
- returnData
- .putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, false);
+ signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_ERROR);
signature = null;
}
}
@@ -430,17 +476,20 @@ public class PgpDecryptVerify {
PGPSignature messageSignature = signatureList.get(signatureIndex);
// these are not cleartext signatures!
- returnData.putBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, false);
+ // TODO: what about binary signatures?
+ signatureResult.setSignatureOnly(false);
//Now check binding signatures
- boolean keyBinding_isok = verifyKeyBinding(context, messageSignature, signatureKey);
- boolean sig_isok = signature.verify(messageSignature);
+ boolean validKeyBinding = verifyKeyBinding(context, messageSignature, signatureKey);
+ boolean validSignature = signature.verify(messageSignature);
- returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, keyBinding_isok & sig_isok);
+ // TODO: implement CERTIFIED!
+ if (validKeyBinding & validSignature) {
+ signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
+ }
}
}
- // TODO: test if this integrity really check works!
if (encryptedData.isIntegrityProtected()) {
updateProgress(R.string.progress_verifying_integrity, 95, 100);
@@ -455,9 +504,12 @@ public class PgpDecryptVerify {
} else {
// no integrity check
Log.e(Constants.TAG, "Encrypted data was not integrity protected!");
+ // TODO: inform user?
}
updateProgress(R.string.progress_done, 100, 100);
+
+ returnData.setSignatureResult(signatureResult);
return returnData;
}
@@ -474,11 +526,12 @@ public class PgpDecryptVerify {
* @throws PGPException
* @throws SignatureException
*/
- private Bundle verifyCleartextSignature(ArmoredInputStream aIn)
+ private PgpDecryptVerifyResult verifyCleartextSignature(ArmoredInputStream aIn)
throws IOException, PgpGeneralException, PGPException, SignatureException {
- Bundle returnData = new Bundle();
+ PgpDecryptVerifyResult returnData = new PgpDecryptVerifyResult();
+ OpenPgpSignatureResult signatureResult = new OpenPgpSignatureResult();
// cleartext signatures are never encrypted ;)
- returnData.putBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, true);
+ signatureResult.setSignatureOnly(true);
ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -504,8 +557,6 @@ public class PgpDecryptVerify {
byte[] clearText = out.toByteArray();
outStream.write(clearText);
- returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true);
-
updateProgress(R.string.progress_processing_signature, 60, 100);
PGPObjectFactory pgpFact = new PGPObjectFactory(aIn);
@@ -533,15 +584,17 @@ public class PgpDecryptVerify {
if (signKeyRing != null) {
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
}
- returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId);
+ signatureResult.setUserId(userId);
break;
}
}
- returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId);
+ signatureResult.setKeyId(signatureKeyId);
if (signature == null) {
- returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true);
+ signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY);
+ returnData.setSignatureResult(signatureResult);
+
updateProgress(R.string.progress_done, 100, 100);
return returnData;
}
@@ -569,12 +622,17 @@ public class PgpDecryptVerify {
} while (lookAhead != -1);
}
- boolean sig_isok = signature.verify();
-
//Now check binding signatures
- boolean keyBinding_isok = verifyKeyBinding(context, signature, signatureKey);
+ boolean validKeyBinding = verifyKeyBinding(context, signature, signatureKey);
+ boolean validSignature = signature.verify();
- returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, sig_isok & keyBinding_isok);
+ if (validSignature & validKeyBinding) {
+ signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
+ }
+
+ // TODO: what about SIGNATURE_SUCCESS_CERTIFIED and SIGNATURE_ERROR????
+
+ returnData.setSignatureResult(signatureResult);
updateProgress(R.string.progress_done, 100, 100);
return returnData;
@@ -582,34 +640,34 @@ public class PgpDecryptVerify {
private static boolean verifyKeyBinding(Context context, PGPSignature signature, PGPPublicKey signatureKey) {
long signatureKeyId = signature.getKeyID();
- boolean keyBinding_isok = false;
- String userId = null;
+ boolean validKeyBinding = false;
+
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(context,
signatureKeyId);
PGPPublicKey mKey = null;
if (signKeyRing != null) {
mKey = PgpKeyHelper.getMasterKey(signKeyRing);
}
+
if (signature.getKeyID() != mKey.getKeyID()) {
- keyBinding_isok = verifyKeyBinding(mKey, signatureKey);
+ validKeyBinding = verifyKeyBinding(mKey, signatureKey);
} else { //if the key used to make the signature was the master key, no need to check binding sigs
- keyBinding_isok = true;
+ validKeyBinding = true;
}
- return keyBinding_isok;
+ return validKeyBinding;
}
private static boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) {
- boolean subkeyBinding_isok = false;
- boolean tmp_subkeyBinding_isok = false;
- boolean primkeyBinding_isok = false;
- JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+ boolean validSubkeyBinding = false;
+ boolean validTempSubkeyBinding = false;
+ boolean validPrimaryKeyBinding = false;
+
+ JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
+ new JcaPGPContentVerifierBuilderProvider()
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
Iterator<PGPSignature> itr = signingPublicKey.getSignatures();
- subkeyBinding_isok = false;
- tmp_subkeyBinding_isok = false;
- primkeyBinding_isok = false;
while (itr.hasNext()) { //what does gpg do if the subkey binding is wrong?
//gpg has an invalid subkey binding error on key import I think, but doesn't shout
//about keys without subkey signing. Can't get it to import a slightly broken one
@@ -619,32 +677,36 @@ public class PgpDecryptVerify {
//check and if ok, check primary key binding.
try {
sig.init(contentVerifierBuilderProvider, masterPublicKey);
- tmp_subkeyBinding_isok = sig.verifyCertification(masterPublicKey, signingPublicKey);
+ validTempSubkeyBinding = sig.verifyCertification(masterPublicKey, signingPublicKey);
} catch (PGPException e) {
continue;
} catch (SignatureException e) {
continue;
}
- if (tmp_subkeyBinding_isok)
- subkeyBinding_isok = true;
- if (tmp_subkeyBinding_isok) {
- primkeyBinding_isok = verifyPrimaryBinding(sig.getUnhashedSubPackets(), masterPublicKey, signingPublicKey);
- if (primkeyBinding_isok)
+ if (validTempSubkeyBinding)
+ validSubkeyBinding = true;
+ if (validTempSubkeyBinding) {
+ validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getUnhashedSubPackets(),
+ masterPublicKey, signingPublicKey);
+ if (validPrimaryKeyBinding)
break;
- primkeyBinding_isok = verifyPrimaryBinding(sig.getHashedSubPackets(), masterPublicKey, signingPublicKey);
- if (primkeyBinding_isok)
+ validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getHashedSubPackets(),
+ masterPublicKey, signingPublicKey);
+ if (validPrimaryKeyBinding)
break;
}
}
}
- return (subkeyBinding_isok & primkeyBinding_isok);
+ return (validSubkeyBinding & validPrimaryKeyBinding);
}
- private static boolean verifyPrimaryBinding(PGPSignatureSubpacketVector Pkts, PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) {
- boolean primkeyBinding_isok = false;
- JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+ private static boolean verifyPrimaryKeyBinding(PGPSignatureSubpacketVector Pkts,
+ PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) {
+ boolean validPrimaryKeyBinding = false;
+ JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
+ new JcaPGPContentVerifierBuilderProvider()
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureList eSigList;
if (Pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) {
@@ -660,8 +722,8 @@ public class PgpDecryptVerify {
if (emSig.getSignatureType() == PGPSignature.PRIMARYKEY_BINDING) {
try {
emSig.init(contentVerifierBuilderProvider, signingPublicKey);
- primkeyBinding_isok = emSig.verifyCertification(masterPublicKey, signingPublicKey);
- if (primkeyBinding_isok)
+ validPrimaryKeyBinding = emSig.verifyCertification(masterPublicKey, signingPublicKey);
+ if (validPrimaryKeyBinding)
break;
} catch (PGPException e) {
continue;
@@ -671,7 +733,8 @@ public class PgpDecryptVerify {
}
}
}
- return primkeyBinding_isok;
+
+ return validPrimaryKeyBinding;
}
/**
@@ -680,10 +743,9 @@ public class PgpDecryptVerify {
* @param sig
* @param line
* @throws SignatureException
- * @throws IOException
*/
private static void processLine(PGPSignature sig, byte[] line)
- throws SignatureException, IOException {
+ throws SignatureException {
int length = getLengthWithoutWhiteSpace(line);
if (length > 0) {
sig.update(line, 0, length);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java
new file mode 100644
index 000000000..0477c4fdf
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java
@@ -0,0 +1,88 @@
+/*
+ * 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.pgp;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import org.openintents.openpgp.OpenPgpSignatureResult;
+
+public class PgpDecryptVerifyResult implements Parcelable {
+ boolean symmetricPassphraseNeeded;
+ boolean keyPassphraseNeeded;
+ OpenPgpSignatureResult signatureResult;
+
+ public boolean isSymmetricPassphraseNeeded() {
+ return symmetricPassphraseNeeded;
+ }
+
+ public void setSymmetricPassphraseNeeded(boolean symmetricPassphraseNeeded) {
+ this.symmetricPassphraseNeeded = symmetricPassphraseNeeded;
+ }
+
+ public boolean isKeyPassphraseNeeded() {
+ return keyPassphraseNeeded;
+ }
+
+ public void setKeyPassphraseNeeded(boolean keyPassphraseNeeded) {
+ this.keyPassphraseNeeded = keyPassphraseNeeded;
+ }
+
+ public OpenPgpSignatureResult getSignatureResult() {
+ return signatureResult;
+ }
+
+ public void setSignatureResult(OpenPgpSignatureResult signatureResult) {
+ this.signatureResult = signatureResult;
+ }
+
+ public PgpDecryptVerifyResult() {
+
+ }
+
+ public PgpDecryptVerifyResult(PgpDecryptVerifyResult b) {
+ this.symmetricPassphraseNeeded = b.symmetricPassphraseNeeded;
+ this.keyPassphraseNeeded = b.keyPassphraseNeeded;
+ this.signatureResult = b.signatureResult;
+ }
+
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeByte((byte) (symmetricPassphraseNeeded ? 1 : 0));
+ dest.writeByte((byte) (keyPassphraseNeeded ? 1 : 0));
+ dest.writeParcelable(signatureResult, 0);
+ }
+
+ public static final Creator<PgpDecryptVerifyResult> CREATOR = new Creator<PgpDecryptVerifyResult>() {
+ public PgpDecryptVerifyResult createFromParcel(final Parcel source) {
+ PgpDecryptVerifyResult vr = new PgpDecryptVerifyResult();
+ vr.symmetricPassphraseNeeded = source.readByte() == 1;
+ vr.keyPassphraseNeeded = source.readByte() == 1;
+ vr.signatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader());
+ return vr;
+ }
+
+ public PgpDecryptVerifyResult[] newArray(final int size) {
+ return new PgpDecryptVerifyResult[size];
+ }
+ };
+}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java
index 7ac904d89..1db4f98b1 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java
@@ -193,11 +193,10 @@ public class PgpHelper {
* @param context
* @param progress
* @param file
- * @throws FileNotFoundException
* @throws IOException
*/
public static void deleteFileSecurely(Context context, ProgressDialogUpdater progress, File file)
- throws FileNotFoundException, IOException {
+ throws IOException {
long length = file.length();
SecureRandom random = new SecureRandom();
RandomAccessFile raf = new RandomAccessFile(file, "rws");
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
index a7a574ee7..138e54f71 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
@@ -17,11 +17,9 @@
package org.sufficientlysecure.keychain.pgp;
-import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@@ -29,12 +27,10 @@ import java.util.List;
import org.spongycastle.bcpg.ArmoredOutputStream;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.PGPUtil;
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
@@ -44,11 +40,9 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
import org.sufficientlysecure.keychain.util.HkpKeyServer;
-import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException;
import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
import android.content.Context;
@@ -85,13 +79,14 @@ public class PgpImportExport {
public boolean uploadKeyRingToServer(HkpKeyServer server, PGPPublicKeyRing keyring) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ArmoredOutputStream aos = new ArmoredOutputStream(bos);
+ ArmoredOutputStream aos = null;
try {
+ aos = new ArmoredOutputStream(bos);
aos.write(keyring.getEncoded());
aos.close();
- String armouredKey = bos.toString("UTF-8");
- server.add(armouredKey);
+ String armoredKey = bos.toString("UTF-8");
+ server.add(armoredKey);
return true;
} catch (IOException e) {
@@ -101,7 +96,8 @@ public class PgpImportExport {
return false;
} finally {
try {
- bos.close();
+ if (aos != null) aos.close();
+ if (bos != null) bos.close();
} catch (IOException e) {
}
}
@@ -161,59 +157,53 @@ public class PgpImportExport {
return returnData;
}
- public Bundle exportKeyRings(ArrayList<Long> keyRingMasterKeyIds, int keyType,
- OutputStream outStream) throws PgpGeneralException, FileNotFoundException,
+ public Bundle exportKeyRings(ArrayList<Long> keyRingRowIds, int keyType,
+ OutputStream outStream) throws PgpGeneralException,
PGPException, IOException {
Bundle returnData = new Bundle();
+ int rowIdsSize = keyRingRowIds.size();
+
updateProgress(
mContext.getResources().getQuantityString(R.plurals.progress_exporting_key,
- keyRingMasterKeyIds.size()), 0, 100);
+ rowIdsSize), 0, 100);
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
throw new PgpGeneralException(
mContext.getString(R.string.error_external_storage_not_ready));
}
-
- if (keyType == Id.type.secret_key) {
- ArmoredOutputStream outSec = new ArmoredOutputStream(outStream);
- outSec.setHeader("Version", PgpHelper.getFullVersion(mContext));
-
- for (int i = 0; i < keyRingMasterKeyIds.size(); ++i) {
- updateProgress(i * 100 / keyRingMasterKeyIds.size() / 2, 100);
-
- PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(
- mContext, keyRingMasterKeyIds.get(i));
+ // For each row id
+ for (int i = 0; i < rowIdsSize; ++i) {
+ // Create an output stream
+ ArmoredOutputStream arOutStream = new ArmoredOutputStream(outStream);
+ arOutStream.setHeader("Version", PgpHelper.getFullVersion(mContext));
+
+ // If the keyType is secret get the PGPSecretKeyRing
+ // based on the row id and encode it to the output
+ if (keyType == Id.type.secret_key) {
+ updateProgress(i * 100 / rowIdsSize / 2, 100);
+ PGPSecretKeyRing secretKeyRing =
+ ProviderHelper.getPGPSecretKeyRingByRowId(mContext, keyRingRowIds.get(i));
if (secretKeyRing != null) {
- secretKeyRing.encode(outSec);
- }
- }
- outSec.close();
- } else {
- // export public keyrings...
- ArmoredOutputStream outPub = new ArmoredOutputStream(outStream);
- outPub.setHeader("Version", PgpHelper.getFullVersion(mContext));
-
- for (int i = 0; i < keyRingMasterKeyIds.size(); ++i) {
- // double the needed time if exporting both public and secret parts
- if (keyType == Id.type.secret_key) {
- updateProgress(i * 100 / keyRingMasterKeyIds.size() / 2, 100);
- } else {
- updateProgress(i * 100 / keyRingMasterKeyIds.size(), 100);
+ secretKeyRing.encode(arOutStream);
}
-
- PGPPublicKeyRing publicKeyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(
- mContext, keyRingMasterKeyIds.get(i));
+ // Else if it's a public key get the PGPPublicKeyRing
+ // and encode that to the output
+ } else {
+ updateProgress(i * 100 / rowIdsSize, 100);
+ PGPPublicKeyRing publicKeyRing =
+ ProviderHelper.getPGPPublicKeyRingByRowId(mContext, keyRingRowIds.get(i));
if (publicKeyRing != null) {
- publicKeyRing.encode(outPub);
+ publicKeyRing.encode(arOutStream);
}
}
- outPub.close();
+
+ arOutStream.close();
}
- returnData.putInt(KeychainIntentService.RESULT_EXPORT, keyRingMasterKeyIds.size());
+ returnData.putInt(KeychainIntentService.RESULT_EXPORT, rowIdsSize);
updateProgress(R.string.progress_done, 100, 100);
@@ -234,7 +224,7 @@ public class PgpImportExport {
for (PGPSecretKey testSecretKey : new IterableIterator<PGPSecretKey>(
secretKeyRing.getSecretKeys())) {
if (!testSecretKey.isMasterKey()) {
- if (PgpKeyHelper.isSecretKeyPrivateEmpty(testSecretKey)) {
+ if (testSecretKey.isPrivateKeyEmpty()) {
// this is bad, something is very wrong...
save = false;
status = Id.return_value.bad;
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 38480a766..902dd8da9 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
@@ -32,6 +32,7 @@ import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
+import org.spongycastle.util.encoders.Hex;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
@@ -415,28 +416,27 @@ public class PgpKeyHelper {
String algorithmStr = null;
switch (algorithm) {
- case PGPPublicKey.RSA_ENCRYPT:
- case PGPPublicKey.RSA_GENERAL:
- case PGPPublicKey.RSA_SIGN: {
- algorithmStr = "RSA";
- break;
- }
-
- case PGPPublicKey.DSA: {
- algorithmStr = "DSA";
- break;
- }
+ case PGPPublicKey.RSA_ENCRYPT:
+ case PGPPublicKey.RSA_GENERAL:
+ case PGPPublicKey.RSA_SIGN: {
+ algorithmStr = "RSA";
+ break;
+ }
+ case PGPPublicKey.DSA: {
+ algorithmStr = "DSA";
+ break;
+ }
- case PGPPublicKey.ELGAMAL_ENCRYPT:
- case PGPPublicKey.ELGAMAL_GENERAL: {
- algorithmStr = "ElGamal";
- break;
- }
+ case PGPPublicKey.ELGAMAL_ENCRYPT:
+ case PGPPublicKey.ELGAMAL_GENERAL: {
+ algorithmStr = "ElGamal";
+ break;
+ }
- default: {
- algorithmStr = "Unknown";
- break;
- }
+ default: {
+ algorithmStr = "Unknown";
+ break;
+ }
}
if(keySize > 0)
return algorithmStr + ", " + keySize + " bit";
@@ -444,31 +444,6 @@ public class PgpKeyHelper {
return algorithmStr;
}
- /**
- * Converts fingerprint to hex with whitespaces after 4 characters
- *
- * @param fp
- * @return
- */
- public static String convertFingerprintToHex(byte[] fp, boolean chunked) {
- String fingerPrint = "";
- for (int i = 0; i < fp.length; ++i) {
- if (chunked && i != 0 && i % 10 == 0) {
- fingerPrint += " ";
- } else if (chunked && i != 0 && i % 2 == 0) {
- fingerPrint += " ";
- }
- String chunk = Integer.toHexString((fp[i] + 256) % 256).toUpperCase(Locale.US);
- while (chunk.length() < 2) {
- chunk = "0" + chunk;
- }
- fingerPrint += chunk;
- }
-
- return fingerPrint;
-
- }
-
public static String getFingerPrint(Context context, long keyId) {
PGPPublicKey key = ProviderHelper.getPGPPublicKeyByKeyId(context, keyId);
// if it is no public key get it from your own keys...
@@ -484,52 +459,68 @@ public class PgpKeyHelper {
return convertFingerprintToHex(key.getFingerprint(), true);
}
- public static boolean isSecretKeyPrivateEmpty(PGPSecretKey secretKey) {
- return secretKey.isPrivateKeyEmpty();
- }
-
-// public static boolean isSecretKeyPrivateEmpty(Context context, long keyId) {
-// PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, keyId);
-// if (secretKey == null) {
-// Log.e(Constants.TAG, "Key could not be found!");
-// return false; // could be a public key, assume it is not empty
-// }
-// return isSecretKeyPrivateEmpty(secretKey);
-// }
-
- public static String convertKeyIdToHex(long keyId) {
- String fingerPrint = Long.toHexString(keyId & 0xffffffffL).toUpperCase(Locale.US);
- while (fingerPrint.length() < 8) {
- fingerPrint = "0" + fingerPrint;
+ /**
+ * Converts fingerprint to hex (optional: with whitespaces after 4 characters)
+ * <p/>
+ * Fingerprint is shown using lowercase characters. Studies have shown that humans can
+ * better differentiate between numbers and letters when letters are lowercase.
+ *
+ * @param fingerprint
+ * @param split split into 4 character chunks
+ * @return
+ */
+ public static String convertFingerprintToHex(byte[] fingerprint, boolean split) {
+ String hexString = Hex.toHexString(fingerprint);
+ if (split) {
+ hexString = hexString.replaceAll("(.{4})(?!$)", "$1 ");
}
- return fingerPrint;
+
+ return hexString;
}
/**
- * TODO: documentation
- *
+ * Convert key id from long to 64 bit hex string
+ * <p/>
+ * V4: "The Key ID is the low-order 64 bits of the fingerprint"
+ * <p/>
+ * see http://tools.ietf.org/html/rfc4880#section-12.2
+ *
* @param keyId
* @return
*/
- public static String convertKeyToHex(long keyId) {
- return convertKeyIdToHex(keyId >> 32) + convertKeyIdToHex(keyId);
+ public static String convertKeyIdToHex(long keyId) {
+ return "0x" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId);
+ }
+
+ private static String convertKeyIdToHex32bit(long keyId) {
+ String hexString = Long.toHexString(keyId & 0xffffffffL).toLowerCase(Locale.US);
+ while (hexString.length() < 8) {
+ hexString = "0" + hexString;
+ }
+ return hexString;
}
- public static long convertHexToKeyId(String data) {
- int len = data.length();
- String s2 = data.substring(len - 8);
- String s1 = data.substring(0, len - 8);
+ /**
+ * Used in HkpKeyServer to convert hex encoded key ids back to long.
+ *
+ * @param hexString
+ * @return
+ */
+ public static long convertHexToKeyId(String hexString) {
+ int len = hexString.length();
+ String s2 = hexString.substring(len - 8);
+ String s1 = hexString.substring(0, len - 8);
return (Long.parseLong(s1, 16) << 32) | Long.parseLong(s2, 16);
}
/**
* Splits userId string into naming part, email part, and comment part
- *
+ *
* @param userId
* @return array with naming (0), email (1), comment (2)
*/
public static String[] splitUserId(String userId) {
- String[] result = new String[] { null, null, null };
+ String[] result = new String[]{null, null, null};
if (userId == null || userId.equals("")) {
return result;
@@ -550,7 +541,6 @@ public class PgpKeyHelper {
result[0] = matcher.group(1);
result[1] = matcher.group(3);
result[2] = matcher.group(2);
- return result;
}
return result;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
index 7caee4048..5ebb53f20 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
@@ -107,7 +107,7 @@ public class PgpKeyOperation {
*
* @param algorithmChoice
* @param keySize
- * @param passPhrase
+ * @param passphrase
* @param isMasterKey
* @return
* @throws NoSuchAlgorithmException
@@ -118,7 +118,7 @@ public class PgpKeyOperation {
*/
// TODO: key flags?
- public PGPSecretKey createKey(int algorithmChoice, int keySize, String passPhrase,
+ public PGPSecretKey createKey(int algorithmChoice, int keySize, String passphrase,
boolean isMasterKey) throws NoSuchAlgorithmException, PGPException, NoSuchProviderException,
PgpGeneralException, InvalidAlgorithmParameterException {
@@ -126,8 +126,8 @@ public class PgpKeyOperation {
throw new PgpGeneralException(mContext.getString(R.string.error_key_size_minimum512bit));
}
- if (passPhrase == null) {
- passPhrase = "";
+ if (passphrase == null) {
+ passphrase = "";
}
int algorithm = 0;
@@ -181,7 +181,7 @@ public class PgpKeyOperation {
// Build key encrypter and decrypter based on passphrase
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
PGPEncryptedData.CAST5, sha1Calc)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passPhrase.toCharArray());
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
PGPSecretKey secKey = new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
sha1Calc, isMasterKey, keyEncryptor);
@@ -190,7 +190,7 @@ public class PgpKeyOperation {
}
public void changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassPhrase,
- String newPassPhrase) throws IOException, PGPException, PGPException,
+ String newPassPhrase) throws IOException, PGPException,
NoSuchProviderException {
updateProgress(R.string.progress_building_key, 0, 100);
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 171aa9912..f072e13be 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
@@ -342,7 +342,7 @@ public class KeychainProvider extends ContentProvider {
/**
* Returns type of the query (secret/public)
*
- * @param uri
+ * @param match
* @return
*/
private int getKeyType(int match) {
@@ -1039,7 +1039,8 @@ public class KeychainProvider extends ContentProvider {
* Build default selection statement for KeyRings. If no extra selection is specified only build
* where clause with rowId
*
- * @param uri
+ * @param defaultSelection
+ * @param keyType
* @param selection
* @return
*/
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 c1b2ef6e3..f740e1c7c 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
@@ -100,7 +100,7 @@ public class ProviderHelper {
}
/**
- * Retrieves the actual PGPPublicKeyRing object from the database blob based on the maserKeyId
+ * Retrieves the actual PGPPublicKeyRing object from the database blob based on the masterKeyId
*/
public static PGPPublicKeyRing getPGPPublicKeyRingByMasterKeyId(Context context,
long masterKeyId) {
@@ -123,11 +123,8 @@ public class ProviderHelper {
*/
public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) {
PGPPublicKeyRing keyRing = getPGPPublicKeyRingByKeyId(context, keyId);
- if (keyRing == null) {
- return null;
- }
- return keyRing.getPublicKey(keyId);
+ return (keyRing == null)? null : keyRing.getPublicKey(keyId);
}
/**
@@ -162,11 +159,8 @@ public class ProviderHelper {
*/
public static PGPSecretKey getPGPSecretKeyByKeyId(Context context, long keyId) {
PGPSecretKeyRing keyRing = getPGPSecretKeyRingByKeyId(context, keyId);
- if (keyRing == null) {
- return null;
- }
- return keyRing.getSecretKey(keyId);
+ return (keyRing == null) ? null : keyRing.getSecretKey(keyId);
}
/**
@@ -411,10 +405,10 @@ public class ProviderHelper {
long keyRingRowId, PGPSecretKey key, int rank) throws IOException {
ContentValues values = new ContentValues();
- boolean has_private = true;
+ boolean hasPrivate = true;
if (key.isMasterKey()) {
- if (PgpKeyHelper.isSecretKeyPrivateEmpty(key)) {
- has_private = false;
+ if (key.isPrivateKeyEmpty()) {
+ hasPrivate = false;
}
}
@@ -422,8 +416,8 @@ public class ProviderHelper {
values.put(Keys.IS_MASTER_KEY, key.isMasterKey());
values.put(Keys.ALGORITHM, key.getPublicKey().getAlgorithm());
values.put(Keys.KEY_SIZE, key.getPublicKey().getBitStrength());
- values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key) && has_private));
- values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key) && has_private));
+ values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key) && hasPrivate));
+ values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key) && hasPrivate));
values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key));
values.put(Keys.IS_REVOKED, key.getPublicKey().isRevoked());
values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000);
@@ -481,6 +475,30 @@ public class ProviderHelper {
}
/**
+ * Private helper method
+ */
+ private static ArrayList<Long> getKeyRingsRowIds(Context context, Uri queryUri) {
+ Cursor cursor = context.getContentResolver().query(queryUri,
+ new String[]{KeyRings._ID}, null, null, null);
+
+ ArrayList<Long> rowIds = new ArrayList<Long>();
+ if (cursor != null) {
+ int IdCol = cursor.getColumnIndex(KeyRings._ID);
+ if (cursor.moveToFirst()) {
+ do {
+ rowIds.add(cursor.getLong(IdCol));
+ } while (cursor.moveToNext());
+ }
+ }
+
+ if (cursor != null) {
+ cursor.close();
+ }
+
+ return rowIds;
+ }
+
+ /**
* Retrieves ids of all SecretKeyRings
*/
public static ArrayList<Long> getSecretKeyRingsMasterKeyIds(Context context) {
@@ -496,6 +514,22 @@ public class ProviderHelper {
return getKeyRingsMasterKeyIds(context, queryUri);
}
+ /**
+ * Retrieves ids of all SecretKeyRings
+ */
+ public static ArrayList<Long> getSecretKeyRingsRowIds(Context context) {
+ Uri queryUri = KeyRings.buildSecretKeyRingsUri();
+ return getKeyRingsRowIds(context, queryUri);
+ }
+
+ /**
+ * Retrieves ids of all PublicKeyRings
+ */
+ public static ArrayList<Long> getPublicKeyRingsRowIds(Context context) {
+ Uri queryUri = KeyRings.buildPublicKeyRingsUri();
+ return getKeyRingsRowIds(context, queryUri);
+ }
+
public static void deletePublicKeyRing(Context context, long rowId) {
ContentResolver cr = context.getContentResolver();
cr.delete(KeyRings.buildPublicKeyRingsUri(Long.toString(rowId)), null, null);
@@ -722,7 +756,7 @@ public class ProviderHelper {
String armoredKey = bos.toString("UTF-8");
- Log.d(Constants.TAG, "armouredKey:" + armoredKey);
+ Log.d(Constants.TAG, "armoredKey:" + armoredKey);
output.add(armoredKey);
} catch (IOException e) {
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 302dbea0b..93238349d 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
@@ -44,11 +44,13 @@ import org.sufficientlysecure.keychain.helper.OtherHelper;
import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpImportExport;
import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
@@ -152,6 +154,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
public static final String EXPORT_KEY_TYPE = "export_key_type";
public static final String EXPORT_ALL = "export_all";
public static final String EXPORT_KEY_RING_MASTER_KEY_ID = "export_key_ring_id";
+ public static final String EXPORT_KEY_RING_ROW_ID = "export_key_rind_row_id";
// upload key
public static final String UPLOAD_KEY_SERVER = "upload_key_server";
@@ -181,13 +184,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
// decrypt/verify
public static final String RESULT_DECRYPTED_STRING = "decrypted_message";
public static final String RESULT_DECRYPTED_BYTES = "decrypted_data";
- public static final String RESULT_SIGNATURE = "signature";
- public static final String RESULT_SIGNATURE_KEY_ID = "signature_key_id";
- public static final String RESULT_SIGNATURE_USER_ID = "signature_user_id";
- public static final String RESULT_CLEARTEXT_SIGNATURE_ONLY = "signature_only";
-
- public static final String RESULT_SIGNATURE_SUCCESS = "signature_success";
- public static final String RESULT_SIGNATURE_UNKNOWN = "signature_unknown";
+ public static final String RESULT_DECRYPT_VERIFY_RESULT = "signature";
// import
public static final String RESULT_IMPORT_ADDED = "added";
@@ -206,7 +203,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
private boolean mIsCanceled;
public KeychainIntentService() {
- super("ApgService");
+ super("KeychainIntentService");
}
@Override
@@ -489,15 +486,17 @@ public class KeychainIntentService extends IntentService implements ProgressDial
// verifyText and decrypt returning additional resultData values for the
// verification of signatures
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, outStream);
- builder.progress(this);
+ builder.progressDialogUpdater(this);
builder.assumeSymmetric(assumeSymmetricEncryption)
.passphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId));
- resultData = builder.build().execute();
+ PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
outStream.close();
+ resultData.putParcelable(RESULT_DECRYPT_VERIFY_RESULT, decryptVerifyResult);
+
/* Output */
switch (target) {
@@ -599,13 +598,23 @@ public class KeychainIntentService extends IntentService implements ProgressDial
String passphrase = data.getString(GENERATE_KEY_SYMMETRIC_PASSPHRASE);
/* Operation */
+ int keysTotal = 2;
+ int keysCreated = 0;
+ setProgress(
+ getApplicationContext().getResources().getQuantityString(R.plurals.progress_generating, keysTotal),
+ keysCreated,
+ keysTotal);
PgpKeyOperation keyOperations = new PgpKeyOperation(this, this);
PGPSecretKey masterKey = keyOperations.createKey(Id.choice.algorithm.rsa,
4096, passphrase, true);
+ keysCreated++;
+ setProgress(keysCreated, keysTotal);
PGPSecretKey subKey = keyOperations.createKey(Id.choice.algorithm.rsa,
4096, passphrase, false);
+ keysCreated++;
+ setProgress(keysCreated, keysTotal);
// TODO: default to one master for cert, one sub for encrypt and one sub
// for sign
@@ -668,10 +677,12 @@ public class KeychainIntentService extends IntentService implements ProgressDial
String outputFile = data.getString(EXPORT_FILENAME);
+ long[] rowIds = new long[0];
+
+ // If not exporting all keys get the rowIds of the keys to export from the intent
boolean exportAll = data.getBoolean(EXPORT_ALL);
- long keyRingMasterKeyId = -1;
if (!exportAll) {
- keyRingMasterKeyId = data.getLong(EXPORT_KEY_RING_MASTER_KEY_ID);
+ rowIds = data.getLongArray(EXPORT_KEY_RING_ROW_ID);
}
/* Operation */
@@ -684,24 +695,26 @@ public class KeychainIntentService extends IntentService implements ProgressDial
// OutputStream
FileOutputStream outStream = new FileOutputStream(outputFile);
- ArrayList<Long> keyRingMasterKeyIds = new ArrayList<Long>();
+ ArrayList<Long> keyRingRowIds = new ArrayList<Long>();
if (exportAll) {
- // get all key ring row ids based on export type
+ // get all key ring row ids based on export type
if (keyType == Id.type.public_key) {
- keyRingMasterKeyIds = ProviderHelper.getPublicKeyRingsMasterKeyIds(this);
+ keyRingRowIds = ProviderHelper.getPublicKeyRingsRowIds(this);
} else {
- keyRingMasterKeyIds = ProviderHelper.getSecretKeyRingsMasterKeyIds(this);
+ keyRingRowIds = ProviderHelper.getSecretKeyRingsRowIds(this);
}
} else {
- keyRingMasterKeyIds.add(keyRingMasterKeyId);
+ for(long rowId : rowIds) {
+ keyRingRowIds.add(rowId);
+ }
}
- Bundle resultData = new Bundle();
+ Bundle resultData;
PgpImportExport pgpImportExport = new PgpImportExport(this, this);
resultData = pgpImportExport
- .exportKeyRings(keyRingMasterKeyIds, keyType, outStream);
+ .exportKeyRings(keyRingRowIds, keyType, outStream);
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
} catch (Exception e) {
@@ -751,7 +764,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
*/
// 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
- // armour blocks
+ // armor blocks
BufferedInputStream bufferedInput = new BufferedInputStream(new ByteArrayInputStream(downloadedKey));
try {
@@ -867,10 +880,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial
}
/**
- * Set progress of ProgressDialog by sending message to handler on UI thread
+ * Set progressDialogUpdater of ProgressDialog by sending message to handler on UI thread
*/
public void setProgress(String message, int progress, int max) {
- Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max="
+ Log.d(Constants.TAG, "Send message by setProgress with progressDialogUpdater=" + progress + ", max="
+ max);
Bundle data = new Bundle();
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
index 6eba9cc83..ebc002ceb 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
@@ -21,7 +21,6 @@ import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
import org.sufficientlysecure.keychain.R;
import android.app.Activity;
-import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.os.Handler;
@@ -51,21 +50,26 @@ public class KeychainIntentServiceHandler extends Handler {
this.mActivity = activity;
}
- public KeychainIntentServiceHandler(Activity activity, ProgressDialogFragment progressDialogFragment) {
+ public KeychainIntentServiceHandler(Activity activity,
+ ProgressDialogFragment progressDialogFragment) {
this.mActivity = activity;
this.mProgressDialogFragment = progressDialogFragment;
}
- public KeychainIntentServiceHandler(Activity activity, int progressDialogMessageId, int progressDialogStyle) {
- this(activity, progressDialogMessageId, progressDialogStyle, false, null);
+ public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage,
+ int progressDialogStyle) {
+ this(activity, progressDialogMessage, progressDialogStyle, false, null);
}
- public KeychainIntentServiceHandler(Activity activity, int progressDialogMessageId,
+ public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage,
int progressDialogStyle, boolean cancelable,
OnCancelListener onCancelListener) {
this.mActivity = activity;
- this.mProgressDialogFragment = ProgressDialogFragment.newInstance(progressDialogMessageId,
- progressDialogStyle, cancelable, onCancelListener);
+ this.mProgressDialogFragment = ProgressDialogFragment.newInstance(
+ progressDialogMessage,
+ progressDialogStyle,
+ cancelable,
+ onCancelListener);
}
public void showProgressDialog(FragmentActivity activity) {
@@ -84,43 +88,43 @@ public class KeychainIntentServiceHandler extends Handler {
Bundle data = message.getData();
switch (message.arg1) {
- case MESSAGE_OKAY:
- mProgressDialogFragment.dismissAllowingStateLoss();
+ case MESSAGE_OKAY:
+ mProgressDialogFragment.dismissAllowingStateLoss();
- break;
+ break;
- case MESSAGE_EXCEPTION:
- mProgressDialogFragment.dismissAllowingStateLoss();
+ case MESSAGE_EXCEPTION:
+ mProgressDialogFragment.dismissAllowingStateLoss();
- // show error from service
- if (data.containsKey(DATA_ERROR)) {
- Toast.makeText(mActivity,
- mActivity.getString(R.string.error_message, data.getString(DATA_ERROR)),
- Toast.LENGTH_SHORT).show();
- }
+ // show error from service
+ if (data.containsKey(DATA_ERROR)) {
+ Toast.makeText(mActivity,
+ mActivity.getString(R.string.error_message, data.getString(DATA_ERROR)),
+ Toast.LENGTH_SHORT).show();
+ }
- break;
-
- case MESSAGE_UPDATE_PROGRESS:
- if (data.containsKey(DATA_PROGRESS) && data.containsKey(DATA_PROGRESS_MAX)) {
-
- // update progress from service
- if (data.containsKey(DATA_MESSAGE)) {
- mProgressDialogFragment.setProgress(data.getString(DATA_MESSAGE),
- data.getInt(DATA_PROGRESS), data.getInt(DATA_PROGRESS_MAX));
- } else if (data.containsKey(DATA_MESSAGE_ID)) {
- mProgressDialogFragment.setProgress(data.getInt(DATA_MESSAGE_ID),
- data.getInt(DATA_PROGRESS), data.getInt(DATA_PROGRESS_MAX));
- } else {
- mProgressDialogFragment.setProgress(data.getInt(DATA_PROGRESS),
- data.getInt(DATA_PROGRESS_MAX));
+ break;
+
+ case MESSAGE_UPDATE_PROGRESS:
+ if (data.containsKey(DATA_PROGRESS) && data.containsKey(DATA_PROGRESS_MAX)) {
+
+ // update progress from service
+ if (data.containsKey(DATA_MESSAGE)) {
+ mProgressDialogFragment.setProgress(data.getString(DATA_MESSAGE),
+ data.getInt(DATA_PROGRESS), data.getInt(DATA_PROGRESS_MAX));
+ } else if (data.containsKey(DATA_MESSAGE_ID)) {
+ mProgressDialogFragment.setProgress(data.getInt(DATA_MESSAGE_ID),
+ data.getInt(DATA_PROGRESS), data.getInt(DATA_PROGRESS_MAX));
+ } else {
+ mProgressDialogFragment.setProgress(data.getInt(DATA_PROGRESS),
+ data.getInt(DATA_PROGRESS_MAX));
+ }
}
- }
- break;
+ break;
- default:
- break;
+ default:
+ break;
}
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
index abd2320e3..ce34d451d 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
@@ -21,6 +21,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
+import android.util.LongSparseArray;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPSecretKey;
@@ -77,7 +78,7 @@ public class PassphraseCacheService extends Service {
private BroadcastReceiver mIntentReceiver;
- private HashMap<Long, String> mPassphraseCache = new HashMap<Long, String>();
+ private LongSparseArray<String> mPassphraseCache = new LongSparseArray<String>();
Context mContext;
@@ -347,7 +348,7 @@ public class PassphraseCacheService extends Service {
Log.d(TAG, "Timeout of keyId " + keyId + ", removed from memory!");
// stop whole service if no cached passphrases remaining
- if (mPassphraseCache.isEmpty()) {
+ if (mPassphraseCache.size() == 0) {
Log.d(TAG, "No passphrases remaining in memory, stopping service!");
stopSelf();
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java
index a7afc9698..178b2fc67 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java
@@ -41,7 +41,7 @@ public class AppSettingsActivity extends ActionBarActivity {
super.onCreate(savedInstanceState);
// Inflate a "Done" custom action bar
- ActionBarHelper.setDoneView(getSupportActionBar(), R.string.api_settings_save,
+ ActionBarHelper.setOneButtonView(getSupportActionBar(), R.string.api_settings_save, R.drawable.ic_action_done,
new View.OnClickListener() {
@Override
public void onClick(View v) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java
index 8c8e6f00a..f697faa6e 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java
@@ -21,7 +21,6 @@ import android.app.PendingIntent;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
-import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -33,9 +32,11 @@ import org.spongycastle.util.Arrays;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
+import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
@@ -103,9 +104,8 @@ public class OpenPgpService extends RemoteService {
// 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);
-
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
return result;
}
@@ -114,8 +114,8 @@ public class OpenPgpService extends RemoteService {
}
Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
result.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keyIdsArray);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
}
@@ -130,9 +130,8 @@ public class OpenPgpService extends RemoteService {
// 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);
-
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
return result;
}
@@ -179,9 +178,9 @@ public class OpenPgpService extends RemoteService {
return result;
} catch (Exception e) {
Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- result.putExtra(OpenPgpApi.RESULT_ERRORS,
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
}
@@ -208,9 +207,9 @@ public class OpenPgpService extends RemoteService {
}
} else {
Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- result.putExtra(OpenPgpApi.RESULT_ERRORS,
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, "Missing parameter user_ids or key_ids!"));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
@@ -267,9 +266,9 @@ public class OpenPgpService extends RemoteService {
return result;
} catch (Exception e) {
Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- result.putExtra(OpenPgpApi.RESULT_ERRORS,
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
}
@@ -284,98 +283,30 @@ public class OpenPgpService extends RemoteService {
Intent result = new Intent();
try {
- // TODO:
- // fix the mess: http://stackoverflow.com/questions/148130/how-do-i-peek-at-the-first-two-bytes-in-an-inputstream
- // should we allow to decrypt everything under every key id or only the one set?
- // TODO: instead of trying to get the passphrase before
- // pause stream when passphrase is missing and then resume
-
- // TODO: put this code into PgpDecryptVerify class
-
- // TODO: This allows to decrypt messages with ALL secret keys, not only the one for the
- // app, Fix this?
-// String passphrase = null;
-// if (!signedOnly) {
-// // BEGIN Get key
-// // TODO: this input stream is consumed after PgpMain.getDecryptionKeyId()... do it
-// // better!
-// InputStream inputStream2 = new ByteArrayInputStream(inputBytes);
-//
-// // TODO: duplicates functions from DecryptActivity!
-// long secretKeyId;
-// try {
-// if (inputStream2.markSupported()) {
-// // should probably set this to the max size of two
-// // pgpF objects, if it even needs to be anything other
-// // than 0.
-// inputStream2.mark(200);
-// }
-// secretKeyId = PgpHelper.getDecryptionKeyId(this, inputStream2);
-// if (secretKeyId == Id.key.none) {
-// throw new PgpGeneralException(getString(R.string.error_no_secret_key_found));
-// }
-// } catch (NoAsymmetricEncryptionException e) {
-// if (inputStream2.markSupported()) {
-// inputStream2.reset();
-// }
-// secretKeyId = Id.key.symmetric;
-// if (!PgpDecryptVerify.hasSymmetricEncryption(this, inputStream2)) {
-// throw new PgpGeneralException(
-// getString(R.string.error_no_known_encryption_found));
-// }
-// // we do not support symmetric decryption from the API!
-// throw new Exception("Symmetric decryption is not supported!");
-// }
-//
-// Log.d(Constants.TAG, "secretKeyId " + secretKeyId);
-
- // NOTE: currently this only gets the passphrase for the key set for this client
- String passphrase;
- if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
- passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
- } else {
- passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId());
- }
- if (passphrase == null) {
- // get PendingIntent for passphrase input, add it to given params and return to client
- Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
- return passphraseBundle;
- }
-
+ String passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
long inputLength = is.available();
InputData inputData = new InputData(is, inputLength);
- Bundle outputBundle;
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os);
-
- builder.assumeSymmetric(false)
+ builder.assumeSymmetric(false) // no support for symmetric encryption
+ .enforcedKeyId(appSettings.getKeyId()) // allow only the private key for this app for decryption
.passphrase(passphrase);
- // TODO: this also decrypts with other secret keys that have no passphrase!!!
- outputBundle = builder.build().execute();
-
- //TODO: instead of using all these wrapping use OpenPgpSignatureResult directly
- // in DecryptVerify class and then in DecryptActivity
- boolean signature = outputBundle.getBoolean(KeychainIntentService.RESULT_SIGNATURE, false);
- if (signature) {
- long signatureKeyId = outputBundle
- .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, 0);
- String signatureUserId = outputBundle
- .getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
- boolean signatureSuccess = outputBundle
- .getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, false);
- boolean signatureUnknown = outputBundle
- .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, false);
- boolean signatureOnly = outputBundle
- .getBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, false);
-
- int signatureStatus = OpenPgpSignatureResult.SIGNATURE_ERROR;
- if (signatureSuccess) {
- signatureStatus = OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED;
- } else if (signatureUnknown) {
- signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY;
-
- // If signature is unknown we return an additional PendingIntent
+ // TODO: currently does not support binary signed-only content
+ PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
+
+ if (decryptVerifyResult.isKeyPassphraseNeeded()) {
+ // get PendingIntent for passphrase input, add it to given params and return to client
+ Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
+ return passphraseBundle;
+ } else if (decryptVerifyResult.isSymmetricPassphraseNeeded()) {
+ throw new PgpGeneralException("Decryption of symmetric content not supported by API!");
+ }
+
+ OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
+ if (signatureResult != null) {
+ if (signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY) {
+ // If signature is unknown we return an _additional_ PendingIntent
// to retrieve the missing key
// TODO!!!
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
@@ -389,11 +320,9 @@ public class OpenPgpService extends RemoteService {
result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
}
-
- OpenPgpSignatureResult sigResult = new OpenPgpSignatureResult(signatureStatus,
- signatureUserId, signatureOnly, signatureKeyId);
- result.putExtra(OpenPgpApi.RESULT_SIGNATURE, sigResult);
+ result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
}
+
} finally {
is.close();
os.close();
@@ -403,9 +332,44 @@ public class OpenPgpService extends RemoteService {
return result;
} catch (Exception e) {
Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
+ new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- result.putExtra(OpenPgpApi.RESULT_ERRORS,
+ return result;
+ }
+ }
+
+ private Intent getKeyImpl(Intent data) {
+ try {
+ long keyId = data.getLongExtra(OpenPgpApi.EXTRA_KEY_ID, 0);
+
+ if (ProviderHelper.getPGPPublicKeyByKeyId(this, keyId) == null) {
+ Intent result = new Intent();
+
+ // If keys are not in db we return an additional PendingIntent
+ // to retrieve the missing key
+ // TODO!!!
+ Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
+ intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
+ intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo");
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
+
+ PendingIntent pi = PendingIntent.getActivity(getBaseContext(),
+ PRIVATE_REQUEST_CODE_GET_KEYS, intent, 0);
+
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
+ return result;
+ } else {
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
+ return result;
+ }
+ } catch (Exception e) {
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
}
@@ -431,7 +395,7 @@ public class OpenPgpService extends RemoteService {
if (data == null) {
Intent result = new Intent();
OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!");
- result.putExtra(OpenPgpApi.RESULT_ERRORS, error);
+ result.putExtra(OpenPgpApi.RESULT_ERROR, error);
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
@@ -440,7 +404,7 @@ public class OpenPgpService extends RemoteService {
if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != OpenPgpApi.API_VERSION) {
Intent result = new Intent();
OpenPgpError error = new OpenPgpError(OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!");
- result.putExtra(OpenPgpApi.RESULT_ERRORS, error);
+ result.putExtra(OpenPgpApi.RESULT_ERROR, error);
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
@@ -471,13 +435,12 @@ public class OpenPgpService extends RemoteService {
return signImpl(data, input, output, appSettings);
} else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) {
return encryptAndSignImpl(data, input, output, appSettings, false);
- } else if (OpenPgpApi.ACTION_SIGN_AND_ENCTYPT.equals(action)) {
+ } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) {
return encryptAndSignImpl(data, input, output, appSettings, true);
} else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) {
return decryptAndVerifyImpl(data, input, output, appSettings);
- } else if (OpenPgpApi.ACTION_DOWNLOAD_KEYS.equals(action)) {
- // TODO!
- return null;
+ } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) {
+ return getKeyImpl(data);
} else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) {
return getKeyIdsImpl(data);
} else {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
index e7b3b2945..cb556be39 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
@@ -72,7 +72,7 @@ public abstract class RemoteService extends Service {
// return error
Intent result = new Intent();
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- result.putExtra(OpenPgpApi.RESULT_ERRORS,
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
return result;
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java
index 11b3ee217..8fb562884 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java
@@ -88,7 +88,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE);
// Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.api_register_allow,
+ ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.api_register_allow, R.drawable.ic_action_done,
new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -108,7 +108,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
RemoteServiceActivity.this.finish();
}
}
- }, R.string.api_register_disallow, new View.OnClickListener() {
+ }, R.string.api_register_disallow, R.drawable.ic_action_cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
// Disallow
@@ -161,7 +161,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
}
// Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_okay,
+ ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done,
new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -173,7 +173,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
RemoteServiceActivity.this.finish();
}
- }, R.string.btn_do_not_save, new View.OnClickListener() {
+ }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
// cancel
@@ -214,7 +214,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
String text = "<font color=\"red\">" + errorMessage + "</font>";
// Inflate a "Done" custom action bar view
- ActionBarHelper.setDoneView(getSupportActionBar(), R.string.btn_okay,
+ ActionBarHelper.setOneButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done,
new View.OnClickListener() {
@Override
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 aab6b81d9..029dda1a0 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
@@ -230,7 +230,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
// Message is received after signing is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_signing, ProgressDialog.STYLE_SPINNER) {
+ getString(R.string.progress_signing), ProgressDialog.STYLE_SPINNER) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -249,7 +249,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
finish();
}
}
- };
+ }
};
// Create a new Messenger for the communication back
@@ -283,7 +283,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
// Message is received after uploading is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_exporting, ProgressDialog.STYLE_HORIZONTAL) {
+ getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -295,7 +295,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
setResult(RESULT_OK);
finish();
}
- };
+ }
};
// Create a new Messenger for the communication back
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 9bb675db0..38d763ce4 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
@@ -25,6 +25,7 @@ import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.regex.Matcher;
+import org.openintents.openpgp.OpenPgpSignatureResult;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
@@ -32,6 +33,7 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.helper.FileHelper;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
@@ -528,6 +530,10 @@ 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());
@@ -644,7 +650,7 @@ public class DecryptActivity extends DrawerActivity {
// Message is received after encrypting is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_decrypting, ProgressDialog.STYLE_HORIZONTAL) {
+ getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -690,11 +696,15 @@ public class DecryptActivity extends DrawerActivity {
}
- if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE)) {
- String userId = returnData
- .getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
- mSignatureKeyId = returnData
- .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
+ PgpDecryptVerifyResult decryptVerifyResult =
+ returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT);
+
+ OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
+
+ if (signatureResult != null) {
+
+ String userId = signatureResult.getUserId();
+ mSignatureKeyId = signatureResult.getKeyId();
mUserIdRest.setText("id: "
+ PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId));
if (userId == null) {
@@ -707,26 +717,37 @@ public class DecryptActivity extends DrawerActivity {
}
mUserId.setText(userId);
- if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS)) {
- mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
- mLookupKey.setVisibility(View.GONE);
- } else if (returnData
- .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN)) {
- mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
- mLookupKey.setVisibility(View.VISIBLE);
- AppMsg.makeText(DecryptActivity.this,
- R.string.unknown_signature,
- AppMsg.STYLE_ALERT).show();
- } else {
- mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
- mLookupKey.setVisibility(View.GONE);
+ switch (signatureResult.getStatus()) {
+ case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: {
+ mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
+ mLookupKey.setVisibility(View.GONE);
+ break;
+ }
+
+ // TODO!
+// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: {
+// break;
+// }
+
+ case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: {
+ mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
+ mLookupKey.setVisibility(View.VISIBLE);
+ AppMsg.makeText(DecryptActivity.this,
+ R.string.unknown_signature,
+ AppMsg.STYLE_ALERT).show();
+ break;
+ }
+
+ default: {
+ mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
+ mLookupKey.setVisibility(View.GONE);
+ break;
+ }
}
mSignatureLayout.setVisibility(View.VISIBLE);
}
}
}
-
- ;
};
// Create a new Messenger for the communication back
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 e2822c898..0c35bb2b1 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
@@ -92,12 +92,12 @@ public class EditKeyActivity extends ActionBarActivity {
private SectionView mUserIdsView;
private SectionView mKeysView;
- private String mCurrentPassPhrase = null;
+ private String mCurrentPassphrase = null;
private String mNewPassPhrase = null;
private String mSavedNewPassPhrase = null;
private boolean mIsPassPhraseSet;
- private BootstrapButton mChangePassPhrase;
+ private BootstrapButton mChangePassphrase;
private CheckBox mNoPassphrase;
@@ -134,14 +134,14 @@ public class EditKeyActivity extends ActionBarActivity {
* @param intent
*/
private void handleActionCreateKey(Intent intent) {
- // Inflate a "Done"/"Cancel" custom action bar
- ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_save,
+ // Inflate a "Save"/"Cancel" custom action bar
+ ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_save, R.drawable.ic_action_save,
new View.OnClickListener() {
@Override
public void onClick(View v) {
saveClicked();
}
- }, R.string.btn_do_not_save, new View.OnClickListener() {
+ }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
cancelClicked();
@@ -150,7 +150,7 @@ public class EditKeyActivity extends ActionBarActivity {
Bundle extras = intent.getExtras();
- mCurrentPassPhrase = "";
+ mCurrentPassphrase = "";
if (extras != null) {
// if userId is given, prefill the fields
@@ -165,7 +165,7 @@ public class EditKeyActivity extends ActionBarActivity {
if (noPassphrase) {
// check "no passphrase" checkbox and remove button
mNoPassphrase.setChecked(true);
- mChangePassPhrase.setVisibility(View.GONE);
+ mChangePassphrase.setVisibility(View.GONE);
}
}
@@ -181,13 +181,14 @@ public class EditKeyActivity extends ActionBarActivity {
// fill values for this action
Bundle data = new Bundle();
data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE,
- mCurrentPassPhrase);
+ mCurrentPassphrase);
serviceIntent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after generating is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
- this, R.string.progress_generating, ProgressDialog.STYLE_SPINNER, true,
+ this, getResources().getQuantityString(R.plurals.progress_generating, 1),
+ ProgressDialog.STYLE_HORIZONTAL, true,
new DialogInterface.OnCancelListener() {
@Override
@@ -224,7 +225,7 @@ public class EditKeyActivity extends ActionBarActivity {
buildLayout();
}
- };
+ }
};
// Create a new Messenger for the communication back
@@ -248,8 +249,8 @@ public class EditKeyActivity extends ActionBarActivity {
* @param intent
*/
private void handleActionEditKey(Intent intent) {
- // Inflate a "Done"/"Cancel" custom action bar
- ActionBarHelper.setDoneView(getSupportActionBar(), R.string.btn_save,
+ // Inflate a "Save"/"Cancel" custom action bar
+ ActionBarHelper.setOneButtonView(getSupportActionBar(), R.string.btn_save, R.drawable.ic_action_save,
new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -279,9 +280,9 @@ public class EditKeyActivity extends ActionBarActivity {
@Override
public void handleMessage(Message message) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
- String passPhrase = PassphraseCacheService.getCachedPassphrase(
+ String passphrase = PassphraseCacheService.getCachedPassphrase(
EditKeyActivity.this, masterKeyId);
- mCurrentPassPhrase = passPhrase;
+ mCurrentPassphrase = passphrase;
finallySaveClicked();
}
}
@@ -326,8 +327,8 @@ public class EditKeyActivity extends ActionBarActivity {
cancelClicked();
return true;
case R.id.menu_key_edit_export_file:
- mExportHelper.showExportKeysDialog(mDataUri, Id.type.secret_key, Constants.path.APP_DIR
- + "/secexport.asc");
+ long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())};
+ mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.path.APP_DIR_FILE_SEC);
return true;
case R.id.menu_key_edit_delete: {
// Message is received after key is deleted
@@ -371,14 +372,14 @@ public class EditKeyActivity extends ActionBarActivity {
}
}
- mCurrentPassPhrase = "";
+ mCurrentPassphrase = "";
buildLayout();
mIsPassPhraseSet = PassphraseCacheService.hasPassphrase(this, masterKeyId);
if (!mIsPassPhraseSet) {
// check "no passphrase" checkbox and remove button
mNoPassphrase.setChecked(true);
- mChangePassPhrase.setVisibility(View.GONE);
+ mChangePassphrase.setVisibility(View.GONE);
}
}
@@ -408,7 +409,7 @@ public class EditKeyActivity extends ActionBarActivity {
// set title based on isPassphraseSet()
int title = -1;
if (isPassphraseSet()) {
- title = R.string.title_change_pass_phrase;
+ title = R.string.title_change_passphrase;
} else {
title = R.string.title_set_passphrase;
}
@@ -427,7 +428,7 @@ public class EditKeyActivity extends ActionBarActivity {
setContentView(R.layout.edit_key_activity);
// find views
- mChangePassPhrase = (BootstrapButton) findViewById(R.id.edit_key_btn_change_pass_phrase);
+ mChangePassphrase = (BootstrapButton) findViewById(R.id.edit_key_btn_change_passphrase);
mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase);
// Build layout based on given userIds and keys
@@ -447,7 +448,7 @@ public class EditKeyActivity extends ActionBarActivity {
updatePassPhraseButtonText();
- mChangePassPhrase.setOnClickListener(new OnClickListener() {
+ mChangePassphrase.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
showSetPassphraseDialog();
}
@@ -462,10 +463,10 @@ public class EditKeyActivity extends ActionBarActivity {
// remove passphrase
mSavedNewPassPhrase = mNewPassPhrase;
mNewPassPhrase = "";
- mChangePassPhrase.setVisibility(View.GONE);
+ mChangePassphrase.setVisibility(View.GONE);
} else {
mNewPassPhrase = mSavedNewPassPhrase;
- mChangePassPhrase.setVisibility(View.VISIBLE);
+ mChangePassphrase.setVisibility(View.VISIBLE);
}
}
});
@@ -504,7 +505,7 @@ public class EditKeyActivity extends ActionBarActivity {
if (passphrase == null) {
showPassphraseDialog(masterKeyId, masterCanSign);
} else {
- mCurrentPassPhrase = passphrase;
+ mCurrentPassphrase = passphrase;
finallySaveClicked();
}
} catch (PgpGeneralException e) {
@@ -523,7 +524,7 @@ public class EditKeyActivity extends ActionBarActivity {
// fill values for this action
Bundle data = new Bundle();
data.putString(KeychainIntentService.SAVE_KEYRING_CURRENT_PASSPHRASE,
- mCurrentPassPhrase);
+ mCurrentPassphrase);
data.putString(KeychainIntentService.SAVE_KEYRING_NEW_PASSPHRASE, mNewPassPhrase);
data.putStringArrayList(KeychainIntentService.SAVE_KEYRING_USER_IDS,
getUserIds(mUserIdsView));
@@ -541,7 +542,7 @@ public class EditKeyActivity extends ActionBarActivity {
// Message is received after saving is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_saving, ProgressDialog.STYLE_HORIZONTAL) {
+ getString(R.string.progress_saving), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -559,7 +560,7 @@ public class EditKeyActivity extends ActionBarActivity {
setResult(RESULT_OK, data);
finish();
}
- };
+ }
};
// Create a new Messenger for the communication back
@@ -694,7 +695,7 @@ public class EditKeyActivity extends ActionBarActivity {
}
private void updatePassPhraseButtonText() {
- mChangePassPhrase.setText(isPassphraseSet() ? getString(R.string.btn_change_passphrase)
+ mChangePassphrase.setText(isPassphraseSet() ? getString(R.string.btn_change_passphrase)
: getString(R.string.btn_set_passphrase));
}
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 9da6c1b9f..8f8952763 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
@@ -52,17 +52,21 @@ import android.os.Message;
import android.os.Messenger;
import android.view.View;
import android.view.View.OnClickListener;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;
import com.beardedhen.androidbootstrap.BootstrapButton;
+import com.beardedhen.androidbootstrap.FontAwesomeText;
import com.devspark.appmsg.AppMsg;
public class EncryptActivity extends DrawerActivity {
@@ -101,18 +105,24 @@ public class EncryptActivity extends DrawerActivity {
private int mEncryptTarget;
- private EditText mPassPhrase = null;
- private EditText mPassPhraseAgain = null;
+ private EditText mPassphrase = null;
+ private EditText mPassphraseAgain = null;
private CheckBox mAsciiArmor = null;
private Spinner mFileCompression = null;
private EditText mFilename = null;
private CheckBox mDeleteAfter = null;
+ private CheckBox mShareAfter = null;
private BootstrapButton mBrowse = null;
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,6 +157,9 @@ public class EncryptActivity extends DrawerActivity {
updateMode();
updateActionBarButtons();
+
+ // retrieve and cache the system's short animation time
+ mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
}
/**
@@ -436,14 +449,14 @@ public class EncryptActivity extends DrawerActivity {
// symmetric encryption
if (mMode.getCurrentView().getId() == R.id.modeSymmetric) {
boolean gotPassPhrase = false;
- String passPhrase = mPassPhrase.getText().toString();
- String passPhraseAgain = mPassPhraseAgain.getText().toString();
- if (!passPhrase.equals(passPhraseAgain)) {
+ String passphrase = mPassphrase.getText().toString();
+ String passphraseAgain = mPassphraseAgain.getText().toString();
+ if (!passphrase.equals(passphraseAgain)) {
AppMsg.makeText(this, R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
return;
}
- gotPassPhrase = (passPhrase.length() != 0);
+ gotPassPhrase = (passphrase.length() != 0);
if (!gotPassPhrase) {
AppMsg.makeText(this, R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT)
.show();
@@ -550,11 +563,11 @@ public class EncryptActivity extends DrawerActivity {
if (mMode.getCurrentView().getId() == R.id.modeSymmetric) {
Log.d(Constants.TAG, "Symmetric encryption enabled!");
- String passPhrase = mPassPhrase.getText().toString();
- if (passPhrase.length() == 0) {
- passPhrase = null;
+ String passphrase = mPassphrase.getText().toString();
+ if (passphrase.length() == 0) {
+ passphrase = null;
}
- data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passPhrase);
+ data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase);
} else {
mSecretKeyIdToPass = mSecretKeyId;
encryptionKeyIds = mEncryptionKeyIds;
@@ -604,7 +617,7 @@ public class EncryptActivity extends DrawerActivity {
// Message is received after encrypting is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_encrypting, ProgressDialog.STYLE_HORIZONTAL) {
+ getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -650,6 +663,15 @@ public class EncryptActivity extends DrawerActivity {
.newInstance(mInputFilename);
deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog");
}
+
+ if (mShareAfter.isChecked()) {
+ // Share encrypted file
+ Intent sendFileIntent = new Intent(Intent.ACTION_SEND);
+ sendFileIntent.setType("*/*");
+ sendFileIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(mOutputFilename));
+ startActivity(Intent.createChooser(sendFileIntent,
+ getString(R.string.title_send_file)));
+ }
break;
default:
@@ -659,8 +681,6 @@ public class EncryptActivity extends DrawerActivity {
}
}
}
-
- ;
};
// Create a new Messenger for the communication back
@@ -766,8 +786,8 @@ public class EncryptActivity extends DrawerActivity {
mMainUserId = (TextView) findViewById(R.id.mainUserId);
mMainUserIdRest = (TextView) findViewById(R.id.mainUserIdRest);
- mPassPhrase = (EditText) findViewById(R.id.passPhrase);
- mPassPhraseAgain = (EditText) findViewById(R.id.passPhraseAgain);
+ mPassphrase = (EditText) findViewById(R.id.passphrase);
+ mPassphraseAgain = (EditText) findViewById(R.id.passphraseAgain);
// measure the height of the source_file view and set the message view's min height to that,
// so it fills mSource fully... bit of a hack.
@@ -785,6 +805,50 @@ 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[]{
new Choice(Id.choice.compression.none, getString(R.string.choice_none) + " ("
@@ -809,6 +873,7 @@ public class EncryptActivity extends DrawerActivity {
}
mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterEncryption);
+ mShareAfter = (CheckBox) findViewById(R.id.shareAfterEncryption);
mAsciiArmor = (CheckBox) findViewById(R.id.asciiArmour);
mAsciiArmor.setChecked(Preferences.getPreferences(this).getDefaultAsciiArmour());
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
index 9ccd7e088..ac8250bef 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
@@ -22,16 +22,11 @@ import java.util.ArrayList;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentStatePagerAdapter;
-import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
-import android.widget.TextView;
public class HelpActivity extends ActionBarActivity {
public static final String EXTRA_SELECTED_TAB = "selectedTab";
@@ -64,19 +59,19 @@ public class HelpActivity extends ActionBarActivity {
Bundle startBundle = new Bundle();
startBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_start);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_start)),
- HelpHtmlFragment.class, startBundle, (selectedTab == 0 ? true : false));
+ HelpHtmlFragment.class, startBundle, (selectedTab == 0) );
Bundle nfcBundle = new Bundle();
nfcBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_nfc_beam);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_nfc_beam)),
- HelpHtmlFragment.class, nfcBundle, (selectedTab == 1 ? true : false));
+ HelpHtmlFragment.class, nfcBundle, (selectedTab == 1) );
Bundle changelogBundle = new Bundle();
changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_changelog)),
- HelpHtmlFragment.class, changelogBundle, (selectedTab == 2 ? true : false));
+ HelpHtmlFragment.class, changelogBundle, (selectedTab == 2) );
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_about)),
- HelpAboutFragment.class, null, (selectedTab == 3 ? true : false));
+ HelpAboutFragment.class, null, (selectedTab == 3) );
}
} \ No newline at end of file
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 5ac421a44..f04a0e227 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
@@ -161,7 +161,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
} else if (extras.containsKey(EXTRA_KEY_ID)) {
long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0);
if (keyId != 0) {
- query = "0x" + PgpKeyHelper.convertKeyToHex(keyId);
+ query = PgpKeyHelper.convertKeyIdToHex(keyId);
}
} else if (extras.containsKey(EXTRA_FINGERPRINT)) {
String fingerprint = intent.getStringExtra(EXTRA_FINGERPRINT);
@@ -360,51 +360,53 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
// }
- // Message is received after importing is done in ApgService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_importing, ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard ApgHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- // get returned data bundle
- Bundle returnData = message.getData();
-
- int added = returnData.getInt(KeychainIntentService.RESULT_IMPORT_ADDED);
- int updated = returnData
- .getInt(KeychainIntentService.RESULT_IMPORT_UPDATED);
- int bad = returnData.getInt(KeychainIntentService.RESULT_IMPORT_BAD);
- String toastMessage;
- if (added > 0 && updated > 0) {
- String addedStr = getResources().getQuantityString(
- R.plurals.keys_added_and_updated_1, added, added);
- String updatedStr = getResources().getQuantityString(
- R.plurals.keys_added_and_updated_2, updated, updated);
- toastMessage = addedStr + updatedStr;
- } else if (added > 0) {
- toastMessage = getResources().getQuantityString(R.plurals.keys_added,
- added, added);
- } else if (updated > 0) {
- toastMessage = getResources().getQuantityString(R.plurals.keys_updated,
- updated, updated);
- } else {
- toastMessage = getString(R.string.no_keys_added_or_updated);
- }
- AppMsg.makeText(ImportKeysActivity.this, toastMessage, AppMsg.STYLE_INFO)
- .show();
- if (bad > 0) {
- BadImportKeyDialogFragment badImportKeyDialogFragment = BadImportKeyDialogFragment.newInstance(bad);
- badImportKeyDialogFragment.show(getSupportFragmentManager(), "badKeyDialog");
- }
- }
- }
- };
-
/**
* Import keys with mImportData
*/
public void importKeys() {
+ // Message is received after importing is done in ApgService
+ KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
+ this,
+ getString(R.string.progress_importing),
+ ProgressDialog.STYLE_HORIZONTAL) {
+ public void handleMessage(Message message) {
+ // handle messages by standard KeychainIntentServiceHandler first
+ super.handleMessage(message);
+
+ if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
+ // get returned data bundle
+ Bundle returnData = message.getData();
+
+ int added = returnData.getInt(KeychainIntentService.RESULT_IMPORT_ADDED);
+ int updated = returnData
+ .getInt(KeychainIntentService.RESULT_IMPORT_UPDATED);
+ int bad = returnData.getInt(KeychainIntentService.RESULT_IMPORT_BAD);
+ String toastMessage;
+ if (added > 0 && updated > 0) {
+ String addedStr = getResources().getQuantityString(
+ R.plurals.keys_added_and_updated_1, added, added);
+ String updatedStr = getResources().getQuantityString(
+ R.plurals.keys_added_and_updated_2, updated, updated);
+ toastMessage = addedStr + updatedStr;
+ } else if (added > 0) {
+ toastMessage = getResources().getQuantityString(R.plurals.keys_added,
+ added, added);
+ } else if (updated > 0) {
+ toastMessage = getResources().getQuantityString(R.plurals.keys_updated,
+ updated, updated);
+ } else {
+ toastMessage = getString(R.string.no_keys_added_or_updated);
+ }
+ AppMsg.makeText(ImportKeysActivity.this, toastMessage, AppMsg.STYLE_INFO)
+ .show();
+ if (bad > 0) {
+ BadImportKeyDialogFragment badImportKeyDialogFragment = BadImportKeyDialogFragment.newInstance(bad);
+ badImportKeyDialogFragment.show(getSupportFragmentManager(), "badKeyDialog");
+ }
+ }
+ }
+ };
+
if (mListFragment.getKeyBytes() != null || mListFragment.getDataUri() != null) {
Log.d(Constants.TAG, "importKeys started");
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
index 1118f0264..a6917d6f4 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
@@ -219,27 +219,44 @@ public class ImportKeysListFragment extends ListFragment implements
} else {
setListShownNoAnimation(true);
}
+
+ Exception error = data.getError();
+
switch (loader.getId()) {
case LOADER_ID_BYTES:
+
+ if(error == null){
+ // No error
+ } else if(error instanceof ImportKeysListLoader.FileHasNoContent) {
+ AppMsg.makeText(getActivity(), R.string.error_import_file_no_content,
+ AppMsg.STYLE_ALERT).show();
+ } else if(error instanceof ImportKeysListLoader.NonPgpPart) {
+ AppMsg.makeText(getActivity(),
+ ((ImportKeysListLoader.NonPgpPart) error).getCount() + " " + getResources().
+ getQuantityString(R.plurals.error_import_non_pgp_part,
+ ((ImportKeysListLoader.NonPgpPart) error).getCount()),
+ new AppMsg.Style(AppMsg.LENGTH_LONG, R.color.confirm)).show();
+ } else {
+ AppMsg.makeText(getActivity(), R.string.error_generic_report_bug,
+ new AppMsg.Style(AppMsg.LENGTH_LONG, R.color.alert)).show();
+ }
break;
case LOADER_ID_SERVER_QUERY:
- Exception error = data.getError();
-
- if(error == null){
+ if(error == null) {
AppMsg.makeText(
getActivity(), getResources().getQuantityString(R.plurals.keys_found,
mAdapter.getCount(), mAdapter.getCount()),
AppMsg.STYLE_INFO
).show();
- } else if(error instanceof KeyServer.InsufficientQuery){
+ } else if(error instanceof KeyServer.InsufficientQuery) {
AppMsg.makeText(getActivity(), R.string.error_keyserver_insufficient_query,
AppMsg.STYLE_ALERT).show();
- }else if(error instanceof KeyServer.QueryException){
+ } else if(error instanceof KeyServer.QueryException) {
AppMsg.makeText(getActivity(), R.string.error_keyserver_query,
AppMsg.STYLE_ALERT).show();
- }else if(error instanceof KeyServer.TooManyResponses){
+ } else if(error instanceof KeyServer.TooManyResponses) {
AppMsg.makeText(getActivity(), R.string.error_keyserver_too_many_responses,
AppMsg.STYLE_ALERT).show();
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
index 0bbe2edb1..9eebbed64 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
@@ -59,8 +59,8 @@ public class KeyListActivity extends DrawerActivity {
return true;
case R.id.menu_key_list_export:
- mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.path.APP_DIR
- + "/pubexport.asc");
+ // TODO fix this for unified keylist
+ mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.path.APP_DIR_FILE_PUB);
return true;
default:
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 ea37677d1..c4a694bba 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
@@ -19,11 +19,14 @@ package org.sufficientlysecure.keychain.ui;
import java.util.HashMap;
import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
+import org.sufficientlysecure.keychain.helper.ExportHelper;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyTypes;
@@ -53,13 +56,21 @@ 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.support.v4.view.MenuItemCompat;
+import android.support.v7.app.ActionBarActivity;
+import android.support.v7.widget.SearchView;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
import android.widget.Button;
@@ -73,24 +84,37 @@ import com.beardedhen.androidbootstrap.BootstrapButton;
* Public key list with sticky list headers. It does _not_ extend ListFragment because it uses
* StickyListHeaders library which does not extend upon ListView.
*/
-public class KeyListFragment extends Fragment implements AdapterView.OnItemClickListener,
+public class KeyListFragment extends Fragment implements SearchView.OnQueryTextListener, AdapterView.OnItemClickListener,
LoaderManager.LoaderCallbacks<Cursor> {
private KeyListAdapter mAdapter;
private StickyListHeadersListView mStickyList;
+ // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
+ boolean mListShown;
+ View mProgressContainer;
+ View mListContainer;
+
+ private String mCurQuery;
+ private SearchView mSearchView;
// empty list layout
private BootstrapButton mButtonEmptyCreate;
private BootstrapButton mButtonEmptyImport;
+
/**
* Load custom layout with StickyListView from library
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.key_list_fragment, container, false);
+ View root = inflater.inflate(R.layout.key_list_fragment, container, false);
+
+ mStickyList = (StickyListHeadersListView) root.findViewById(R.id.key_list_list);
+ mStickyList.setOnItemClickListener(this);
- mButtonEmptyCreate = (BootstrapButton) view.findViewById(R.id.key_list_empty_button_create);
+
+ // empty view
+ mButtonEmptyCreate = (BootstrapButton) root.findViewById(R.id.key_list_empty_button_create);
mButtonEmptyCreate.setOnClickListener(new OnClickListener() {
@Override
@@ -102,8 +126,7 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
startActivityForResult(intent, 0);
}
});
-
- mButtonEmptyImport = (BootstrapButton) view.findViewById(R.id.key_list_empty_button_import);
+ mButtonEmptyImport = (BootstrapButton) root.findViewById(R.id.key_list_empty_button_import);
mButtonEmptyImport.setOnClickListener(new OnClickListener() {
@Override
@@ -114,7 +137,12 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
}
});
- return view;
+ // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
+ mListContainer = root.findViewById(R.id.key_list_list_container);
+ mProgressContainer = root.findViewById(R.id.key_list_progress_container);
+ mListShown = true;
+
+ return root;
}
/**
@@ -125,8 +153,6 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- mStickyList = (StickyListHeadersListView) getActivity().findViewById(R.id.list);
-
mStickyList.setOnItemClickListener(this);
mStickyList.setAreHeadersSticky(true);
mStickyList.setDrawingListUnderStickyHeader(false);
@@ -137,7 +163,7 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
}
// this view is made visible if no data is available
- mStickyList.setEmptyView(getActivity().findViewById(R.id.empty));
+ mStickyList.setEmptyView(getActivity().findViewById(R.id.key_list_empty));
/*
* ActionBarSherlock does not support MultiChoiceModeListener. Thus multi-selection is only
@@ -147,8 +173,6 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
mStickyList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mStickyList.getWrappedList().setMultiChoiceModeListener(new MultiChoiceModeListener() {
- private int count = 0;
-
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
android.view.MenuInflater inflater = getActivity().getMenuInflater();
@@ -174,7 +198,7 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
break;
}
case R.id.menu_key_list_multi_delete: {
- ids = mAdapter.getCurrentSelectedItemIds();
+ ids = mStickyList.getWrappedList().getCheckedItemIds();
showDeleteKeyDialog(mode, ids);
break;
}
@@ -184,7 +208,6 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
@Override
public void onDestroyActionMode(ActionMode mode) {
- count = 0;
mAdapter.clearSelection();
}
@@ -192,13 +215,11 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
boolean checked) {
if (checked) {
- count++;
mAdapter.setNewSelection(position, checked);
} else {
- count--;
mAdapter.removeSelection(position);
}
-
+ int count = mStickyList.getCheckedItemCount();
String keysSelected = getResources().getQuantityString(
R.plurals.key_list_selected_keys, count, count);
mode.setTitle(keysSelected);
@@ -207,9 +228,12 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
});
}
- // NOTE: Not supported by StickyListHeader, thus no indicator is shown while loading
+ // We have a menu item to show in action bar.
+ setHasOptionsMenu(true);
+
+ // NOTE: Not supported by StickyListHeader, but reimplemented here
// Start out with a progress indicator.
- // setListShown(false);
+ setListShown(false);
// Create an empty adapter we will use to display the loaded data.
mAdapter = new KeyListAdapter(getActivity(), null, Id.type.public_key);
@@ -238,27 +262,33 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
// 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.
Uri baseUri = KeyRings.buildUnifiedKeyRingsUri();
-
+ String where = null;
+ String whereArgs[] = null;
+ if (mCurQuery != null) {
+ where = KeychainContract.UserIds.USER_ID + " LIKE ?";
+ whereArgs = new String[]{"%" + mCurQuery + "%"};
+ }
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null, SORT_ORDER);
+ return new CursorLoader(getActivity(), baseUri, PROJECTION, where, whereArgs, SORT_ORDER);
}
@Override
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.setSearchQuery(mCurQuery);
mAdapter.swapCursor(data);
mStickyList.setAdapter(mAdapter);
- // NOTE: Not supported by StickyListHeader, thus no indicator is shown while loading
+ // NOTE: Not supported by StickyListHeader, but reimplemented here
// The list should now be shown.
- // if (isResumed()) {
- // setListShown(true);
- // } else {
- // setListShownNoAnimation(true);
- // }
+ if (isResumed()) {
+ setListShown(true);
+ } else {
+ setListShownNoAnimation(true);
+ }
}
@Override
@@ -338,6 +368,87 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog");
}
+
+ @Override
+ public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+ // Get the searchview
+ MenuItem searchItem = menu.findItem(R.id.menu_key_list_search);
+ mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
+
+ // Execute this when searching
+ mSearchView.setOnQueryTextListener(this);
+
+ // Erase search result without focus
+ MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
+ @Override
+ public boolean onMenuItemActionExpand(MenuItem item) {
+ return true;
+ }
+
+ @Override
+ public boolean onMenuItemActionCollapse(MenuItem item) {
+ mCurQuery = null;
+ mSearchView.setQuery("", true);
+ getLoaderManager().restartLoader(0, null, KeyListFragment.this);
+ return true;
+ }
+ });
+
+ super.onCreateOptionsMenu(menu, inflater);
+ }
+
+ @Override
+ public boolean onQueryTextSubmit(String s) {
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String s) {
+ // Called when the action bar search text has changed. Update
+ // the search filter, and restart the loader to do a new query
+ // with this filter.
+ mCurQuery = !TextUtils.isEmpty(s) ? s : null;
+ getLoaderManager().restartLoader(0, null, this);
+ return true;
+ }
+
+ // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
+ public void setListShown(boolean shown, boolean animate) {
+ if (mListShown == shown) {
+ return;
+ }
+ mListShown = shown;
+ if (shown) {
+ if (animate) {
+ mProgressContainer.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_out));
+ mListContainer.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_in));
+ }
+ mProgressContainer.setVisibility(View.GONE);
+ mListContainer.setVisibility(View.VISIBLE);
+ } else {
+ if (animate) {
+ mProgressContainer.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_in));
+ mListContainer.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_out));
+ }
+ mProgressContainer.setVisibility(View.VISIBLE);
+ mListContainer.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
+ public void setListShown(boolean shown) {
+ setListShown(shown, true);
+ }
+
+ // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
+ public void setListShownNoAnimation(boolean shown) {
+ setListShown(shown, false);
+ }
+
/**
* Implements StickyListHeadersAdapter from library
*/
@@ -347,6 +458,8 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
private int mIndexIsRevoked;
private int mMasterKeyId;
+ private String mCurQuery;
+
@SuppressLint("UseSparseArrays")
private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();
@@ -394,12 +507,12 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
String userId = cursor.getString(mIndexUserId);
String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
if (userIdSplit[0] != null) {
- mainUserId.setText(userIdSplit[0]);
+ mainUserId.setText(highlightSearchQuery(userIdSplit[0]));
} else {
mainUserId.setText(R.string.user_id_no_name);
}
if (userIdSplit[1] != null) {
- mainUserIdRest.setText(userIdSplit[1]);
+ mainUserIdRest.setText(highlightSearchQuery(userIdSplit[1]));
mainUserIdRest.setVisibility(View.VISIBLE);
} else {
mainUserIdRest.setVisibility(View.GONE);
@@ -558,20 +671,6 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
notifyDataSetChanged();
}
- public boolean isPositionChecked(int position) {
- Boolean result = mSelection.get(position);
- return result == null ? false : result;
- }
-
- public long[] getCurrentSelectedItemIds() {
- long[] ids = new long[mSelection.size()];
- int i = 0;
- // get master key ids
- for (int pos : mSelection.keySet())
- ids[i++] = mAdapter.getItemId(pos);
- return ids;
- }
-
public long[] getCurrentSelectedMasterKeyIds() {
long[] ids = new long[mSelection.size()];
int i = 0;
@@ -608,6 +707,34 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
return v;
}
+ // search highlight methods
+
+ public void setSearchQuery(String searchQuery) {
+ mCurQuery = searchQuery;
+ }
+
+ public String getSearchQuery() {
+ return mCurQuery;
+ }
+
+ protected Spannable highlightSearchQuery(String text) {
+ Spannable highlight = Spannable.Factory.getInstance().newSpannable(text);
+
+ if (mCurQuery != null) {
+ Pattern pattern = Pattern.compile("(?i)" + mCurQuery);
+ Matcher matcher = pattern.matcher(text);
+ if (matcher.find()) {
+ highlight.setSpan(
+ new ForegroundColorSpan(mContext.getResources().getColor(R.color.emphasis)),
+ matcher.start(),
+ matcher.end(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ return highlight;
+ } else {
+ return highlight;
+ }
+ }
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
index b38beebd1..2e8f25890 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
@@ -24,24 +24,27 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference;
+import android.annotation.SuppressLint;
import android.content.Intent;
+import android.os.Build;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.support.v7.app.ActionBarActivity;
+import java.util.List;
+
+@SuppressLint("NewApi")
public class PreferencesActivity extends PreferenceActivity {
- private IntegerListPreference mPassPhraseCacheTtl = null;
- private IntegerListPreference mEncryptionAlgorithm = null;
- private IntegerListPreference mHashAlgorithm = null;
- private IntegerListPreference mMessageCompression = null;
- private IntegerListPreference mFileCompression = null;
- private CheckBoxPreference mAsciiArmour = null;
- private CheckBoxPreference mForceV3Signatures = null;
+
+ public final static String ACTION_PREFS_GEN = "org.sufficientlysecure.keychain.ui.PREFS_GEN";
+ public final static String ACTION_PREFS_ADV = "org.sufficientlysecure.keychain.ui.PREFS_ADV";
+
private PreferenceScreen mKeyServerPreference = null;
- private Preferences mPreferences;
+ private static Preferences mPreferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -53,22 +56,218 @@ public class PreferencesActivity extends PreferenceActivity {
// actionBar.setDisplayHomeAsUpEnabled(false);
// actionBar.setHomeButtonEnabled(false);
- addPreferencesFromResource(R.xml.preferences);
+ String action = getIntent().getAction();
+
+ if (action != null && action.equals(ACTION_PREFS_GEN)) {
+ addPreferencesFromResource(R.xml.gen_preferences);
+
+ initializePassPassPhraceCacheTtl(
+ (IntegerListPreference) findPreference(Constants.pref.PASS_PHRASE_CACHE_TTL));
+
+ mKeyServerPreference = (PreferenceScreen) findPreference(Constants.pref.KEY_SERVERS);
+ String servers[] = mPreferences.getKeyServers();
+ mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
+ servers.length, servers.length));
+ mKeyServerPreference
+ .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ Intent intent = new Intent(PreferencesActivity.this,
+ PreferencesKeyServerActivity.class);
+ intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
+ mPreferences.getKeyServers());
+ startActivityForResult(intent, Id.request.key_server_preference);
+ return false;
+ }
+ });
+
+ } else if (action != null && action.equals(ACTION_PREFS_ADV)) {
+ addPreferencesFromResource(R.xml.adv_preferences);
+
+ initializeEncryptionAlgorithm(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM));
+
+ int[] valueIds = new int[] { Id.choice.compression.none, Id.choice.compression.zip,
+ Id.choice.compression.zlib, Id.choice.compression.bzip2, };
+ String[] entries = new String[] {
+ getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
+ "ZIP (" + getString(R.string.compression_fast) + ")",
+ "ZLIB (" + getString(R.string.compression_fast) + ")",
+ "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
+ String[] values = new String[valueIds.length];
+ for (int i = 0; i < values.length; ++i) {
+ values[i] = "" + valueIds[i];
+ }
+
+ initializeHashAlgorithm(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_HASH_ALGORITHM),
+ valueIds, entries, values);
+
+ initializeMessageCompression(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_MESSAGE_COMPRESSION),
+ valueIds, entries, values);
+
+ initializeFileCompression(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_FILE_COMPRESSION),
+ entries, values);
+
+ initializeAsciiArmour((CheckBoxPreference) findPreference(Constants.pref.DEFAULT_ASCII_ARMOUR));
+
+ initializeForceV3Signatures((CheckBoxPreference) findPreference(Constants.pref.FORCE_V3_SIGNATURES));
+
+ } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
+ // Load the legacy preferences headers
+ addPreferencesFromResource(R.xml.preference_headers_legacy);
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case Id.request.key_server_preference: {
+ if (resultCode == RESULT_CANCELED || data == null) {
+ return;
+ }
+ String servers[] = data
+ .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
+ mPreferences.setKeyServers(servers);
+ mKeyServerPreference.setSummary(getResources().getQuantityString(
+ R.plurals.n_key_servers, servers.length, servers.length));
+ break;
+ }
+
+ default: {
+ super.onActivityResult(requestCode, resultCode, data);
+ break;
+ }
+ }
+ }
+
+ /* Called only on Honeycomb and later */
+ @Override
+ public void onBuildHeaders(List<Header> target) {
+ super.onBuildHeaders(target);
+ loadHeadersFromResource(R.xml.preference_headers, target);
+ }
+
+ /** This fragment shows the general preferences in android 3.0+ */
+ public static class GeneralPrefsFragment extends PreferenceFragment {
+
+ private PreferenceScreen mKeyServerPreference = null;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.gen_preferences);
+
+ initializePassPassPhraceCacheTtl(
+ (IntegerListPreference) findPreference(Constants.pref.PASS_PHRASE_CACHE_TTL));
+
+ mKeyServerPreference = (PreferenceScreen) findPreference(Constants.pref.KEY_SERVERS);
+ String servers[] = mPreferences.getKeyServers();
+ mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
+ servers.length, servers.length));
+ mKeyServerPreference
+ .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ Intent intent = new Intent(getActivity(),
+ PreferencesKeyServerActivity.class);
+ intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
+ mPreferences.getKeyServers());
+ startActivityForResult(intent, Id.request.key_server_preference);
+ return false;
+ }
+ });
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case Id.request.key_server_preference: {
+ if (resultCode == RESULT_CANCELED || data == null) {
+ return;
+ }
+ String servers[] = data
+ .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
+ mPreferences.setKeyServers(servers);
+ mKeyServerPreference.setSummary(getResources().getQuantityString(
+ R.plurals.n_key_servers, servers.length, servers.length));
+ break;
+ }
+
+ default: {
+ super.onActivityResult(requestCode, resultCode, data);
+ break;
+ }
+ }
+ }
+ }
+
+ /** This fragment shows the advanced preferences in android 3.0+ */
+ public static class AdvancedPrefsFragment extends PreferenceFragment {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.adv_preferences);
+
+ initializeEncryptionAlgorithm(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM));
+
+ int[] valueIds = new int[] { Id.choice.compression.none, Id.choice.compression.zip,
+ Id.choice.compression.zlib, Id.choice.compression.bzip2, };
+ String[] entries = new String[] {
+ getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
+ "ZIP (" + getString(R.string.compression_fast) + ")",
+ "ZLIB (" + getString(R.string.compression_fast) + ")",
+ "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
+ String[] values = new String[valueIds.length];
+ for (int i = 0; i < values.length; ++i) {
+ values[i] = "" + valueIds[i];
+ }
+
+ initializeHashAlgorithm(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_HASH_ALGORITHM),
+ valueIds, entries, values);
+
+ initializeMessageCompression(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_MESSAGE_COMPRESSION),
+ valueIds, entries, values);
+
+ initializeFileCompression(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_FILE_COMPRESSION),
+ entries, values);
- mPassPhraseCacheTtl = (IntegerListPreference) findPreference(Constants.pref.PASS_PHRASE_CACHE_TTL);
- mPassPhraseCacheTtl.setValue("" + mPreferences.getPassPhraseCacheTtl());
- mPassPhraseCacheTtl.setSummary(mPassPhraseCacheTtl.getEntry());
- mPassPhraseCacheTtl
+ initializeAsciiArmour((CheckBoxPreference) findPreference(Constants.pref.DEFAULT_ASCII_ARMOUR));
+
+ initializeForceV3Signatures((CheckBoxPreference) findPreference(Constants.pref.FORCE_V3_SIGNATURES));
+ }
+ }
+
+ protected boolean isValidFragment (String fragmentName) {
+ return AdvancedPrefsFragment.class.getName().equals(fragmentName)
+ || GeneralPrefsFragment.class.getName().equals(fragmentName)
+ || super.isValidFragment(fragmentName);
+ }
+
+ private static void initializePassPassPhraceCacheTtl(final IntegerListPreference mPassphraseCacheTtl) {
+ mPassphraseCacheTtl.setValue("" + mPreferences.getPassPhraseCacheTtl());
+ mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
+ mPassphraseCacheTtl
.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
- mPassPhraseCacheTtl.setValue(newValue.toString());
- mPassPhraseCacheTtl.setSummary(mPassPhraseCacheTtl.getEntry());
+ mPassphraseCacheTtl.setValue(newValue.toString());
+ mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
mPreferences.setPassPhraseCacheTtl(Integer.parseInt(newValue.toString()));
return false;
}
});
+ }
- mEncryptionAlgorithm = (IntegerListPreference) findPreference(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM);
+ private static void initializeEncryptionAlgorithm(final IntegerListPreference mEncryptionAlgorithm) {
int valueIds[] = { PGPEncryptedData.AES_128, PGPEncryptedData.AES_192,
PGPEncryptedData.AES_256, PGPEncryptedData.BLOWFISH, PGPEncryptedData.TWOFISH,
PGPEncryptedData.CAST5, PGPEncryptedData.DES, PGPEncryptedData.TRIPLE_DES,
@@ -93,8 +292,10 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mHashAlgorithm = (IntegerListPreference) findPreference(Constants.pref.DEFAULT_HASH_ALGORITHM);
+ private static void initializeHashAlgorithm
+ (final IntegerListPreference mHashAlgorithm, int[] valueIds, String[] entries, String[] values) {
valueIds = new int[] { HashAlgorithmTags.MD5, HashAlgorithmTags.RIPEMD160,
HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA224, HashAlgorithmTags.SHA256,
HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512, };
@@ -116,19 +317,10 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mMessageCompression = (IntegerListPreference) findPreference(Constants.pref.DEFAULT_MESSAGE_COMPRESSION);
- valueIds = new int[] { Id.choice.compression.none, Id.choice.compression.zip,
- Id.choice.compression.zlib, Id.choice.compression.bzip2, };
- entries = new String[] {
- getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
- "ZIP (" + getString(R.string.compression_fast) + ")",
- "ZLIB (" + getString(R.string.compression_fast) + ")",
- "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
- values = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
+ private static void initializeMessageCompression
+ (final IntegerListPreference mMessageCompression, int[] valueIds, String[] entries, String[] values) {
mMessageCompression.setEntries(entries);
mMessageCompression.setEntryValues(values);
mMessageCompression.setValue("" + mPreferences.getDefaultMessageCompression());
@@ -143,8 +335,10 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mFileCompression = (IntegerListPreference) findPreference(Constants.pref.DEFAULT_FILE_COMPRESSION);
+ private static void initializeFileCompression
+ (final IntegerListPreference mFileCompression, String[] entries, String[] values) {
mFileCompression.setEntries(entries);
mFileCompression.setEntryValues(values);
mFileCompression.setValue("" + mPreferences.getDefaultFileCompression());
@@ -157,8 +351,9 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mAsciiArmour = (CheckBoxPreference) findPreference(Constants.pref.DEFAULT_ASCII_ARMOUR);
+ private static void initializeAsciiArmour(final CheckBoxPreference mAsciiArmour) {
mAsciiArmour.setChecked(mPreferences.getDefaultAsciiArmour());
mAsciiArmour.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
@@ -167,8 +362,9 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mForceV3Signatures = (CheckBoxPreference) findPreference(Constants.pref.FORCE_V3_SIGNATURES);
+ private static void initializeForceV3Signatures(final CheckBoxPreference mForceV3Signatures) {
mForceV3Signatures.setChecked(mPreferences.getForceV3Signatures());
mForceV3Signatures
.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@@ -178,43 +374,5 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
-
- mKeyServerPreference = (PreferenceScreen) findPreference(Constants.pref.KEY_SERVERS);
- String servers[] = mPreferences.getKeyServers();
- mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
- servers.length, servers.length));
- mKeyServerPreference
- .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- public boolean onPreferenceClick(Preference preference) {
- Intent intent = new Intent(PreferencesActivity.this,
- PreferencesKeyServerActivity.class);
- intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
- mPreferences.getKeyServers());
- startActivityForResult(intent, Id.request.key_server_preference);
- return false;
- }
- });
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case Id.request.key_server_preference: {
- if (resultCode == RESULT_CANCELED || data == null) {
- return;
- }
- String servers[] = data
- .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
- mPreferences.setKeyServers(servers);
- mKeyServerPreference.setSummary(getResources().getQuantityString(
- R.plurals.n_key_servers, servers.length, servers.length));
- break;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
- break;
- }
- }
}
-}
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java
index b5ac739ae..50fec1ffc 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java
@@ -50,14 +50,14 @@ public class PreferencesKeyServerActivity extends ActionBarActivity implements O
super.onCreate(savedInstanceState);
// Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_okay,
+ ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done,
new View.OnClickListener() {
@Override
public void onClick(View v) {
// ok
okClicked();
}
- }, R.string.btn_do_not_save, new View.OnClickListener() {
+ }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
// cancel
@@ -81,11 +81,11 @@ public class PreferencesKeyServerActivity extends ActionBarActivity implements O
Intent intent = getIntent();
String servers[] = intent.getStringArrayExtra(EXTRA_KEY_SERVERS);
if (servers != null) {
- for (int i = 0; i < servers.length; ++i) {
+ for (String serv : servers) {
KeyServerEditor view = (KeyServerEditor) mInflater.inflate(
R.layout.key_server_editor, mEditors, false);
view.setEditorListener(this);
- view.setValue(servers[i]);
+ view.setValue(serv);
mEditors.addView(view);
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java
index 86ae0073f..3c63628f7 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java
@@ -46,14 +46,14 @@ public class SelectPublicKeyActivity extends ActionBarActivity {
super.onCreate(savedInstanceState);
// Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_okay,
+ ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done,
new View.OnClickListener() {
@Override
public void onClick(View v) {
// ok
okClicked();
}
- }, R.string.btn_do_not_save, new View.OnClickListener() {
+ }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
// cancel
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
index 59b46dd00..d320af451 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
@@ -30,7 +30,7 @@ import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter;
-import android.app.Activity;
+import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
@@ -38,17 +38,35 @@ import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
import android.widget.ListView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
-public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
+public class SelectPublicKeyFragment extends ListFragmentWorkaround implements TextWatcher,
LoaderManager.LoaderCallbacks<Cursor> {
public static final String ARG_PRESELECTED_KEY_IDS = "preselected_key_ids";
- private Activity mActivity;
private SelectKeyCursorAdapter mAdapter;
- private ListView mListView;
-
+ private EditText mSearchView;
private long mSelectedMasterKeyIds[];
+ private String mCurQuery;
+
+ // copied from ListFragment
+ static final int INTERNAL_EMPTY_ID = 0x00ff0001;
+ static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002;
+ static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003;
+ // added for search view
+ static final int SEARCH_ID = 0x00ff0004;
/**
* Creates new instance of this fragment
@@ -67,27 +85,100 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
mSelectedMasterKeyIds = getArguments().getLongArray(ARG_PRESELECTED_KEY_IDS);
}
/**
+ * Copied from ListFragment and added EditText for search on top of list.
+ * We do not use a custom layout here, because this breaks the progress bar functionality
+ * of ListFragment.
+ *
+ * @param inflater
+ * @param container
+ * @param savedInstanceState
+ * @return
+ */
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final Context context = getActivity();
+
+ FrameLayout root = new FrameLayout(context);
+
+ // ------------------------------------------------------------------
+
+ LinearLayout pframe = new LinearLayout(context);
+ pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);
+ pframe.setOrientation(LinearLayout.VERTICAL);
+ pframe.setVisibility(View.GONE);
+ pframe.setGravity(Gravity.CENTER);
+
+ ProgressBar progress = new ProgressBar(context, null,
+ android.R.attr.progressBarStyleLarge);
+ pframe.addView(progress, new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+
+ root.addView(pframe, new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+
+ // ------------------------------------------------------------------
+
+ FrameLayout lframe = new FrameLayout(context);
+ lframe.setId(INTERNAL_LIST_CONTAINER_ID);
+
+ TextView tv = new TextView(getActivity());
+ tv.setId(INTERNAL_EMPTY_ID);
+ tv.setGravity(Gravity.CENTER);
+ lframe.addView(tv, new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+
+ // Added for search view: linearLayout, mSearchView
+ LinearLayout linearLayout = new LinearLayout(context);
+ linearLayout.setOrientation(LinearLayout.VERTICAL);
+
+ mSearchView = new EditText(context);
+ mSearchView.setId(SEARCH_ID);
+ mSearchView.setHint(R.string.menu_search);
+ mSearchView.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_action_search), null, null, null);
+
+ linearLayout.addView(mSearchView, new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+
+ ListView lv = new ListView(getActivity());
+ lv.setId(android.R.id.list);
+ lv.setDrawSelectorOnTop(false);
+ linearLayout.addView(lv, new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+
+ lframe.addView(linearLayout, new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+
+ root.addView(lframe, new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+
+ // ------------------------------------------------------------------
+
+ root.setLayoutParams(new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+
+ return root;
+ }
+
+ /**
* Define Adapter and Loader on create of Activity
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- mActivity = getActivity();
- mListView = getListView();
-
- mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+ getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
// Give some text to display if there is no data. In a real
// application this would come from a resource.
setEmptyText(getString(R.string.list_empty));
- mAdapter = new SelectKeyCursorAdapter(mActivity, null, 0, mListView, Id.type.public_key);
+ mSearchView.addTextChangedListener(this);
+
+ mAdapter = new SelectKeyCursorAdapter(getActivity(), null, 0, getListView(), Id.type.public_key);
setListAdapter(mAdapter);
@@ -101,16 +192,16 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
/**
* Selects items based on master key ids in list view
- *
+ *
* @param masterKeyIds
*/
private void preselectMasterKeyIds(long[] masterKeyIds) {
if (masterKeyIds != null) {
- for (int i = 0; i < mListView.getCount(); ++i) {
+ for (int i = 0; i < getListView().getCount(); ++i) {
long keyId = mAdapter.getMasterKeyId(i);
- for (int j = 0; j < masterKeyIds.length; ++j) {
- if (keyId == masterKeyIds[j]) {
- mListView.setItemChecked(i, true);
+ for (long masterKeyId : masterKeyIds) {
+ if (keyId == masterKeyId) {
+ getListView().setItemChecked(i, true);
break;
}
}
@@ -120,15 +211,15 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
/**
* Returns all selected master key ids
- *
+ *
* @return
*/
public long[] getSelectedMasterKeyIds() {
// mListView.getCheckedItemIds() would give the row ids of the KeyRings not the master key
// ids!
Vector<Long> vector = new Vector<Long>();
- for (int i = 0; i < mListView.getCount(); ++i) {
- if (mListView.isItemChecked(i)) {
+ for (int i = 0; i < getListView().getCount(); ++i) {
+ if (getListView().isItemChecked(i)) {
vector.add(mAdapter.getMasterKeyId(i));
}
}
@@ -144,13 +235,13 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
/**
* Returns all selected user ids
- *
+ *
* @return
*/
public String[] getSelectedUserIds() {
Vector<String> userIds = new Vector<String>();
- for (int i = 0; i < mListView.getCount(); ++i) {
- if (mListView.isItemChecked(i)) {
+ for (int i = 0; i < getListView().getCount(); ++i) {
+ if (getListView().isItemChecked(i)) {
userIds.add((String) mAdapter.getUserId(i));
}
}
@@ -168,7 +259,7 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
// These are the rows that we will retrieve.
long now = new Date().getTime() / 1000;
- String[] projection = new String[] {
+ String[] projection = new String[]{
KeyRings._ID,
KeyRings.MASTER_KEY_ID,
UserIds.USER_ID,
@@ -185,7 +276,7 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
+ Keys.CAN_ENCRYPT + " = '1' AND valid_keys." + Keys.CREATION + " <= '"
+ now + "' AND " + "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys."
+ Keys.EXPIRY + " >= '" + now + "')) AS "
- + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, };
+ + SelectKeyCursorAdapter.PROJECTION_ROW_VALID,};
String inMasterKeyList = null;
if (mSelectedMasterKeyIds != null && mSelectedMasterKeyIds.length > 0) {
@@ -199,37 +290,28 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
inMasterKeyList += ")";
}
- // if (searchString != null && searchString.trim().length() > 0) {
- // String[] chunks = searchString.trim().split(" +");
- // qb.appendWhere("(EXISTS (SELECT tmp." + UserIds._ID + " FROM " + UserIds.TABLE_NAME
- // + " AS tmp WHERE " + "tmp." + UserIds.KEY_ID + " = " + Keys.TABLE_NAME + "."
- // + Keys._ID);
- // for (int i = 0; i < chunks.length; ++i) {
- // qb.appendWhere(" AND tmp." + UserIds.USER_ID + " LIKE ");
- // qb.appendWhereEscapeString("%" + chunks[i] + "%");
- // }
- // qb.appendWhere("))");
- //
- // if (inIdList != null) {
- // qb.appendWhere(" OR (" + inIdList + ")");
- // }
- // }
-
String orderBy = UserIds.USER_ID + " ASC";
if (inMasterKeyList != null) {
// sort by selected master keys
orderBy = inMasterKeyList + " DESC, " + orderBy;
}
+ String where = null;
+ String whereArgs[] = null;
+ if (mCurQuery != null) {
+ where = UserIds.USER_ID + " LIKE ?";
+ whereArgs = new String[]{"%" + mCurQuery + "%"};
+ }
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), baseUri, projection, null, null, orderBy);
+ return new CursorLoader(getActivity(), baseUri, projection, where, whereArgs, orderBy);
}
@Override
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.setSearchQuery(mCurQuery);
mAdapter.swapCursor(data);
// The list should now be shown.
@@ -250,4 +332,20 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
// longer using it.
mAdapter.swapCursor(null);
}
+
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+ mCurQuery = !TextUtils.isEmpty(editable.toString()) ? editable.toString() : null;
+ getLoaderManager().restartLoader(0, null, this);
+ }
}
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 6bcb84f46..c9129285e 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
@@ -24,10 +24,13 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import android.Manifest;
import android.app.Activity;
+import android.app.ActivityOptions;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -40,6 +43,7 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
private TextView mKeyUserId;
private TextView mKeyUserIdRest;
+ private TextView mKeyMasterKeyIdHex;
private BootstrapButton mSelectKeyButton;
private Boolean mFilterCertify;
@@ -61,26 +65,52 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
public void selectKey(long secretKeyId) {
if (secretKeyId == Id.key.none) {
- mKeyUserId.setText(R.string.api_settings_no_key);
+ mKeyMasterKeyIdHex.setText(R.string.api_settings_no_key);
mKeyUserIdRest.setText("");
+ mKeyUserId.setVisibility(View.GONE);
+ mKeyUserIdRest.setVisibility(View.GONE);
+
} else {
- String uid = getResources().getString(R.string.user_id_no_name);
- String uidExtra = "";
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(
getActivity(), secretKeyId);
if (keyRing != null) {
PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing);
+ String masterkeyIdHex = PgpKeyHelper.convertKeyIdToHex(secretKeyId);
+
if (key != null) {
String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key);
- String chunks[] = userId.split(" <", 2);
- uid = chunks[0];
- if (chunks.length > 1) {
- uidExtra = "<" + chunks[1];
+
+ 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);
+ mKeyUserId.setVisibility(View.VISIBLE);
+ mKeyUserIdRest.setVisibility(View.VISIBLE);
+ } else {
+ mKeyMasterKeyIdHex.setText(getActivity().getResources().getString(R.string.no_key));
+ mKeyUserId.setVisibility(View.GONE);
+ mKeyUserIdRest.setVisibility(View.GONE);
}
+ } else {
+ mKeyMasterKeyIdHex.setText(getActivity().getResources().getString(R.string.no_keys_added_or_updated) + " for master id: " + secretKeyId);
+ mKeyUserId.setVisibility(View.GONE);
+ mKeyUserIdRest.setVisibility(View.GONE);
}
- mKeyUserId.setText(uid);
- mKeyUserIdRest.setText(uidExtra);
+
}
}
@@ -98,6 +128,7 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
mKeyUserId = (TextView) view.findViewById(R.id.select_secret_key_user_id);
mKeyUserIdRest = (TextView) view.findViewById(R.id.select_secret_key_user_id_rest);
+ mKeyMasterKeyIdHex = (TextView) view.findViewById(R.id.select_secret_key_master_key_hex);
mSelectKeyButton = (BootstrapButton) view
.findViewById(R.id.select_secret_key_select_key_button);
mFilterCertify = false;
@@ -117,30 +148,31 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
startActivityForResult(intent, REQUEST_CODE_SELECT_KEY);
}
+ // 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.
@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);
-
- // remove displayed errors
- mKeyUserId.setError(null);
-
- // give value back to callback
- mCallback.onKeySelected(secretKeyId);
+ 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);
+
+ // remove displayed errors
+ mKeyUserId.setError(null);
+
+ // give value back to callback
+ mCallback.onKeySelected(secretKeyId);
+ }
+ break;
}
- break;
- }
- default:
- super.onActivityResult(requestCode, resultCode, data);
+ default:
+ super.onActivityResult(requestCode, resultCode, data);
- break;
+ 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 550d3047d..6f0aaa0f0 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
@@ -102,7 +102,7 @@ public class UploadKeyActivity extends ActionBarActivity {
// Message is received after uploading is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_exporting, ProgressDialog.STYLE_HORIZONTAL) {
+ getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -113,7 +113,7 @@ public class UploadKeyActivity extends ActionBarActivity {
Toast.LENGTH_SHORT).show();
finish();
}
- };
+ }
};
// Create a new Messenger for the communication back
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 055203c0f..01a2740b1 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
@@ -93,12 +93,12 @@ public class ViewKeyActivity extends ActionBarActivity {
Bundle mainBundle = new Bundle();
mainBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, mDataUri);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_main)),
- ViewKeyMainFragment.class, mainBundle, (selectedTab == 0 ? true : false));
+ ViewKeyMainFragment.class, mainBundle, (selectedTab == 0));
Bundle certBundle = new Bundle();
certBundle.putLong(ViewKeyCertsFragment.ARG_KEYRING_ROW_ID, rowId);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_certs)),
- ViewKeyCertsFragment.class, certBundle, (selectedTab == 1 ? true : false));
+ ViewKeyCertsFragment.class, certBundle, (selectedTab == 1));
}
@Override
@@ -123,8 +123,8 @@ public class ViewKeyActivity extends ActionBarActivity {
uploadToKeyserver(mDataUri);
return true;
case R.id.menu_key_view_export_file:
- mExportHelper.showExportKeysDialog(mDataUri, Id.type.public_key, Constants.path.APP_DIR
- + "/pubexport.asc");
+ long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())};
+ mExportHelper.showExportKeysDialog(ids, Id.type.public_key, Constants.path.APP_DIR_FILE_PUB);
return true;
case R.id.menu_key_view_share_default_fingerprint:
shareKey(mDataUri, true);
@@ -159,7 +159,7 @@ public class ViewKeyActivity extends ActionBarActivity {
}
private void updateFromKeyserver(Uri dataUri) {
- long updateKeyId = ProviderHelper.getMasterKeyId(ViewKeyActivity.this, mDataUri);
+ long updateKeyId = ProviderHelper.getMasterKeyId(ViewKeyActivity.this, dataUri);
if (updateKeyId == 0) {
Log.e(Constants.TAG, "this shouldn't happen. KeyId == 0!");
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 00ca0d1f4..c898a06ea 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
@@ -26,7 +26,10 @@ 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.text.Spannable;
+import android.text.SpannableStringBuilder;
import android.text.format.DateFormat;
+import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -273,7 +276,7 @@ public class ViewKeyMainFragment extends Fragment implements
// get key id from MASTER_KEY_ID
long keyId = data.getLong(KEYS_INDEX_KEY_ID);
- String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
+ String keyIdStr = PgpKeyHelper.convertKeyIdToHex(keyId);
mKeyId.setText(keyIdStr);
// get creation date from CREATION
@@ -306,9 +309,8 @@ public class ViewKeyMainFragment extends Fragment implements
fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), mDataUri);
}
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
- fingerprint = fingerprint.replace(" ", "\n");
- mFingerprint.setText(fingerprint);
+ mFingerprint.setText(colorizeFingerprint(fingerprint));
}
mKeysAdapter.swapCursor(data);
@@ -319,6 +321,25 @@ public class ViewKeyMainFragment extends Fragment implements
}
}
+ private SpannableStringBuilder colorizeFingerprint(String fingerprint) {
+ SpannableStringBuilder sb = new SpannableStringBuilder(fingerprint);
+ ForegroundColorSpan fcs = new ForegroundColorSpan(Color.BLACK);
+
+ // for each 4 characters of the fingerprint + 1 space
+ for (int i = 0; i < fingerprint.length(); i += 5) {
+ int minFingLength = Math.min(i + 4, fingerprint.length());
+ String fourChars = fingerprint.substring(i, minFingLength);
+
+ // Create a foreground color by converting the 4 fingerprint chars to an int hashcode
+ // and then converting that int to hex to use as a color
+ fcs = new ForegroundColorSpan(
+ Color.parseColor(String.format("#%06X", (0xFFFFFF & fourChars.hashCode()))));
+ sb.setSpan(fcs, i, minFingLength, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+ }
+
+ return sb;
+ }
+
/**
* 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.
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/HighlightQueryCursorAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/HighlightQueryCursorAdapter.java
new file mode 100644
index 000000000..fd7a2dc30
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/HighlightQueryCursorAdapter.java
@@ -0,0 +1,66 @@
+/*
+ * 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.adapter;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.support.v4.widget.CursorAdapter;
+import android.text.Spannable;
+import android.text.style.ForegroundColorSpan;
+
+import org.sufficientlysecure.keychain.R;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public abstract class HighlightQueryCursorAdapter extends CursorAdapter {
+
+ private String mCurQuery;
+
+ public HighlightQueryCursorAdapter(Context context, Cursor c, int flags) {
+ super(context, c, flags);
+ mCurQuery = null;
+ }
+
+ public void setSearchQuery(String searchQuery) {
+ mCurQuery = searchQuery;
+ }
+
+ public String getSearchQuery() {
+ return mCurQuery;
+ }
+
+ protected Spannable highlightSearchQuery(String text) {
+ Spannable highlight = Spannable.Factory.getInstance().newSpannable(text);
+
+ if (mCurQuery != null) {
+ Pattern pattern = Pattern.compile("(?i)" + mCurQuery);
+ Matcher matcher = pattern.matcher(text);
+ if (matcher.find()) {
+ highlight.setSpan(
+ new ForegroundColorSpan(mContext.getResources().getColor(R.color.emphasis)),
+ matcher.start(),
+ matcher.end(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ return highlight;
+ } else {
+ return highlight;
+ }
+ }
+}
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 52186b662..4f7623bce 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
@@ -42,7 +42,15 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
protected Activity mActivity;
protected List<ImportKeysListEntry> data;
+ static class ViewHolder{
+ private TextView mainUserId;
+ private TextView mainUserIdRest;
+ private TextView keyId;
+ private TextView fingerprint;
+ private TextView algorithm;
+ private TextView status;
+ }
public ImportKeysAdapter(Activity activity) {
super(activity, -1);
mActivity = activity;
@@ -86,16 +94,21 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
public View getView(int position, View convertView, ViewGroup parent) {
ImportKeysListEntry entry = data.get(position);
-
- View view = mInflater.inflate(R.layout.import_keys_list_entry, null);
-
- TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId);
- TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
- TextView keyId = (TextView) view.findViewById(R.id.keyId);
- TextView fingerprint = (TextView) view.findViewById(R.id.fingerprint);
- TextView algorithm = (TextView) view.findViewById(R.id.algorithm);
- TextView status = (TextView) view.findViewById(R.id.status);
-
+ ViewHolder holder;
+ if(convertView == null) {
+ holder = new ViewHolder();
+ convertView = mInflater.inflate(R.layout.import_keys_list_entry, null);
+ 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();
+ }
// main user id
String userId = entry.userIds.get(0);
String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
@@ -105,39 +118,39 @@ 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];
- mainUserId.setTextColor(Color.RED);
+ holder.mainUserId.setTextColor(Color.RED);
}
- mainUserId.setText(userIdSplit[0]);
+ holder.mainUserId.setText(userIdSplit[0]);
} else {
- mainUserId.setText(R.string.user_id_no_name);
+ holder.mainUserId.setText(R.string.user_id_no_name);
}
// email
if (userIdSplit[1] != null) {
- mainUserIdRest.setText(userIdSplit[1]);
- mainUserIdRest.setVisibility(View.VISIBLE);
+ holder.mainUserIdRest.setText(userIdSplit[1]);
+ holder.mainUserIdRest.setVisibility(View.VISIBLE);
} else {
- mainUserIdRest.setVisibility(View.GONE);
+ holder.mainUserIdRest.setVisibility(View.GONE);
}
- keyId.setText(entry.hexKeyId);
+ holder.keyId.setText(entry.hexKeyId);
if (entry.fingerPrint != null) {
- fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint);
- fingerprint.setVisibility(View.VISIBLE);
+ holder.fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint);
+ holder.fingerprint.setVisibility(View.VISIBLE);
} else {
- fingerprint.setVisibility(View.GONE);
+ holder.fingerprint.setVisibility(View.GONE);
}
- algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm);
+ holder.algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm);
if (entry.revoked) {
- status.setText(R.string.revoked);
+ holder.status.setText(R.string.revoked);
} else {
- status.setVisibility(View.GONE);
+ holder.status.setVisibility(View.GONE);
}
- LinearLayout ll = (LinearLayout) view.findViewById(R.id.list);
+ LinearLayout ll = (LinearLayout) convertView.findViewById(R.id.list);
if (entry.userIds.size() == 1) {
ll.setVisibility(View.GONE);
} else {
@@ -162,10 +175,10 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
}
}
- CheckBox cBox = (CheckBox) view.findViewById(R.id.selected);
+ CheckBox cBox = (CheckBox) convertView.findViewById(R.id.selected);
cBox.setChecked(entry.isSelected());
- return view;
+ return convertView;
}
}
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 4a7a9c93a..a52e9b447 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
@@ -125,7 +125,10 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
* Constructor for later querying from keyserver
*/
public ImportKeysListEntry() {
+ // keys from keyserver are always public keys
secretKey = false;
+ // do not select by default
+ selected = false;
userIds = new ArrayList<String>();
}
@@ -167,7 +170,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
this.revoked = pgpKeyRing.getPublicKey().isRevoked();
this.fingerPrint = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey()
.getFingerprint(), true);
- this.hexKeyId = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
+ this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId);
this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength();
int algorithm = pgpKeyRing.getPublicKey().getAlgorithm();
if (algorithm == PGPPublicKey.RSA_ENCRYPT || algorithm == PGPPublicKey.RSA_GENERAL
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
index 29e418db7..3eca99f15 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
@@ -20,7 +20,6 @@ package org.sufficientlysecure.keychain.ui.adapter;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.List;
import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPObjectFactory;
@@ -34,6 +33,21 @@ import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> {
+
+ public static class FileHasNoContent extends Exception {
+
+ }
+
+ public static class NonPgpPart extends Exception {
+ private int count;
+ public NonPgpPart(int count) {
+ this.count = count;
+ }
+ public int getCount() {
+ return count;
+ }
+ }
+
Context mContext;
InputData mInputData;
@@ -88,21 +102,26 @@ public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper
/**
* Reads all PGPKeyRing objects from input
*
- * @param keyringBytes
+ * @param inputData
* @return
*/
private void generateListOfKeyrings(InputData inputData) {
+
+ boolean isEmpty = true;
+ int nonPgpCounter = 0;
+
PositionAwareInputStream progressIn = new PositionAwareInputStream(
inputData.getInputStream());
// 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
- // armour blocks
+ // armor blocks
BufferedInputStream bufferedInput = new BufferedInputStream(progressIn);
try {
// read all available blocks... (asc files can contain many blocks with BEGIN END)
while (bufferedInput.available() > 0) {
+ isEmpty = false;
InputStream in = PGPUtil.getDecoderStream(bufferedInput);
PGPObjectFactory objectFactory = new PGPObjectFactory(in);
@@ -116,11 +135,25 @@ public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper
addToData(newKeyring);
} else {
Log.e(Constants.TAG, "Object not recognized as PGPKeyRing!");
+ nonPgpCounter++;
}
}
}
} catch (Exception e) {
Log.e(Constants.TAG, "Exception on parsing key file!", e);
+ entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(data, e);
+ nonPgpCounter = 0;
+ }
+
+ if(isEmpty) {
+ Log.e(Constants.TAG, "File has no content!", new FileHasNoContent());
+ entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>
+ (data, new FileHasNoContent());
+ }
+
+ if(nonPgpCounter > 0) {
+ entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>
+ (data, new NonPgpPart(nonPgpCounter));
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
index d44dd5890..6d67a0e65 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
@@ -25,7 +25,6 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import android.content.Context;
import android.database.Cursor;
-import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -33,7 +32,9 @@ import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
-public class SelectKeyCursorAdapter extends CursorAdapter {
+
+
+public class SelectKeyCursorAdapter extends HighlightQueryCursorAdapter {
protected int mKeyType;
@@ -55,7 +56,6 @@ public class SelectKeyCursorAdapter extends CursorAdapter {
mInflater = LayoutInflater.from(context);
mListView = listView;
mKeyType = keyType;
-
initIndex(c);
}
@@ -104,12 +104,12 @@ public class SelectKeyCursorAdapter extends CursorAdapter {
String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
if (userIdSplit[0] != null) {
- mainUserId.setText(userIdSplit[0]);
+ mainUserId.setText(highlightSearchQuery(userIdSplit[0]));
} else {
mainUserId.setText(R.string.user_id_no_name);
}
if (userIdSplit[1] != null) {
- mainUserIdRest.setText(userIdSplit[1]);
+ mainUserIdRest.setText(highlightSearchQuery(userIdSplit[1]));
} else {
mainUserIdRest.setText("");
}
@@ -164,5 +164,4 @@ public class SelectKeyCursorAdapter extends CursorAdapter {
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return mInflater.inflate(R.layout.select_key_item, null);
}
-
}
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 54c7eb60e..046a98883 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
@@ -83,7 +83,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey);
- String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId));
+ String keyIdStr = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId));
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(cursor.getInt(mIndexAlgorithm),
cursor.getInt(mIndexKeySize));
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java
index 98b677511..a47601c9b 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java
@@ -32,6 +32,7 @@ import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.Choice;
+import java.util.ArrayList;
import java.util.Vector;
public class CreateKeyDialogFragment extends DialogFragment {
@@ -78,7 +79,7 @@ public class CreateKeyDialogFragment extends DialogFragment {
boolean wouldBeMasterKey = (childCount == 0);
final Spinner algorithm = (Spinner) view.findViewById(R.id.create_key_algorithm);
- Vector<Choice> choices = new Vector<Choice>();
+ ArrayList<Choice> choices = new ArrayList<Choice>();
choices.add(new Choice(Id.choice.algorithm.dsa, getResources().getString(
R.string.dsa)));
if (!wouldBeMasterKey) {
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 cd8bc79a9..162bf32fd 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
@@ -67,7 +67,7 @@ public class DeleteFileDialogFragment extends DialogFragment {
alert.setMessage(this.getString(R.string.file_delete_confirmation, deleteFile));
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-
+
@Override
public void onClick(DialogInterface dialog, int id) {
dismiss();
@@ -83,7 +83,10 @@ public class DeleteFileDialogFragment extends DialogFragment {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
ProgressDialogFragment deletingDialog = ProgressDialogFragment.newInstance(
- R.string.progress_deleting_securely, ProgressDialog.STYLE_HORIZONTAL, false, null);
+ getString(R.string.progress_deleting_securely),
+ ProgressDialog.STYLE_HORIZONTAL,
+ false,
+ null);
// Message is received after deleting is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(activity, deletingDialog) {
@@ -95,7 +98,7 @@ public class DeleteFileDialogFragment extends DialogFragment {
Toast.makeText(activity, R.string.file_delete_successful,
Toast.LENGTH_SHORT).show();
}
- };
+ }
};
// Create a new Messenger for the communication back
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
index 39ce63b5f..2a3a7508d 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
@@ -33,7 +33,6 @@ import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
-import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
index e88271240..afa05cc91 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
@@ -153,17 +153,17 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
dismiss();
long curKeyIndex = 1;
boolean keyOK = true;
- String passPhrase = mPassphraseEditText.getText().toString();
+ String passphrase = mPassphraseEditText.getText().toString();
long keyId;
PGPSecretKey clickSecretKey = secretKey;
if (clickSecretKey != null) {
- while (keyOK == true) {
+ while (keyOK) {
if (clickSecretKey != null) { // check again for loop
try {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- passPhrase.toCharArray());
+ passphrase.toCharArray());
PGPPrivateKey testKey = clickSecretKey
.extractPrivateKey(keyDecryptor);
if (testKey == null) {
@@ -206,10 +206,10 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
// cache the new passphrase
Log.d(Constants.TAG, "Everything okay! Caching entered passphrase");
- PassphraseCacheService.addCachedPassphrase(activity, keyId, passPhrase);
- if (keyOK == false && clickSecretKey.getKeyID() != keyId) {
+ PassphraseCacheService.addCachedPassphrase(activity, keyId, passphrase);
+ if ( !keyOK && clickSecretKey.getKeyID() != keyId) {
PassphraseCacheService.addCachedPassphrase(activity, clickSecretKey.getKeyID(),
- passPhrase);
+ passphrase);
}
sendMessageToHandler(MESSAGE_OKAY);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
index 6c62d14e0..b7a1882ef 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
@@ -30,7 +30,7 @@ import android.view.KeyEvent;
import org.sufficientlysecure.keychain.R;
public class ProgressDialogFragment extends DialogFragment {
- private static final String ARG_MESSAGE_ID = "message_id";
+ private static final String ARG_MESSAGE = "message";
private static final String ARG_STYLE = "style";
private static final String ARG_CANCELABLE = "cancelable";
@@ -39,16 +39,16 @@ public class ProgressDialogFragment extends DialogFragment {
/**
* Creates new instance of this fragment
*
- * @param messageId
+ * @param message
* @param style
* @param cancelable
* @return
*/
- public static ProgressDialogFragment newInstance(int messageId, int style, boolean cancelable,
+ public static ProgressDialogFragment newInstance(String message, int style, boolean cancelable,
OnCancelListener onCancelListener) {
ProgressDialogFragment frag = new ProgressDialogFragment();
Bundle args = new Bundle();
- args.putInt(ARG_MESSAGE_ID, messageId);
+ args.putString(ARG_MESSAGE, message);
args.putInt(ARG_STYLE, style);
args.putBoolean(ARG_CANCELABLE, cancelable);
@@ -117,22 +117,22 @@ public class ProgressDialogFragment extends DialogFragment {
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
- int messageId = getArguments().getInt(ARG_MESSAGE_ID);
+ String message = getArguments().getString(ARG_MESSAGE);
int style = getArguments().getInt(ARG_STYLE);
boolean cancelable = getArguments().getBoolean(ARG_CANCELABLE);
- dialog.setMessage(getString(messageId));
+ dialog.setMessage(message);
dialog.setProgressStyle(style);
if (cancelable) {
dialog.setButton(DialogInterface.BUTTON_NEGATIVE,
activity.getString(R.string.progress_cancel),
new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- });
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
}
// Disable the back button
@@ -140,7 +140,6 @@ public class ProgressDialogFragment extends DialogFragment {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
-
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true;
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
index 50e72dfba..e406547b3 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
@@ -101,9 +101,9 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
public void onClick(DialogInterface dialog, int id) {
dismiss();
- String passPhrase1 = mPassphraseEditText.getText().toString();
- String passPhrase2 = mPassphraseAgainEditText.getText().toString();
- if (!passPhrase1.equals(passPhrase2)) {
+ String passphrase1 = mPassphraseEditText.getText().toString();
+ String passphrase2 = mPassphraseAgainEditText.getText().toString();
+ if (!passphrase1.equals(passphrase2)) {
Toast.makeText(
activity,
getString(R.string.error_message,
@@ -112,7 +112,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
return;
}
- if (passPhrase1.equals("")) {
+ if (passphrase1.equals("")) {
Toast.makeText(
activity,
getString(R.string.error_message,
@@ -123,7 +123,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
// return resulting data back to activity
Bundle data = new Bundle();
- data.putString(MESSAGE_NEW_PASSPHRASE, passPhrase1);
+ data.putString(MESSAGE_NEW_PASSPHRASE, passphrase1);
sendMessageToHandler(MESSAGE_OKAY, data);
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java
index 03e09cdcb..b850638a6 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java
@@ -53,7 +53,6 @@ public class ShareNfcDialogFragment extends DialogFragment {
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
- alert.setIcon(android.R.drawable.ic_dialog_info);
alert.setTitle(R.string.share_nfc_dialog);
alert.setCancelable(true);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
index 6c265057e..65461cb4f 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
@@ -34,6 +34,7 @@ import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
@@ -58,6 +59,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
Spinner mUsage;
TextView mCreationDate;
BootstrapButton mExpiryDateButton;
+ GregorianCalendar mCreatedDate;
GregorianCalendar mExpiryDate;
private int mDatePickerResultCount = 0;
@@ -113,8 +115,12 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
if (date == null) {
date = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
}
-
- DatePickerDialog dialog = new DatePickerDialog(getContext(),
+ /*
+ * Using custom DatePickerDialog which overrides the setTitle because
+ * the DatePickerDialog title is buggy (unix warparound bug).
+ * See: https://code.google.com/p/android/issues/detail?id=49066
+ */
+ DatePickerDialog dialog = new ExpiryDatePickerDialog(getContext(),
mExpiryDateSetListener, date.get(Calendar.YEAR), date.get(Calendar.MONTH),
date.get(Calendar.DAY_OF_MONTH));
mDatePickerResultCount = 0;
@@ -129,6 +135,21 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
}
}
});
+
+ // setCalendarViewShown() is supported from API 11 onwards.
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB)
+ // Hide calendarView in tablets because of the unix warparound bug.
+ dialog.getDatePicker().setCalendarViewShown(false);
+
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+ if ( dialog != null && mCreatedDate != null ) {
+ dialog.getDatePicker().setMinDate(mCreatedDate.getTime().getTime()+ DateUtils.DAY_IN_MILLIS);
+ } else {
+ //When created date isn't available
+ dialog.getDatePicker().setMinDate(date.getTime().getTime()+ DateUtils.DAY_IN_MILLIS);
+ }
+ }
+
dialog.show();
}
});
@@ -153,9 +174,8 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
}
mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(key));
- String keyId1Str = PgpKeyHelper.convertKeyIdToHex(key.getKeyID());
- String keyId2Str = PgpKeyHelper.convertKeyIdToHex(key.getKeyID() >> 32);
- mKeyId.setText(keyId1Str + " " + keyId2Str);
+ String keyIdStr = PgpKeyHelper.convertKeyIdToHex(key.getKeyID());
+ mKeyId.setText(keyIdStr);
Vector<Choice> choices = new Vector<Choice>();
boolean isElGamalKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT);
@@ -205,7 +225,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
cal.setTime(PgpKeyHelper.getCreationDate(key));
- mCreationDate.setText(DateFormat.getDateInstance().format(cal.getTime()));
+ setCreatedDate(cal);
cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
Date expiryDate = PgpKeyHelper.getExpiryDate(key);
if (expiryDate == null) {
@@ -235,6 +255,15 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
mEditorListener = listener;
}
+ private void setCreatedDate(GregorianCalendar date) {
+ mCreatedDate = date;
+ if (date == null) {
+ mCreationDate.setText(getContext().getString(R.string.none));
+ } else {
+ mCreationDate.setText(DateFormat.getDateInstance().format(date.getTime()));
+ }
+ }
+
private void setExpiryDate(GregorianCalendar date) {
mExpiryDate = date;
if (date == null) {
@@ -253,3 +282,14 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
}
}
+
+class ExpiryDatePickerDialog extends DatePickerDialog {
+
+ public ExpiryDatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) {
+ super(context, callBack, year, monthOfYear, dayOfMonth);
+ }
+ //Set permanent title.
+ public void setTitle(CharSequence title) {
+ super.setTitle(getContext().getString(R.string.expiry_date_dialog_title));
+ }
+}
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 a95d80a4e..0acfe13bc 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
@@ -80,19 +80,19 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
public void setType(int type) {
mType = type;
switch (type) {
- case Id.type.user_id: {
- mTitle.setText(R.string.section_user_ids);
- break;
- }
+ case Id.type.user_id: {
+ mTitle.setText(R.string.section_user_ids);
+ break;
+ }
- case Id.type.key: {
- mTitle.setText(R.string.section_keys);
- break;
- }
+ case Id.type.key: {
+ mTitle.setText(R.string.section_keys);
+ break;
+ }
- default: {
- break;
- }
+ default: {
+ break;
+ }
}
}
@@ -103,7 +103,9 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
}
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
@Override
protected void onFinishInflate() {
mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -121,7 +123,9 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
super.onFinishInflate();
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
public void onDeleted(Editor editor) {
this.updateEditorsVisible();
}
@@ -131,38 +135,40 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
mEditors.setVisibility(hasChildren ? View.VISIBLE : View.GONE);
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
public void onClick(View v) {
if (canEdit) {
switch (mType) {
- case Id.type.user_id: {
- UserIdEditor view = (UserIdEditor) mInflater.inflate(
- R.layout.edit_key_user_id_item, mEditors, false);
- view.setEditorListener(this);
- if (mEditors.getChildCount() == 0) {
- view.setIsMainUserId(true);
+ case Id.type.user_id: {
+ UserIdEditor view = (UserIdEditor) mInflater.inflate(
+ R.layout.edit_key_user_id_item, mEditors, false);
+ view.setEditorListener(this);
+ if (mEditors.getChildCount() == 0) {
+ view.setIsMainUserId(true);
+ }
+ mEditors.addView(view);
+ break;
}
- mEditors.addView(view);
- break;
- }
- case Id.type.key: {
- CreateKeyDialogFragment mCreateKeyDialogFragment = CreateKeyDialogFragment.newInstance(mEditors.getChildCount());
- mCreateKeyDialogFragment.setOnAlgorithmSelectedListener(new CreateKeyDialogFragment.OnAlgorithmSelectedListener() {
- @Override
- public void onAlgorithmSelected(Choice algorithmChoice, int keySize) {
- mNewKeyAlgorithmChoice = algorithmChoice;
- mNewKeySize = keySize;
- createKey();
- }
- });
- mCreateKeyDialogFragment.show(mActivity.getSupportFragmentManager(), "createKeyDialog");
- break;
- }
+ case Id.type.key: {
+ CreateKeyDialogFragment mCreateKeyDialogFragment = CreateKeyDialogFragment.newInstance(mEditors.getChildCount());
+ mCreateKeyDialogFragment.setOnAlgorithmSelectedListener(new CreateKeyDialogFragment.OnAlgorithmSelectedListener() {
+ @Override
+ public void onAlgorithmSelected(Choice algorithmChoice, int keySize) {
+ mNewKeyAlgorithmChoice = algorithmChoice;
+ mNewKeySize = keySize;
+ createKey();
+ }
+ });
+ mCreateKeyDialogFragment.show(mActivity.getSupportFragmentManager(), "createKeyDialog");
+ break;
+ }
- default: {
- break;
- }
+ default: {
+ break;
+ }
}
this.updateEditorsVisible();
}
@@ -220,31 +226,34 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
Bundle data = new Bundle();
Boolean isMasterKey;
- String passPhrase;
+ String passphrase;
if (mEditors.getChildCount() > 0) {
PGPSecretKey masterKey = ((KeyEditor) mEditors.getChildAt(0)).getValue();
- passPhrase = PassphraseCacheService
+ passphrase = PassphraseCacheService
.getCachedPassphrase(mActivity, masterKey.getKeyID());
isMasterKey = false;
} else {
- passPhrase = "";
+ passphrase = "";
isMasterKey = true;
}
data.putBoolean(KeychainIntentService.GENERATE_KEY_MASTER_KEY, isMasterKey);
- data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passPhrase);
+ data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase);
data.putInt(KeychainIntentService.GENERATE_KEY_ALGORITHM, mNewKeyAlgorithmChoice.getId());
data.putInt(KeychainIntentService.GENERATE_KEY_KEY_SIZE, mNewKeySize);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// show progress dialog
- mGeneratingDialog = ProgressDialogFragment.newInstance(R.string.progress_generating,
- ProgressDialog.STYLE_SPINNER, true, new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- mActivity.stopService(intent);
- }
- });
+ mGeneratingDialog = ProgressDialogFragment.newInstance(
+ getResources().getQuantityString(R.plurals.progress_generating, 1),
+ ProgressDialog.STYLE_SPINNER,
+ true,
+ new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ mActivity.stopService(intent);
+ }
+ });
// Message is received after generating is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(mActivity,
@@ -261,7 +270,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
.getByteArray(KeychainIntentService.RESULT_NEW_KEY));
addGeneratedKeyToView(newKey);
}
- };
+ }
};
// Create a new Messenger for the communication back
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java
index 5428b626e..71cd89ae8 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java
@@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui.widget;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import android.widget.*;
import org.sufficientlysecure.keychain.R;
import android.content.Context;
@@ -26,11 +27,9 @@ import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
import com.beardedhen.androidbootstrap.BootstrapButton;
+import org.sufficientlysecure.keychain.helper.ContactHelper;
public class UserIdEditor extends LinearLayout implements Editor, OnClickListener {
private EditorListener mEditorListener = null;
@@ -38,7 +37,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene
private BootstrapButton mDeleteButton;
private RadioButton mIsMainUserId;
private EditText mName;
- private EditText mEmail;
+ private AutoCompleteTextView mEmail;
private EditText mComment;
// see http://www.regular-expressions.info/email.html
@@ -102,9 +101,17 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene
mIsMainUserId.setOnClickListener(this);
mName = (EditText) findViewById(R.id.name);
- mEmail = (EditText) findViewById(R.id.email);
+ mEmail = (AutoCompleteTextView) findViewById(R.id.email);
mComment = (EditText) findViewById(R.id.comment);
+
+ mEmail.setThreshold(1); // Start working from first character
+ mEmail.setAdapter(
+ new ArrayAdapter<String>
+ (this.getContext(), android.R.layout.simple_dropdown_item_1line,
+ ContactHelper.getMailAccounts(getContext())
+ ));
+
super.onFinishInflate();
}
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 b94c42e90..32266839c 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
@@ -1,6 +1,8 @@
/*
+ * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2011 Thialfihar <thi@thialfihar.org>
* Copyright (C) 2011 Senecaso
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -224,7 +226,7 @@ public class HkpKeyServer extends KeyServer {
HttpClient client = new DefaultHttpClient();
try {
HttpGet get = new HttpGet("http://" + mHost + ":" + mPort
- + "/pks/lookup?op=get&search=0x" + PgpKeyHelper.convertKeyToHex(keyId));
+ + "/pks/lookup?op=get&search=" + PgpKeyHelper.convertKeyIdToHex(keyId));
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
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 072affb1f..7049820e8 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
@@ -1,6 +1,8 @@
/*
+ * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2011 Thialfihar <thi@thialfihar.org>
* Copyright (C) 2011 Senecaso
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -16,14 +18,8 @@
package org.sufficientlysecure.keychain.util;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Date;
import java.util.List;
-import android.os.Parcel;
-import android.os.Parcelable;
-
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
public abstract class KeyServer {
@@ -52,5 +48,5 @@ public abstract class KeyServer {
abstract String get(long keyId) throws QueryException;
- abstract void add(String armouredText) throws AddKeyException;
+ abstract void add(String armoredText) throws AddKeyException;
}
diff --git a/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_save.png b/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_save.png
new file mode 100644
index 000000000..c4b7783cc
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_save.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_search.png b/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_search.png
new file mode 100644
index 000000000..f594b4e48
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_search.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_secure.png b/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_secure.png
new file mode 100644
index 000000000..287ae2fb0
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_secure.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_select_all.png b/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_select_all.png
new file mode 100644
index 000000000..fc0dd57b6
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_select_all.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_save.png b/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_save.png
new file mode 100644
index 000000000..61304a68c
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_save.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_search.png b/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_search.png
new file mode 100644
index 000000000..f6719d228
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_search.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_secure.png b/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_secure.png
new file mode 100644
index 000000000..d49217234
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_secure.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_select_all.png b/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_select_all.png
new file mode 100644
index 000000000..da37d7a6e
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_select_all.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_save.png b/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_save.png
new file mode 100644
index 000000000..29c5f4d3b
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_save.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_search.png b/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_search.png
new file mode 100644
index 000000000..aad535e97
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_search.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_secure.png b/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_secure.png
new file mode 100644
index 000000000..2a0898381
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_secure.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_select_all.png b/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_select_all.png
new file mode 100644
index 000000000..af37a3680
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_select_all.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_save.png b/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_save.png
new file mode 100644
index 000000000..744350049
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_save.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_search.png b/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_search.png
new file mode 100644
index 000000000..9c0ea3ca0
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_search.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_secure.png b/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_secure.png
new file mode 100644
index 000000000..d8c094ed8
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_secure.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_select_all.png b/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_select_all.png
new file mode 100644
index 000000000..aa5937eab
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_select_all.png
Binary files differ
diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_error_message.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_error_message.xml
index 5927dbf43..48aa89d4f 100644
--- a/OpenPGP-Keychain/src/main/res/layout/api_app_error_message.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/api_app_error_message.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_select_pub_keys_activity.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_select_pub_keys_activity.xml
index 877b4e74e..a10592607 100644
--- a/OpenPGP-Keychain/src/main/res/layout/api_app_select_pub_keys_activity.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/api_app_select_pub_keys_activity.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
diff --git a/OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml b/OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml
index e6c81c3fc..c56ba130e 100644
--- a/OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml
@@ -71,7 +71,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
- android:text="Main User Id"
+ android:text="@string/label_main_user_id"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_alignTop="@+id/linearLayout"
android:layout_toRightOf="@+id/relativeLayout" />
diff --git a/OpenPGP-Keychain/src/main/res/layout/drawer_list.xml b/OpenPGP-Keychain/src/main/res/layout/drawer_list.xml
index 18210afc5..81ceba20c 100644
--- a/OpenPGP-Keychain/src/main/res/layout/drawer_list.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/drawer_list.xml
@@ -12,7 +12,7 @@
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
- android:background="#fff"
+ android:background="@color/white"
android:choiceMode="singleChoice"
android:divider="@color/bg_gray"
android:dividerHeight="1dp" />
diff --git a/OpenPGP-Keychain/src/main/res/layout/edit_key_activity.xml b/OpenPGP-Keychain/src/main/res/layout/edit_key_activity.xml
index 182540dc5..fc4422cf0 100644
--- a/OpenPGP-Keychain/src/main/res/layout/edit_key_activity.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/edit_key_activity.xml
@@ -27,7 +27,7 @@
android:text="@string/label_no_passphrase" />
<com.beardedhen.androidbootstrap.BootstrapButton
- android:id="@+id/edit_key_btn_change_pass_phrase"
+ android:id="@+id/edit_key_btn_change_passphrase"
android:layout_width="match_parent"
android:layout_height="60dp"
android:padding="4dp"
diff --git a/OpenPGP-Keychain/src/main/res/layout/edit_key_key_item.xml b/OpenPGP-Keychain/src/main/res/layout/edit_key_key_item.xml
index 4bf4aa38a..45b8d6511 100644
--- a/OpenPGP-Keychain/src/main/res/layout/edit_key_key_item.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/edit_key_key_item.xml
@@ -50,7 +50,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="5dip"
- android:text="Name" />
+ android:text="@string/label_name" />
</TableRow>
<TableRow>
diff --git a/OpenPGP-Keychain/src/main/res/layout/edit_key_user_id_item.xml b/OpenPGP-Keychain/src/main/res/layout/edit_key_user_id_item.xml
index 663949d8e..3030d6bae 100644
--- a/OpenPGP-Keychain/src/main/res/layout/edit_key_user_id_item.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/edit_key_user_id_item.xml
@@ -49,7 +49,7 @@
android:paddingRight="5dip"
android:text="@string/label_email" />
- <EditText
+ <AutoCompleteTextView
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/OpenPGP-Keychain/src/main/res/layout/encrypt_activity.xml b/OpenPGP-Keychain/src/main/res/layout/encrypt_activity.xml
index 678f2bd4e..dc4cf0063 100644
--- a/OpenPGP-Keychain/src/main/res/layout/encrypt_activity.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/encrypt_activity.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
+ xmlns:fontawesometext="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -82,7 +83,7 @@
android:layout_gravity="right"
android:ellipsize="end"
android:singleLine="true"
- android:text="Sign User Id"
+ android:text="@string/label_sign_user_id"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
@@ -92,7 +93,7 @@
android:layout_gravity="right"
android:ellipsize="end"
android:singleLine="true"
- android:text="Sign email"
+ android:text="@string/label_sign_email"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>
@@ -135,7 +136,7 @@
<TableRow>
<TextView
- android:id="@+id/label_passPhrase"
+ android:id="@+id/label_passphrase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
@@ -144,7 +145,7 @@
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
- android:id="@+id/passPhrase"
+ android:id="@+id/passphrase"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword" />
@@ -153,7 +154,7 @@
<TableRow>
<TextView
- android:id="@+id/label_passPhraseAgain"
+ android:id="@+id/label_passphraseAgain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
@@ -162,7 +163,7 @@
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
- android:id="@+id/passPhraseAgain"
+ android:id="@+id/passphraseAgain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword" />
@@ -251,51 +252,97 @@
</LinearLayout>
<LinearLayout
+ android:id="@+id/advancedSettingsControl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal">
-
- <TextView
- android:id="@+id/label_fileCompression"
- android:layout_width="0dip"
+ 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_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_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:layout_gravity="center_vertical" />
+ 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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal">
+ android:orientation="vertical"
+ android:visibility="gone">
- <CheckBox
- android:id="@+id/deleteAfterEncryption"
- android:layout_width="wrap_content"
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:text="@string/label_delete_after_encryption" />
- </LinearLayout>
+ android:orientation="horizontal">
- <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" />
- <CheckBox
- android:id="@+id/asciiArmour"
- android:layout_width="wrap_content"
+ <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:layout_gravity="center_vertical"
- android:text="@string/label_ascii_armor" />
+ 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>
</LinearLayout>
</LinearLayout>
</ViewFlipper>
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 37d1c5702..3cc0bc6dc 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
@@ -48,7 +48,7 @@
android:id="@+id/mainUserId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Main User ID"
+ android:text="@string/label_main_user_id"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
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 f3a21e1bf..77bd6f4e9 100644
--- a/OpenPGP-Keychain/src/main/res/layout/key_list_fragment.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/key_list_fragment.xml
@@ -3,75 +3,106 @@
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical" >
-
- <se.emilsjolander.stickylistheaders.StickyListHeadersListView
- android:id="@+id/list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipToPadding="false"
- android:drawSelectorOnTop="true"
- android:fastScrollEnabled="true"
- android:paddingBottom="16dp"
- android:paddingLeft="16dp"
- android:paddingRight="32dp"
- android:scrollbarStyle="outsideOverlay" />
+ android:orientation="vertical">
+ <!--rebuild functionality of ListFragment -->
<LinearLayout
- android:id="@+id/empty"
+ android:id="@+id/key_list_progress_container"
+ android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:gravity="center"
- android:orientation="vertical"
- android:visibility="gone" >
+ android:visibility="gone"
+ android:gravity="center">
- <TextView
+ <ProgressBar
+ style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:text="@string/key_list_empty_text1"
- android:textAppearance="?android:attr/textAppearanceLarge" />
+ android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="center"
+ android:textAppearance="?android:attr/textAppearanceSmall"
android:text=""
- android:textAppearance="?android:attr/textAppearanceLarge" />
+ android:paddingTop="4dip"
+ android:singleLine="true" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="4dp"
- android:gravity="center"
- android:text="@string/key_list_empty_text2"
- android:textAppearance="?android:attr/textAppearanceSmall" />
+ </LinearLayout>
- <com.beardedhen.androidbootstrap.BootstrapButton
- android:id="@+id/key_list_empty_button_create"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="4dp"
- android:text="@string/key_list_empty_button_create"
- bootstrapbutton:bb_icon_left="fa-plus"
- bootstrapbutton:bb_type="default" />
+ <FrameLayout
+ android:id="@+id/key_list_list_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="4dp"
+ <se.emilsjolander.stickylistheaders.StickyListHeadersListView
+ android:id="@+id/key_list_list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipToPadding="false"
+ android:drawSelectorOnTop="true"
+ android:fastScrollEnabled="true"
+ android:paddingBottom="16dp"
+ android:paddingLeft="16dp"
+ android:paddingRight="32dp"
+ android:scrollbarStyle="outsideOverlay" />
+
+ <LinearLayout
+ android:id="@+id/key_list_empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:gravity="center"
- android:text="@string/key_list_empty_text3"
- android:textAppearance="?android:attr/textAppearanceSmall" />
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:text="@string/key_list_empty_text1"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="4dp"
+ android:gravity="center"
+ android:text="@string/key_list_empty_text2"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <com.beardedhen.androidbootstrap.BootstrapButton
+ android:id="@+id/key_list_empty_button_create"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="4dp"
+ android:text="@string/key_list_empty_button_create"
+ bootstrapbutton:bb_icon_left="fa-plus"
+ bootstrapbutton:bb_type="default" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="4dp"
+ android:gravity="center"
+ android:text="@string/key_list_empty_text3"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <com.beardedhen.androidbootstrap.BootstrapButton
+ android:id="@+id/key_list_empty_button_import"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="4dp"
+ android:text="@string/key_list_empty_button_import"
+ bootstrapbutton:bb_icon_left="fa-download"
+ bootstrapbutton:bb_type="default" />
+ </LinearLayout>
+
+ </FrameLayout>
- <com.beardedhen.androidbootstrap.BootstrapButton
- android:id="@+id/key_list_empty_button_import"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="4dp"
- android:text="@string/key_list_empty_button_import"
- bootstrapbutton:bb_icon_left="fa-download"
- bootstrapbutton:bb_type="default" />
- </LinearLayout>
-</FrameLayout> \ No newline at end of file
+</FrameLayout>
diff --git a/OpenPGP-Keychain/src/main/res/layout/key_list_item.xml b/OpenPGP-Keychain/src/main/res/layout/key_list_item.xml
index 12c6b6caa..f52693138 100644
--- a/OpenPGP-Keychain/src/main/res/layout/key_list_item.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/key_list_item.xml
@@ -15,7 +15,7 @@
android:id="@+id/mainUserId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Main User ID"
+ android:text="@string/label_main_user_id"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
diff --git a/OpenPGP-Keychain/src/main/res/layout/key_server_export.xml b/OpenPGP-Keychain/src/main/res/layout/key_server_export.xml
index c162a6e28..6031bf7c7 100644
--- a/OpenPGP-Keychain/src/main/res/layout/key_server_export.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/key_server_export.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<ScrollView 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"
android:layout_width="match_parent"
android:layout_height="match_parent" >
diff --git a/OpenPGP-Keychain/src/main/res/layout/passphrase_repeat_dialog.xml b/OpenPGP-Keychain/src/main/res/layout/passphrase_repeat_dialog.xml
index 2bdd231ee..ae523762c 100644
--- a/OpenPGP-Keychain/src/main/res/layout/passphrase_repeat_dialog.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/passphrase_repeat_dialog.xml
@@ -6,7 +6,9 @@
android:paddingRight="16dp"
android:stretchColumns="1" >
- <TableRow>
+ <TableRow
+ android:layout_marginBottom="5dip"
+ >
<TextView
android:id="@+id/passphrase_label_passphrase"
@@ -24,7 +26,9 @@
android:padding="4dp" />
</TableRow>
- <TableRow>
+ <TableRow
+ android:layout_marginBottom="10dip"
+ >
<TextView
android:id="@+id/passphrase_label_passphrase_again"
diff --git a/OpenPGP-Keychain/src/main/res/layout/select_key_item.xml b/OpenPGP-Keychain/src/main/res/layout/select_key_item.xml
index bbfe17c44..08c161ec6 100644
--- a/OpenPGP-Keychain/src/main/res/layout/select_key_item.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/select_key_item.xml
@@ -25,7 +25,7 @@
android:id="@+id/mainUserId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Main User ID"
+ android:text="@string/label_main_user_id"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
diff --git a/OpenPGP-Keychain/src/main/res/layout/select_secret_key_layout_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/select_secret_key_layout_fragment.xml
index 4a3cd3d28..1141091a3 100644
--- a/OpenPGP-Keychain/src/main/res/layout/select_secret_key_layout_fragment.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/select_secret_key_layout_fragment.xml
@@ -3,7 +3,7 @@
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal" >
+ android:orientation="horizontal">
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/select_secret_key_select_key_button"
@@ -25,31 +25,45 @@
android:layout_marginLeft="4dp"
android:layout_marginTop="4dp"
android:orientation="vertical"
- android:paddingLeft="16dp" >
+ android:paddingLeft="4dp">
<!-- Has been made focusable to display error messages with setError -->
-
<TextView
android:id="@+id/select_secret_key_user_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="right"
+ android:layout_gravity="left"
android:ellipsize="end"
android:focusable="true"
android:focusableInTouchMode="true"
android:singleLine="true"
- android:text="@string/api_settings_no_key"
- android:textAppearance="?android:attr/textAppearanceMedium" />
+ android:visibility="gone"
+ android:layout_marginRight="5dip"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/select_secret_key_user_id_rest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="right"
+ android:layout_gravity="left"
android:ellipsize="end"
android:singleLine="true"
+ android:layout_marginRight="5dip"
android:text=""
+ android:visibility="gone"
android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <TextView
+ android:id="@+id/select_secret_key_master_key_hex"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="left"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="@string/api_settings_no_key"
+ android:layout_marginRight="5dip" />
+
+
</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 c44835bb0..9e4bc70eb 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
@@ -20,7 +20,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="5dip"
- android:text="Key ID"
+ android:text="@string/label_key_id"
android:textAppearance="?android:attr/textAppearanceMedium"
android:typeface="monospace" />
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 644548183..6ef3f3072 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
@@ -92,7 +92,7 @@
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
- android:stretchColumns="1">
+ android:shrinkColumns="1">
<TableRow>
diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml
index 508d080a6..22f0cdc5f 100644
--- a/OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml
@@ -10,7 +10,7 @@
android:id="@+id/userId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="User ID"
+ android:text="@string/user_id"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/menu/key_list.xml b/OpenPGP-Keychain/src/main/res/menu/key_list.xml
index 23ab8c9f3..addef0c2d 100644
--- a/OpenPGP-Keychain/src/main/res/menu/key_list.xml
+++ b/OpenPGP-Keychain/src/main/res/menu/key_list.xml
@@ -4,12 +4,17 @@
<item
android:id="@+id/menu_key_list_import"
- app:showAsAction="always|withText"
+ app:showAsAction="ifRoom|withText"
android:icon="@drawable/ic_action_add_person"
android:title="@string/menu_import" />
<item
android:id="@+id/menu_key_list_export"
app:showAsAction="never"
android:title="@string/menu_export_keys" />
-
-</menu> \ No newline at end of file
+ <item
+ android:id="@+id/menu_key_list_search"
+ android:title="@string/menu_search"
+ android:icon="@drawable/ic_action_search"
+ app:actionViewClass="android.support.v7.widget.SearchView"
+ app:showAsAction="collapseActionView|ifRoom" />
+</menu>
diff --git a/OpenPGP-Keychain/src/main/res/menu/key_list_multi.xml b/OpenPGP-Keychain/src/main/res/menu/key_list_multi.xml
index bbed11f07..db709052f 100644
--- a/OpenPGP-Keychain/src/main/res/menu/key_list_multi.xml
+++ b/OpenPGP-Keychain/src/main/res/menu/key_list_multi.xml
@@ -2,11 +2,20 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
+ android:id="@+id/menu_key_list_multi_select_all"
+ android:icon="@drawable/ic_action_select_all"
+ android:title="@string/menu_select_all" />
+ <item
+ android:id="@+id/menu_key_list_multi_export"
+ android:icon="@drawable/ic_action_import_export"
+ android:title="@string/menu_export_key" />
+ <item
android:id="@+id/menu_key_list_multi_encrypt"
+ android:icon="@drawable/ic_action_secure"
android:title="@string/menu_encrypt_to" />
<item
android:id="@+id/menu_key_list_multi_delete"
android:icon="@drawable/ic_action_discard"
android:title="@string/menu_delete_key" />
-</menu> \ No newline at end of file
+</menu>
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 50220bd0b..37d4193f7 100644
--- a/OpenPGP-Keychain/src/main/res/raw-de/help_about.html
+++ b/OpenPGP-Keychain/src/main/res/raw-de/help_about.html
@@ -2,7 +2,7 @@
<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><a href="http://www.openkeychain.org">OpenKeychain</a> ist eine OpenPGP implementation für Android.</p>
<p>Lizenz: GPLv3+</p>
<h2>Entwickler OpenKeychain</h2>
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 ea31d1f3d..1197869b5 100644
--- a/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html
+++ b/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html
@@ -86,7 +86,7 @@
</ul>
<h2>1.0.2</h2>
<ul>
-<li>filterable key lists</li>
+<li>Filterbare Schlüsselliste</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>
diff --git a/OpenPGP-Keychain/src/main/res/raw-el/help_about.html b/OpenPGP-Keychain/src/main/res/raw-el/help_about.html
new file mode 100644
index 000000000..863aeee58
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-el/help_about.html
@@ -0,0 +1,45 @@
+<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>
+
+</ul>
+<h2>Developers APG 1.x</h2>
+<ul>
+<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>
+<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>
+<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_changelog.html b/OpenPGP-Keychain/src/main/res/raw-el/help_changelog.html
new file mode 100644
index 000000000..abf660ba8
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-el/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-el/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-el/help_nfc_beam.html
new file mode 100644
index 000000000..88492731c
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-el/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-el/help_start.html b/OpenPGP-Keychain/src/main/res/raw-el/help_start.html
new file mode 100644
index 000000000..3a6443a2f
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-el/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 "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>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-el/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-el/nfc_beam_share.html
new file mode 100644
index 000000000..083e055c7
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-el/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-fa-rIR/help_about.html b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_about.html
new file mode 100644
index 000000000..863aeee58
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_about.html
@@ -0,0 +1,45 @@
+<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>
+
+</ul>
+<h2>Developers APG 1.x</h2>
+<ul>
+<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>
+<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>
+<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-fa-rIR/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_changelog.html
new file mode 100644
index 000000000..abf660ba8
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/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-fa-rIR/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_nfc_beam.html
new file mode 100644
index 000000000..88492731c
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/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-fa-rIR/help_start.html b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_start.html
new file mode 100644
index 000000000..f8c255232
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_start.html
@@ -0,0 +1,19 @@
+<html>
+<head></head>
+<body>
+<h2>شروع کار</h2>
+<p>اول شما نیاز به یک جفت کلید شخصی دارید. از طریق منوها در "کلیدهای من" بسازید و یا از طریق"واردات کلیدهای" جفت کلیدهای موجود را وارد کنید. پس از آن، شما می توانید کلید های دوستان خود را دانلود کنید و یا آنها را از طریق کدهای QR یا 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>هم بخشی کردن</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>ترجمه ها</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-fa-rIR/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/nfc_beam_share.html
new file mode 100644
index 000000000..083e055c7
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/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/values-de/strings.xml b/OpenPGP-Keychain/src/main/res/values-de/strings.xml
index 09b4fdb23..dcb21dea3 100644
--- a/OpenPGP-Keychain/src/main/res/values-de/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-de/strings.xml
@@ -13,7 +13,6 @@
<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_pass_phrase">Passwort ändern</string>
<string name="title_set_passphrase">Passwort setzen</string>
<string name="title_send_email">E-Mail senden...</string>
<string name="title_encrypt_to_file">In eine Datei verschlüsseln</string>
@@ -266,12 +265,14 @@
<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_query">Keyserveranfrage fehlgeschlagen</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>
<!--progress dialogs, usually ending in '…'-->
<string name="progress_done">fertig.</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>
@@ -337,10 +338,6 @@
<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">OpenKeychain: Datei entschlüsseln</string>
- <string name="intent_import_key">OpenKeychain: Schlüssel importieren</string>
- <string name="intent_send_encrypt">OpenKeychain: Verschlüsseln</string>
- <string name="intent_send_decrypt">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>
diff --git a/OpenPGP-Keychain/src/main/res/values-el/strings.xml b/OpenPGP-Keychain/src/main/res/values-el/strings.xml
new file mode 100644
index 000000000..84b39c221
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/values-el/strings.xml
@@ -0,0 +1,53 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+ <!--title-->
+ <string name="title_select_recipients">Επιλογή Δημόσιου Κλειδιού</string>
+ <string name="title_select_secret_key">Επιλογή Ιδιωτικού Κλειδιού</string>
+ <string name="title_authentication">Κωδικός</string>
+ <string name="title_create_key">Δημιουργία Κλειδιού</string>
+ <string name="title_edit_key">Επεξεργασία Κλειδιού</string>
+ <string name="title_preferences">Επιλογές</string>
+ <!--section-->
+ <!--button-->
+ <string name="btn_sign">Υπόγραψε</string>
+ <string name="btn_save">Αποθήκευση</string>
+ <string name="btn_do_not_save">Ακύρωση</string>
+ <string name="btn_delete">Διαγραφή</string>
+ <string name="btn_no_date">Κανένα</string>
+ <string name="btn_okay">ΟΚ</string>
+ <string name="btn_change_passphrase">Αλλαγή κωδικού</string>
+ <string name="btn_set_passphrase">Επέλεξε Κωδικό</string>
+ <!--menu-->
+ <string name="menu_delete_key">Διαγραφής κλειδιού</string>
+ <string name="menu_create_key">Δημιουργίας κλειδιού</string>
+ <!--label-->
+ <string name="label_sign">Υπόγραψε</string>
+ <string name="label_message">Μήνυμα</string>
+ <string name="label_file">Αρχείο</string>
+ <string name="label_passphrase">Κωδικός</string>
+ <string name="label_passphrase_again">Ξανά</string>
+ <string name="label_algorithm">Αλγόριθμος</string>
+ <string name="label_encryption_algorithm">Αλγόριθμος κρυπτογράφησης</string>
+ <string name="label_asymmetric">Δημόσιο κλειδί</string>
+ <string name="label_symmetric">Κωδικός</string>
+ <string name="label_key_size">Μέγεθος κλειδιού</string>
+ <string name="label_email">Ηλεκτρονικό ταχυδρομίο</string>
+ <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-->
+</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 6efe9548d..41dc629aa 100644
--- a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml
@@ -10,7 +10,6 @@
<string name="title_edit_key">Editar clave</string>
<string name="title_preferences">Preferencias</string>
<string name="title_api_registered_apps">Aplicaciones registradas</string>
- <string name="title_change_pass_phrase">Cambiar contraseña</string>
<string name="title_set_passphrase">Establecer contraseña</string>
<string name="title_send_email">Enviar correo electrónico...</string>
<string name="title_encrypt_to_file">Cifrar a archivo</string>
diff --git a/OpenPGP-Keychain/src/main/res/values-es/strings.xml b/OpenPGP-Keychain/src/main/res/values-es/strings.xml
index 48ea6cc69..c643a3cd8 100644
--- a/OpenPGP-Keychain/src/main/res/values-es/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-es/strings.xml
@@ -13,7 +13,7 @@
<string name="title_preferences"> Preferencias</string>
<string name="title_api_registered_apps">Aplicaciones registradas</string>
<string name="title_key_server_preference">Prioridad del servidor de claves</string>
- <string name="title_change_pass_phrase">Cambiar la frase de contraseña</string>
+ <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_encrypt_to_file">Cifrar hacia archivo</string>
@@ -92,6 +92,7 @@
<string name="menu_beam_preferences">Ajustes de Beam</string>
<string name="menu_key_edit_cancel">Cancelar</string>
<string name="menu_encrypt_to">Cifrar hacia...</string>
+ <string name="menu_select_all">Seleccionar todo</string>
<!--label-->
<string name="label_sign">Firmar</string>
<string name="label_message">Mensaje</string>
@@ -125,6 +126,7 @@
<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>
+ <string name="expiry_date_dialog_title">Establer la fecha de vencimiento</string>
<plurals name="select_keys_button">
<item quantity="one">%d seleccionado</item>
<item quantity="other">%d seleccionados</item>
@@ -266,12 +268,16 @@
<string name="error_expiry_must_come_after_creation">la fecha de caducidad debe ser posterior a la fecha de creación</string>
<string name="error_can_not_delete_contact">no puedes eliminar este contacto porque eres tú mismo.</string>
<string name="error_can_not_delete_contacts">no puedes eliminar los siguientes contactos porque son tú mismo:\n%s</string>
+ <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>
<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>
<!--progress dialogs, usually ending in '…'-->
<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>
@@ -337,10 +343,10 @@
<string name="import_nfc_help_button">Ayuda</string>
<string name="import_clipboard_button">Tomar la clave desde el portapapeles</string>
<!--Intent labels-->
- <string name="intent_decrypt_file">OpenKeychain: Descifrar archivo</string>
- <string name="intent_import_key">OpenKeychain: Importar clave</string>
- <string name="intent_send_encrypt">OpenKeychain: Cifrar</string>
- <string name="intent_send_decrypt">OpenKeychain: Descifrar</string>
+ <string name="intent_decrypt_file">Descifrar archivo con OpenKeychain</string>
+ <string name="intent_import_key">Importar clave con OpenKeychain</string>
+ <string name="intent_send_encrypt">Cifrar con OpenKeychain</string>
+ <string name="intent_send_decrypt">Descifrar con OpenKeychain</string>
<!--Remote API-->
<string name="api_no_apps">¡No hay aplicaciones registradas!\n\nLas aplicaciones de terceros pueden pedir permiso de acceso a OpenKeychain. Después de obtener acceso, serán enumeradas aquí.</string>
<string name="api_settings_show_advanced">Mostrar la configuración avanzada</string>
diff --git a/OpenPGP-Keychain/src/main/res/values-fa-rIR/strings.xml b/OpenPGP-Keychain/src/main/res/values-fa-rIR/strings.xml
new file mode 100644
index 000000000..6bb115049
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/values-fa-rIR/strings.xml
@@ -0,0 +1,26 @@
+<?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-->
+</resources>
diff --git a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml
index bf66756cf..d99bbcd7c 100644
--- a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml
@@ -13,9 +13,10 @@
<string name="title_preferences">Préférences</string>
<string name="title_api_registered_apps">Applications enregistrées</string>
<string name="title_key_server_preference">Préférences du serveur de clefs</string>
- <string name="title_change_pass_phrase">Changer la phrase de passe</string>
+ <string name="title_change_passphrase">Modifier la phrase de passe</string>
<string name="title_set_passphrase">Définir la phrase de passe</string>
<string name="title_send_email">Envoyer un courriel...</string>
+ <string name="title_send_file">Envoyer un fichier...</string>
<string name="title_encrypt_to_file">Chiffrer vers un fichier</string>
<string name="title_decrypt_to_file">Déchiffrer vers un fichier</string>
<string name="title_import_keys">importer des clefs</string>
@@ -92,6 +93,7 @@
<string name="menu_beam_preferences">Paramètres Beam</string>
<string name="menu_key_edit_cancel">Annuler</string>
<string name="menu_encrypt_to">Chiffrer vers...</string>
+ <string name="menu_select_all">Tout sélectionner</string>
<!--label-->
<string name="label_sign">Signer</string>
<string name="label_message">Message</string>
@@ -104,6 +106,7 @@
<string name="label_select_public_keys">Destinataires</string>
<string name="label_delete_after_encryption">Supprimer après le chiffrement</string>
<string name="label_delete_after_decryption">Supprimer après le chiffrement</string>
+ <string name="label_share_after_encryption">Partager après chiffrement</string>
<string name="label_encryption_algorithm">Algorithme de chiffrement</string>
<string name="label_hash_algorithm">Algorithme de hachage</string>
<string name="label_asymmetric">Clef publique</string>
@@ -122,9 +125,12 @@
<string name="label_name">Nom</string>
<string name="label_comment">Commentaire</string>
<string name="label_email">Courriel</string>
+ <string name="label_sign_user_id">Signer l\'ID utilisateur</string>
+ <string name="label_sign_email">Signer le courriel</string>
<string name="label_send_key">Téléverser la clef vers le serveur de clefs choisi après certification</string>
<string name="label_fingerprint">Empreinte</string>
<string name="select_keys_button_default">Choisir</string>
+ <string name="expiry_date_dialog_title">Définir une date d\'expiration</string>
<plurals name="select_keys_button">
<item quantity="one">%d choisie</item>
<item quantity="other">%d choisies</item>
@@ -137,6 +143,7 @@
<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_key_servers">
<item quantity="one">%d serveur de clefs</item>
<item quantity="other">%d serveurs de clefs</item>
@@ -269,12 +276,19 @@
<string name="error_keyserver_insufficient_query">Requête serveur insuffisante</string>
<string name="error_keyserver_query">Échec lors de l\'interrogation du serveur de clefs</string>
<string name="error_keyserver_too_many_responses">Trop de réponses</string>
+ <string name="error_import_file_no_content">Le fichier n\'a pas de contenu</string>
+ <string name="error_generic_report_bug">Une erreur générique est survenue, veuillez créer un nouveau rapport de bogue pour OpenKeychain.</string>
<plurals name="error_can_not_delete_info">
<item quantity="one">Veuillez le supprimer depuis l\'écran « Mes Clefs »!</item>
<item quantity="other">Veuillez les supprimer depuis l\'écran « Mes Clefs »!</item>
</plurals>
+ <plurals name="error_import_non_pgp_part">
+ <item quantity="one">une partie du fichier chargé est un objet OpenPGP valide mais pas une clef OpenPGP</item>
+ <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_saving">sauvegarde...</string>
<string name="progress_importing">importation...</string>
<string name="progress_exporting">exportation...</string>
@@ -340,10 +354,10 @@
<string name="import_nfc_help_button">Aide</string>
<string name="import_clipboard_button">Obtenir la clef depuis le presse-papiers</string>
<!--Intent labels-->
- <string name="intent_decrypt_file">OpenKeychain : déchiffrer le ficher</string>
- <string name="intent_import_key">OpenKeychain : importer la clef</string>
- <string name="intent_send_encrypt">OpenKeychain : chiffrer</string>
- <string name="intent_send_decrypt">OpenKeychain : déchiffrer</string>
+ <string name="intent_decrypt_file">Déchiffrer le fichier avec OpenKeychain</string>
+ <string name="intent_import_key">Importer la clef avec OpenKeychain</string>
+ <string name="intent_send_encrypt">Chiffrer avec OpenKeychain</string>
+ <string name="intent_send_decrypt">Déchiffrer avec OpenKeychain</string>
<!--Remote API-->
<string name="api_no_apps">Aucune application enregistrée !\n\nLes applications tierces peuvent demander l\'accès à OpenKeychain. Après avoir autorisé l\'accès, elles seront listées ici.</string>
<string name="api_settings_show_advanced">Afficher les paramètres avancés</string>
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 86a094c41..f9e7074da 100644
--- a/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml
@@ -13,9 +13,10 @@
<string name="title_preferences">Preferenze</string>
<string name="title_api_registered_apps">App Registrate</string>
<string name="title_key_server_preference">Preferenze Server delle Chiavi</string>
- <string name="title_change_pass_phrase">Cambia Frase di Accesso</string>
+ <string name="title_change_passphrase">Cambia Frase Di Accesso</string>
<string name="title_set_passphrase">Imposta Frase di Accesso</string>
<string name="title_send_email">Invia Mail...</string>
+ <string name="title_send_file">Invia file...</string>
<string name="title_encrypt_to_file">Codifica File</string>
<string name="title_decrypt_to_file">Decodifica File</string>
<string name="title_import_keys">Importa Chiavi</string>
@@ -92,6 +93,7 @@
<string name="menu_beam_preferences">Impostazioni Beam</string>
<string name="menu_key_edit_cancel">Annulla</string>
<string name="menu_encrypt_to">Codifica su...</string>
+ <string name="menu_select_all">Seleziona tutto</string>
<!--label-->
<string name="label_sign">Firma</string>
<string name="label_message">Messaggio</string>
@@ -104,6 +106,7 @@
<string name="label_select_public_keys">Destinatari</string>
<string name="label_delete_after_encryption">Cancella Dopo Codifica</string>
<string name="label_delete_after_decryption">Cancella Dopo Decodifica</string>
+ <string name="label_share_after_encryption">Condividi Dopo la Codifica</string>
<string name="label_encryption_algorithm">Algoritmo di Codifica</string>
<string name="label_hash_algorithm">Algoritmo di Hash</string>
<string name="label_asymmetric">Chiave Pubblica</string>
@@ -122,9 +125,12 @@
<string name="label_name">Nome</string>
<string name="label_comment">Commento</string>
<string name="label_email">Email</string>
+ <string name="label_sign_user_id">Firma ID Utente</string>
+ <string name="label_sign_email">Firma email</string>
<string name="label_send_key">Carica chiave nel server delle chiavi selezionati dopo la certificazione</string>
<string name="label_fingerprint">Impronta</string>
<string name="select_keys_button_default">Seleziona</string>
+ <string name="expiry_date_dialog_title">Impostare la data di scadenza</string>
<plurals name="select_keys_button">
<item quantity="one">%d selezionato</item>
<item quantity="other">%d selezionati</item>
@@ -137,6 +143,7 @@
<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_key_servers">
<item quantity="one">%d server delle chiavi</item>
<item quantity="other">%d server delle chiavi</item>
@@ -269,12 +276,19 @@
<string name="error_keyserver_insufficient_query">Query di server insufficiente</string>
<string name="error_keyserver_query">Interrogazione del server delle chiavi fallita</string>
<string name="error_keyserver_too_many_responses">Troppi responsi</string>
+ <string name="error_import_file_no_content">Il File non ha contenuti</string>
+ <string name="error_generic_report_bug">Si è verificato un errore generico, si prega di creare una nuova segnalazione di errore per OpenKeychain.</string>
<plurals name="error_can_not_delete_info">
<item quantity="one">Per favore cancellala dalla schermata \'Mie Chavi\'</item>
<item quantity="other">Per favore cancellatele dalla schermata \'Mie Chavi\'</item>
</plurals>
+ <plurals name="error_import_non_pgp_part">
+ <item quantity="one">parte del file caricato e\' un oggetto OpenPGP valido, ma non una chave OpenPGP</item>
+ <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_saving">salvataggio...</string>
<string name="progress_importing">importazione...</string>
<string name="progress_exporting">esportazione...</string>
@@ -340,10 +354,10 @@
<string name="import_nfc_help_button">Aiuto</string>
<string name="import_clipboard_button">Ottieni chiave dagli appunti</string>
<!--Intent labels-->
- <string name="intent_decrypt_file">OpenKeyChain: Decodifica File</string>
- <string name="intent_import_key">OpenKeyChain: Importa Chiave</string>
- <string name="intent_send_encrypt">OpenKeychain: Codifica</string>
- <string name="intent_send_decrypt">OpenKeychain: Decodifica</string>
+ <string name="intent_decrypt_file">Decodifica File con OpenKeychain</string>
+ <string name="intent_import_key">Importa Chiave con OpenKeychain</string>
+ <string name="intent_send_encrypt">Codifica con OpenKeychain</string>
+ <string name="intent_send_decrypt">Decodifica con OpenKeychain</string>
<!--Remote API-->
<string name="api_no_apps">Nessuna app registrata!\n\nApp di terza parti possono richiedere accesso a OpenKeychain. Dopo aver concesso l\'accesso, saranno elencate qui.</string>
<string name="api_settings_show_advanced">Mostra impostazioni avanzate</string>
diff --git a/OpenPGP-Keychain/src/main/res/values-ja/strings.xml b/OpenPGP-Keychain/src/main/res/values-ja/strings.xml
index c99f8b31c..e5ee5ecc0 100644
--- a/OpenPGP-Keychain/src/main/res/values-ja/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-ja/strings.xml
@@ -13,9 +13,10 @@
<string name="title_preferences">設定</string>
<string name="title_api_registered_apps">登録済みのアプリケーション</string>
<string name="title_key_server_preference">鍵サーバ設定</string>
- <string name="title_change_pass_phrase">パスフレーズの変更</string>
+ <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>
@@ -92,6 +93,7 @@
<string name="menu_beam_preferences">Beamの設定</string>
<string name="menu_key_edit_cancel">キャンセル</string>
<string name="menu_encrypt_to">暗号化...</string>
+ <string name="menu_select_all">すべて選択</string>
<!--label-->
<string name="label_sign">署名</string>
<string name="label_message">メッセージ</string>
@@ -104,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">ハッシュアルゴリズム</string>
<string name="label_asymmetric">公開鍵</string>
@@ -122,9 +125,12 @@
<string name="label_name">名前</string>
<string name="label_comment">コメント</string>
<string name="label_email">Eメールアドレス</string>
+ <string name="label_sign_user_id">署名ユーザーID</string>
+ <string name="label_sign_email">メールを署名</string>
<string name="label_send_key">証明後選択した鍵サーバに鍵をアップロード</string>
<string name="label_fingerprint">指紋</string>
<string name="select_keys_button_default">選択</string>
+ <string name="expiry_date_dialog_title">期限日時を設定</string>
<plurals name="select_keys_button">
<item quantity="other">%d を選択</item>
</plurals>
@@ -136,6 +142,7 @@
<string name="can_sign">署名可能</string>
<string name="expired">期限切れ</string>
<string name="revoked">破棄</string>
+ <string name="user_id">ユーザーID</string>
<plurals name="n_key_servers">
<item quantity="other">%d の鍵サーバ</item>
</plurals>
@@ -261,11 +268,17 @@
<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">一般エラーが発生しました、この新しいバグの情報をOpenKeychainプロジェクトに送ってください</string>
<plurals name="error_can_not_delete_info">
<item quantity="other">\'自分の鍵\'画面から削除してください!</item>
</plurals>
+ <plurals name="error_import_non_pgp_part">
+ <item quantity="other">読み込んだファイルのOpenPGPオブジェクト部分は正しいですが、OpenPGPの鍵ではありません</item>
+ </plurals>
<!--progress dialogs, usually ending in '…'-->
<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>
@@ -329,10 +342,10 @@
<string name="import_nfc_help_button">ヘルプ</string>
<string name="import_clipboard_button">クリップボードから鍵を取得</string>
<!--Intent labels-->
- <string name="intent_decrypt_file">OpenKeychain: ファイル復号化</string>
- <string name="intent_import_key">OpenKeychain: 鍵のインポート</string>
- <string name="intent_send_encrypt">OpenKeychain: 暗号化</string>
- <string name="intent_send_decrypt">OpenKeychain: 復号化</string>
+ <string name="intent_decrypt_file">OpenKeychainでファイルを復号化</string>
+ <string name="intent_import_key">OpenKeychainに鍵をインポート</string>
+ <string name="intent_send_encrypt">OpenKeychainで暗号化</string>
+ <string name="intent_send_decrypt">OpenKeychainで復号化</string>
<!--Remote API-->
<string name="api_no_apps">登録されていないアプリケーション!\n\nサードパーティアプリケーションはOpenKeychainにアクセスを要求できます。アクセスを与えた後、それらはここにリストされます。</string>
<string name="api_settings_show_advanced">拡張設定を表示</string>
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 7d7efa616..de6ba554d 100644
--- a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml
@@ -10,7 +10,6 @@
<string name="title_edit_key">Sleutel bewerken</string>
<string name="title_preferences">Instellingen</string>
<string name="title_api_registered_apps">Geregistreerde apps</string>
- <string name="title_change_pass_phrase">Wachtwoord wijzigen</string>
<string name="title_set_passphrase">Wachtwoord instellen</string>
<string name="title_send_email">E-mail verzenden...</string>
<string name="title_encrypt_to_file">Versleutelen naar bestand</string>
diff --git a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml
index 7d865cc23..22f676ccb 100644
--- a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml
@@ -13,7 +13,7 @@
<string name="title_preferences">Настройки</string>
<string name="title_api_registered_apps">Связанные приложения</string>
<string name="title_key_server_preference">Настройки сервера ключей</string>
- <string name="title_change_pass_phrase">Изменить пароль</string>
+ <string name="title_change_passphrase">Изменить пароль</string>
<string name="title_set_passphrase">Задать пароль</string>
<string name="title_send_email">Отправить...</string>
<string name="title_encrypt_to_file">Зашифровать в файл</string>
@@ -92,6 +92,7 @@
<string name="menu_beam_preferences">Настройки Beam</string>
<string name="menu_key_edit_cancel">Отмена</string>
<string name="menu_encrypt_to">Зашифровать....</string>
+ <string name="menu_select_all">Выбрать все</string>
<!--label-->
<string name="label_sign">Подписать</string>
<string name="label_message">Сообщение</string>
@@ -125,6 +126,7 @@
<string name="label_send_key">После сертификации загрузить ключ на сервер</string>
<string name="label_fingerprint">Отпечаток</string>
<string name="select_keys_button_default">Выбрать</string>
+ <string name="expiry_date_dialog_title">Срок годности</string>
<plurals name="select_keys_button">
<item quantity="one">%d выбран</item>
<item quantity="few">%d выбрано</item>
@@ -284,6 +286,7 @@
</plurals>
<!--progress dialogs, usually ending in '…'-->
<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>
diff --git a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml
index 7f1766a5c..7ccb661d3 100644
--- a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml
@@ -13,9 +13,10 @@
<string name="title_preferences">Налаштування</string>
<string name="title_api_registered_apps">Зареєстровані програми</string>
<string name="title_key_server_preference">Налаштування сервера ключів</string>
- <string name="title_change_pass_phrase">Змінити парольну фразу</string>
+ <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>
@@ -92,6 +93,7 @@
<string name="menu_beam_preferences">Налаштування променя</string>
<string name="menu_key_edit_cancel">Скасувати</string>
<string name="menu_encrypt_to">Зашифрувати…</string>
+ <string name="menu_select_all">Вибрати усе</string>
<!--label-->
<string name="label_sign">Підпис</string>
<string name="label_message">Повідомлення</string>
@@ -104,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">Хеш алгоритм</string>
<string name="label_asymmetric">Публічний ключ</string>
@@ -122,9 +125,12 @@
<string name="label_name">Назва</string>
<string name="label_comment">Коментар</string>
<string name="label_email">Ел. пошта</string>
+ <string name="label_sign_user_id">Ід підпису користувача</string>
+ <string name="label_sign_email">Підписати листа</string>
<string name="label_send_key">Завантажити ключ до вибраного сервера ключів після сертифікації</string>
<string name="label_fingerprint">Відбиток</string>
<string name="select_keys_button_default">Вибрати</string>
+ <string name="expiry_date_dialog_title">Задати термін дії</string>
<plurals name="select_keys_button">
<item quantity="one">%d вибраний</item>
<item quantity="few">%d вибрані</item>
@@ -138,6 +144,7 @@
<string name="can_sign">можна підписати</string>
<string name="expired">закінчився</string>
<string name="revoked">скасовано</string>
+ <string name="user_id">ІД користувача</string>
<plurals name="n_key_servers">
<item quantity="one">%d сервер ключів</item>
<item quantity="few">%d сервери ключів</item>
@@ -277,13 +284,21 @@
<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">Трапилася загальна помилка, будь ласка, створіть новий звіт про помилку для OpenKeychain.</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, але не ключем OpenPGP</item>
+ <item quantity="few">частини завантаженого файлу є вірним об\'єктом OpenPGP, але не ключем OpenPGP</item>
+ <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_saving">збереження…</string>
<string name="progress_importing">імпортується…</string>
<string name="progress_exporting">експортується…</string>
@@ -351,10 +366,10 @@
<string name="import_nfc_help_button">Довідка</string>
<string name="import_clipboard_button">Отримати ключ з буфера обміну</string>
<!--Intent labels-->
- <string name="intent_decrypt_file">OpenPGP: розшифрувати файл</string>
- <string name="intent_import_key">OpenPGP: імпортувати ключ</string>
- <string name="intent_send_encrypt">OpenPGP: зашифрувати</string>
- <string name="intent_send_decrypt">OpenPGP: розшифрувати</string>
+ <string name="intent_decrypt_file">Розшифрувати файл з OpenKeychain</string>
+ <string name="intent_import_key">Імпортувати ключ з OpenKeychain</string>
+ <string name="intent_send_encrypt">Зашифрувати з OpenKeychain</string>
+ <string name="intent_send_decrypt">Розшифрувати з OpenKeychain</string>
<!--Remote API-->
<string name="api_no_apps">Нема зареєстрованих програм!\n\nСтороні програми можуть вимагати доступ до OpenPGP Keychain. Після надання доступу вони будуть наведені тут.</string>
<string name="api_settings_show_advanced">Показати додаткові налаштування</string>
diff --git a/OpenPGP-Keychain/src/main/res/values-zh/strings.xml b/OpenPGP-Keychain/src/main/res/values-zh/strings.xml
index f9422b64b..80413d589 100644
--- a/OpenPGP-Keychain/src/main/res/values-zh/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values-zh/strings.xml
@@ -1,17 +1,47 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<!--title-->
+ <string name="title_select_recipients">选择公钥</string>
+ <string name="title_select_secret_key">选择私钥</string>
<string name="title_encrypt">加密</string>
<string name="title_decrypt">解密</string>
+ <string name="title_authentication">密码短语</string>
+ <string name="title_create_key">创建密钥</string>
+ <string name="title_edit_key">编辑密钥</string>
+ <string name="title_preferences">参数</string>
+ <string name="title_api_registered_apps">已注册应用</string>
<string name="title_key_server_preference">密钥服务器偏好</string>
+ <string name="title_set_passphrase">设置密码短语</string>
+ <string name="title_send_email">发送邮件</string>
+ <string name="title_encrypt_to_file">加密至文件</string>
+ <string name="title_decrypt_to_file">解密至文件</string>
+ <string name="title_import_keys">导入密钥</string>
+ <string name="title_export_key">导出密钥</string>
+ <string name="title_export_keys">导出密钥</string>
+ <string name="title_key_not_found">无法找到密钥</string>
<string name="title_key_server_query">查询密钥服务器</string>
<string name="title_send_key">上传到密钥服务器</string>
+ <string name="title_unknown_signature_key">未知签名密钥</string>
+ <string name="title_help">帮助</string>
<!--section-->
+ <string name="section_user_ids">用户ID</string>
+ <string name="section_keys">密钥</string>
+ <string name="section_general">常规</string>
+ <string name="section_defaults">缺省</string>
+ <string name="section_advanced">高级</string>
<string name="section_master_key">主密钥</string>
<string name="section_key_server">密钥服务器</string>
<string name="section_decrypt_verify">解密并验证</string>
<!--button-->
+ <string name="btn_sign">签名</string>
+ <string name="btn_decrypt">解密</string>
<string name="btn_decrypt_verify">解密并验证</string>
+ <string name="btn_select_encrypt_keys">选择收件人</string>
+ <string name="btn_encrypt_file">加密文件</string>
+ <string name="btn_save">保存</string>
+ <string name="btn_do_not_save">取消</string>
+ <string name="btn_delete">删除</string>
+ <string name="btn_no_date">无</string>
<string name="btn_clipboard">剪贴板</string>
<!--menu-->
<string name="menu_help">帮助</string>
diff --git a/OpenPGP-Keychain/src/main/res/values/arrays.xml b/OpenPGP-Keychain/src/main/res/values/arrays.xml
index 974239110..5244de419 100644
--- a/OpenPGP-Keychain/src/main/res/values/arrays.xml
+++ b/OpenPGP-Keychain/src/main/res/values/arrays.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string-array name="pass_phrase_cache_ttl_entries" translatable="false">
+ <string-array name="passphrase_cache_ttl_entries" translatable="false">
<item>@string/choice_15secs</item>
<item>@string/choice_1min</item>
<item>@string/choice_3mins</item>
@@ -15,7 +15,7 @@
<item>@string/choice_8hours</item>
<item>@string/choice_forever</item>
</string-array>
- <string-array name="pass_phrase_cache_ttl_values" translatable="false">
+ <string-array name="passphrase_cache_ttl_values" translatable="false">
<item>15</item>
<item>60</item>
<item>180</item>
diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml
index 723661928..d2e02efcb 100644
--- a/OpenPGP-Keychain/src/main/res/values/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values/strings.xml
@@ -14,9 +14,10 @@
<string name="title_preferences">Preferences</string>
<string name="title_api_registered_apps">Registered Applications</string>
<string name="title_key_server_preference">Keyserver Preference</string>
- <string name="title_change_pass_phrase">Change Passphrase</string>
+ <string name="title_change_passphrase">Change Passphrase</string>
<string name="title_set_passphrase">Set Passphrase</string>
<string name="title_send_email">"Send Mail…"</string>
+ <string name="title_send_file">"Send File…"</string>
<string name="title_encrypt_to_file">Encrypt To File</string>
<string name="title_decrypt_to_file">Decrypt To File</string>
<string name="title_import_keys">Import Keys</string>
@@ -66,6 +67,8 @@
<string name="btn_clipboard">Clipboard</string>
<string name="btn_share">Share with…</string>
<string name="btn_lookup_key">Lookup key</string>
+ <string name="btn_encryption_advanced_settings_show">Show advanced settings</string>
+ <string name="btn_encryption_advanced_settings_hide">Hide advanced settings</string>
<!-- menu -->
<string name="menu_preferences">Settings</string>
@@ -96,6 +99,7 @@
<string name="menu_beam_preferences">Beam settings</string>
<string name="menu_key_edit_cancel">Cancel</string>
<string name="menu_encrypt_to">Encrypt to…</string>
+ <string name="menu_select_all">Select all</string>
<!-- label -->
<string name="label_sign">Sign</string>
@@ -109,6 +113,7 @@
<string name="label_select_public_keys">Recipients</string>
<string name="label_delete_after_encryption">Delete After Encryption</string>
<string name="label_delete_after_decryption">Delete After Decryption</string>
+ <string name="label_share_after_encryption">Share After Encryption</string>
<string name="label_encryption_algorithm">Encryption Algorithm</string>
<string name="label_hash_algorithm">Hash Algorithm</string>
<string name="label_asymmetric">Public Key</string>
@@ -127,9 +132,12 @@
<string name="label_name">Name</string>
<string name="label_comment">Comment</string>
<string name="label_email">Email</string>
+ <string name="label_sign_user_id">Sign User Id</string>
+ <string name="label_sign_email">Sign email</string>
<string name="label_send_key">Upload key to selected keyserver after certification</string>
<string name="label_fingerprint">Fingerprint</string>
<string name="select_keys_button_default">Select</string>
+ <string name="expiry_date_dialog_title">Set expiry date</string>
<plurals name="select_keys_button">
<item quantity="one">%d selected</item>
@@ -139,11 +147,13 @@
<string name="user_id_no_name">&lt;no name&gt;</string>
<string name="none">&lt;none&gt;</string>
<string name="no_key">&lt;no key&gt;</string>
+ <string name="no_email">&lt;No Email&gt;</string>
<string name="unknown_status"></string>
<string name="can_encrypt">can encrypt</string>
<string name="can_sign">can sign</string>
<string name="expired">expired</string>
<string name="revoked">revoked</string>
+ <string name="user_id">User ID</string>
<plurals name="n_contacts">
<item quantity="one">1 contact</item>
@@ -269,6 +279,7 @@
<string name="error_master_key_must_not_be_el_gamal">the master key cannot be an ElGamal key</string>
<string name="error_unknown_algorithm_choice">unknown algorithm choice</string>
<string name="error_user_id_needs_a_name">you need to specify a name</string>
+ <string name="error_user_id_no_email">no email found</string>
<string name="error_user_id_needs_an_email_address">you need to specify an email address</string>
<string name="error_key_needs_a_user_id">need at least one user id</string>
<string name="error_main_user_id_must_not_be_empty">main user id must not be empty</string>
@@ -294,10 +305,16 @@
<string name="error_keyserver_insufficient_query">Insufficient server query</string>
<string name="error_keyserver_query">Querying keyserver failed</string>
<string name="error_keyserver_too_many_responses">Too many responses</string>
+ <string name="error_import_file_no_content">File has no content</string>
+ <string name="error_generic_report_bug">A generic error occurred, please create a new bug report for OpenKeychain.</string>
<plurals name="error_can_not_delete_info">
<item quantity="one">Please delete it from the \'My Keys\' screen!</item>
<item quantity="other">Please delete them from the \'My Keys\' screen!</item>
</plurals>
+ <plurals name="error_import_non_pgp_part">
+ <item quantity="one">part of the loaded file is a valid OpenPGP object but not a OpenPGP key</item>
+ <item quantity="other">parts of the loaded file are valid OpenPGP objects but not OpenPGP keys</item>
+ </plurals>
<!-- progress dialogs, usually ending in '…' -->
<string name="progress_done">done.</string>
@@ -305,7 +322,6 @@
<string name="progress_saving">saving…</string>
<string name="progress_importing">importing…</string>
<string name="progress_exporting">exporting…</string>
- <string name="progress_generating">generating key, this can take up to 3 minutes…</string>
<string name="progress_building_key">building key…</string>
<string name="progress_preparing_master_key">preparing master key…</string>
<string name="progress_certifying_master_key">certifying master key…</string>
@@ -318,6 +334,11 @@
<item quantity="other">exporting keys…</item>
</plurals>
+ <plurals name="progress_generating">
+ <item quantity="one">generating key, this can take up to 3 minutes…</item>
+ <item quantity="other">generating keys, this can take up to 3 minutes…</item>
+ </plurals>
+
<string name="progress_extracting_signature_key">extracting signature key…</string>
<string name="progress_extracting_key">extracting key…</string>
<string name="progress_preparing_streams">preparing streams…</string>
diff --git a/OpenPGP-Keychain/src/main/res/xml/preferences.xml b/OpenPGP-Keychain/src/main/res/xml/adv_preferences.xml
index f5b46c232..2705bd22f 100644
--- a/OpenPGP-Keychain/src/main/res/xml/preferences.xml
+++ b/OpenPGP-Keychain/src/main/res/xml/adv_preferences.xml
@@ -15,21 +15,7 @@
limitations under the License.
-->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
-
- <PreferenceCategory android:title="@string/section_general" >
- <org.sufficientlysecure.keychain.ui.widget.IntegerListPreference
- android:entries="@array/pass_phrase_cache_ttl_entries"
- android:entryValues="@array/pass_phrase_cache_ttl_values"
- android:key="passPhraseCacheTtl"
- android:persistent="false"
- android:title="@string/label_passphrase_cache_ttl" />
-
- <PreferenceScreen
- android:key="keyServers"
- android:persistent="false"
- android:title="@string/label_key_servers" />
- </PreferenceCategory>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/section_defaults" >
<org.sufficientlysecure.keychain.ui.widget.IntegerListPreference
android:key="defaultEncryptionAlgorithm"
@@ -59,5 +45,4 @@
android:persistent="false"
android:title="@string/label_force_v3_signature" />
</PreferenceCategory>
-
</PreferenceScreen> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/xml/gen_preferences.xml b/OpenPGP-Keychain/src/main/res/xml/gen_preferences.xml
new file mode 100644
index 000000000..9f1883df0
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/xml/gen_preferences.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ <PreferenceCategory android:title="@string/section_general" >
+ <org.sufficientlysecure.keychain.ui.widget.IntegerListPreference
+ android:entries="@array/passphrase_cache_ttl_entries"
+ android:entryValues="@array/passphrase_cache_ttl_values"
+ android:key="passphraseCacheTtl"
+ android:persistent="false"
+ android:title="@string/label_passphrase_cache_ttl" />
+
+ <PreferenceScreen
+ android:key="keyServers"
+ android:persistent="false"
+ android:title="@string/label_key_servers" />
+ </PreferenceCategory>
+</PreferenceScreen> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/xml/preference_headers.xml b/OpenPGP-Keychain/src/main/res/xml/preference_headers.xml
new file mode 100644
index 000000000..3506ba322
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/xml/preference_headers.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
+ <header
+ android:fragment="org.sufficientlysecure.keychain.ui.PreferencesActivity$GeneralPrefsFragment"
+ android:title="@string/section_general" />
+ <header
+ android:fragment="org.sufficientlysecure.keychain.ui.PreferencesActivity$AdvancedPrefsFragment"
+ android:title="@string/section_advanced" />
+</preference-headers> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/xml/preference_headers_legacy.xml b/OpenPGP-Keychain/src/main/res/xml/preference_headers_legacy.xml
new file mode 100644
index 000000000..141bf93e5
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/xml/preference_headers_legacy.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ <Preference
+ android:title="@string/section_general" >
+ <intent
+ android:action="org.sufficientlysecure.keychain.ui.PREFS_GEN" />
+ </Preference>
+ <Preference
+ android:title="@string/section_advanced" >
+ <intent
+ android:action="org.sufficientlysecure.keychain.ui.PREFS_ADV" />
+ </Preference>
+</PreferenceScreen> \ No newline at end of file
diff --git a/README.md b/README.md
index ba13e901b..4b997c59f 100644
--- a/README.md
+++ b/README.md
@@ -32,9 +32,9 @@ Development mailinglist at http://groups.google.com/d/forum/openpgp-keychain-dev
1. Have Android SDK "tools", "platform-tools", and "build-tools" directories in your PATH (http://developer.android.com/sdk/index.html)
2. Open the Android SDK Manager (shell command: ``android``).
-Expand the Tools directory and select "Android SDK Build-tools" newest version.
+Expand the Tools directory and select "Android SDK Build-tools (Version 19.0.3)".
Expand the Extras directory and install "Android Support Repository"
-Select everything for the newest SDK
+Select everything for the newest SDK (API-Level 19)
3. Export ANDROID_HOME pointing to your Android SDK
4. Execute ``./gradlew build``
5. You can install the app with ``adb install -r OpenPGP-Keychain/build/apk/OpenPGP-Keychain-debug-unaligned.apk``
@@ -116,6 +116,15 @@ When changing build files or dependencies, respect the following requirements:
* No dependencies from Maven (also a soft requirement for inclusion in [F-Droid](https://f-droid.org))
* Always use a fixed Android Gradle plugin version not a dynamic one, e.g. ``0.7.3`` instead of ``0.7.+`` (allows offline builds without lookups for new versions, also some minor Android plugin versions had serious issues, i.e. [0.7.2 and 0.8.1](http://tools.android.com/tech-docs/new-build-system))
* Commit the corresponding [Gradle wrapper](http://www.gradle.org/docs/current/userguide/gradle_wrapper.html) to the repository (allows easy building for new contributors without the need to install the required Gradle version using a package manager)
+* In order to update the build system to a newer gradle version you need to:
+ * Update every build.gradle file with the new gradle version and/or gradle plugin version
+ * build.gradle
+ * OpenPGP-Keychain/build.gradle
+ * OpenPGP-Keychain-API/build.gradle
+ * OpenPGP-Keychain-API/example-app/build.gradle
+ * OpenPGP-Keychain-API/libraries/keychain-api-library/build.gradle
+ * run ./gradlew wrapper twice to update gradle and download the new jar file
+ * commit the new jar and property files
### Translations
@@ -146,6 +155,14 @@ See http://source.android.com/source/code-style.html
See http://www.androidpolice.com/2009/11/04/auto-formatting-android-xml-files-with-eclipse/
+### Automated syntax check with CheckStyle
+* Paste the tools/checkstyle.xml file to ~/.AndroidStudioPreview/config/codestyles/ (in Linux/Unix)
+ or ~/Library/Preferences/AndroidStudioPreview/codestyles (in Mac OSX)
+* Go to Settings (or Preferences in Mac OS X) > Code Style > Java, select OpenPgpChecker,
+ as well as Code Style > XML and select OpenPgpChecker again.
+* Start code inspection and see the results by selecting Analyze > Inspect Code from Android-Studio
+ or you can directly run checkstyle via cli with .tools/checkstyle. Make sure it's executable first.
+
## Licenses
OpenPGP Kechain is licensed under GPLv3+.
Some parts (older parts and some libraries are Apache License v2, MIT X11 License)
diff --git a/build.gradle b/build.gradle
index 86c40fa3a..25651cd5a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,7 +4,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:0.8.3'
+ classpath 'com.android.tools.build:gradle:0.9.0'
}
}
@@ -16,4 +16,4 @@ allprojects {
task wrapper(type: Wrapper) {
gradleVersion = '1.10'
-} \ No newline at end of file
+}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 9559bfd8b..d8e0b5b29 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sun Feb 09 18:34:27 CET 2014
+#Thu Mar 06 22:23:44 CET 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip
diff --git a/libraries/Android-AppMsg/library/build.gradle b/libraries/Android-AppMsg/library/build.gradle
index 934cf1cb1..f77f1a098 100644
--- a/libraries/Android-AppMsg/library/build.gradle
+++ b/libraries/Android-AppMsg/library/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'android-library'
android {
compileSdkVersion 19
- buildToolsVersion '19.0.1'
+ buildToolsVersion '19.0.3'
defaultConfig {
minSdkVersion 4
diff --git a/libraries/AndroidBootstrap/build.gradle b/libraries/AndroidBootstrap/build.gradle
index 7724c6d9c..220613132 100644
--- a/libraries/AndroidBootstrap/build.gradle
+++ b/libraries/AndroidBootstrap/build.gradle
@@ -2,10 +2,10 @@ apply plugin: 'android-library'
android {
compileSdkVersion 19
- buildToolsVersion "19.0.1"
+ buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 7
- targetSdkVersion 17
+ targetSdkVersion 19
}
sourceSets {
main {
diff --git a/libraries/HtmlTextView/build.gradle b/libraries/HtmlTextView/build.gradle
index a0b9b1bc6..d1b26d2bd 100644
--- a/libraries/HtmlTextView/build.gradle
+++ b/libraries/HtmlTextView/build.gradle
@@ -2,8 +2,8 @@ apply plugin: 'android-library'
android {
- compileSdkVersion 17
- buildToolsVersion '19.0.1'
+ compileSdkVersion 19
+ buildToolsVersion '19.0.3'
sourceSets {
main {
diff --git a/libraries/HtmlTextView/project.properties b/libraries/HtmlTextView/project.properties
index 484dab075..91d2b0246 100644
--- a/libraries/HtmlTextView/project.properties
+++ b/libraries/HtmlTextView/project.properties
@@ -11,5 +11,5 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
-target=android-17
+target=android-19
android.library=true
diff --git a/libraries/StickyListHeaders/library/build.gradle b/libraries/StickyListHeaders/library/build.gradle
index a92c4d80e..b67172c12 100644
--- a/libraries/StickyListHeaders/library/build.gradle
+++ b/libraries/StickyListHeaders/library/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'android-library'
android {
compileSdkVersion 19
- buildToolsVersion '19.0.1'
+ buildToolsVersion '19.0.3'
sourceSets {
main {
diff --git a/libraries/zxing-android-integration/build.gradle b/libraries/zxing-android-integration/build.gradle
index a92c4d80e..b67172c12 100644
--- a/libraries/zxing-android-integration/build.gradle
+++ b/libraries/zxing-android-integration/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'android-library'
android {
compileSdkVersion 19
- buildToolsVersion '19.0.1'
+ buildToolsVersion '19.0.3'
sourceSets {
main {
diff --git a/libraries/zxing/build.gradle b/libraries/zxing/build.gradle
index a92c4d80e..b67172c12 100644
--- a/libraries/zxing/build.gradle
+++ b/libraries/zxing/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'android-library'
android {
compileSdkVersion 19
- buildToolsVersion '19.0.1'
+ buildToolsVersion '19.0.3'
sourceSets {
main {
diff --git a/settings.gradle b/settings.gradle
index 1ebb30ec0..f6ba5c517 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,5 +1,6 @@
include ':OpenPGP-Keychain'
-include ':OpenPGP-Keychain-API:libraries:keychain-api-library'
+include ':OpenPGP-Keychain-API:libraries:openpgp-api-library'
+include ':OpenPGP-Keychain-API:libraries:openkeychain-api-library'
include ':libraries:HtmlTextView'
include ':libraries:StickyListHeaders:library'
include ':libraries:AndroidBootstrap'
diff --git a/tools/checkstyle b/tools/checkstyle
new file mode 100755
index 000000000..27aabced2
--- /dev/null
+++ b/tools/checkstyle
@@ -0,0 +1 @@
+checkstyle -c tools/checkstyle.xml -r OpenPGP-Keychain/src/main/java 2>&1 | egrep -v 'log4j'
diff --git a/tools/checkstyle.xml b/tools/checkstyle.xml
new file mode 100644
index 000000000..95ef07a90
--- /dev/null
+++ b/tools/checkstyle.xml
@@ -0,0 +1,356 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC
+ "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+ "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!-- This is a checkstyle configuration file. For descriptions of
+what the following rules do, please see the checkstyle configuration
+page at http://checkstyle.sourceforge.net/config.html -->
+
+<module name="OpenPgpChecker">
+
+ <module name="SuppressionFilter">
+ <property name="file" value="tools/suppressions.xml"/>
+ </module>
+
+ <module name="RegexpSingleline">
+ <!-- Requires a copyright notice in each file.
+ Code intended to be open-sourced may have a multi-line copyright
+ notice, so that this required text appears on the second line:
+ <pre>
+ /*
+ * Copyright 2008 Google Inc.
+ *
+ * (details of open-source license...)
+ </pre>
+ -->
+ <property name="format"
+ value="^(//| \*) Copyright (\([cC]\) )?[\d]{4}(\-[\d]{4})? .*$"/>
+ <property name="minimum" value="1"/>
+ <property name="maximum" value="10"/>
+ <property name="message" value="Copyright is missing or malformed."/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="FileTabCharacter">
+ <!-- Checks that there are no tab characters in the file.
+ -->
+ </module>
+
+ <module name="NewlineAtEndOfFile">
+ <property name="lineSeparator" value="lf"/>
+ </module>
+
+ <module name="RegexpSingleline">
+ <!-- Checks that FIXME is not used in comments. TODO is preferred.
+ -->
+ <property name="format" value="((//.*)|(\*.*))FIXME"/>
+ <property name="message" value='TODO is preferred to FIXME. e.g. "TODO(johndoe): Refactor when v2 is released."'/>
+ </module>
+
+ <!--
+ <module name="RegexpSingleline">
+ <property name="format" value="((//.*)|(\*.*))TODO[^(]"/>
+ <property name="message" value='All TODOs should be named. e.g. "TODO(johndoe): Refactor when v2 is released."'/>
+ </module>
+ -->
+
+ <!-- All Java AST specific tests live under TreeWalker module. -->
+ <module name="TreeWalker">
+
+ <!--
+
+ IMPORT CHECKS
+
+ -->
+
+ <module name="RedundantImport">
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="UnusedImports">
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="ImportOrder">
+ <!-- Checks for out of order import statements. -->
+
+ <property name="severity" value="warning"/>
+ <property name="groups" value="com.google,android,junit,com,net,org,se,java,javax"/>
+ <!-- This ensures that static imports go first. -->
+ <property name="option" value="top"/>
+ <property name="tokens" value="STATIC_IMPORT, IMPORT"/>
+ </module>
+
+ <!--
+
+ JAVADOC CHECKS
+
+ -->
+
+ <!-- Checks for Javadoc comments. -->
+ <!-- See http://checkstyle.sf.net/config_javadoc.html -->
+ <!--
+ <module name="JavadocMethod">
+ <property name="scope" value="protected"/>
+ <property name="severity" value="warning"/>
+ <property name="allowMissingJavadoc" value="true"/>
+ <property name="allowMissingParamTags" value="true"/>
+ <property name="allowMissingReturnTag" value="true"/>
+ <property name="allowMissingThrowsTags" value="true"/>
+ <property name="allowThrowsTagsForSubclasses" value="true"/>
+ <property name="allowUndeclaredRTE" value="true"/>
+ </module>
+
+ <module name="JavadocType">
+ <property name="scope" value="protected"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="JavadocStyle">
+ <property name="severity" value="warning"/>
+ </module>
+ -->
+
+ <!--
+
+ NAMING CHECKS
+
+ -->
+
+ <!-- Item 38 - Adhere to generally accepted naming conventions -->
+
+ <module name="PackageName">
+ <!-- Validates identifiers for package names against the
+ supplied expression. -->
+ <!-- Here the default checkstyle rule restricts package name parts to
+ seven characters, this is not in line with common practice at Google.
+ -->
+ <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/>
+ <property name="severity" value="warning"/>
+ </module>
+
+ <module name="TypeNameCheck">
+ <!-- Validates static, final fields against the
+ expression "^[A-Z][a-zA-Z0-9]*$". -->
+ <metadata name="altname" value="TypeName"/>
+ <property name="severity" value="warning"/>
+ </module>
+
+ <module name="ConstantNameCheck">
+ <!-- Validates non-private, static, final fields against the supplied
+ public/package final fields "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". -->
+ <metadata name="altname" value="ConstantName"/>
+ <property name="applyToPublic" value="true"/>
+ <property name="applyToProtected" value="true"/>
+ <property name="applyToPackage" value="true"/>
+ <property name="applyToPrivate" value="false"/>
+ <property name="format" value="^([A-Z_][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$"/>
+ <message key="name.invalidPattern"
+ value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/>
+ <property name="severity" value="warning"/>
+ </module>
+
+ <module name="StaticVariableNameCheck">
+ <!-- Validates static, non-final fields against the supplied
+ expression "^[a-z][a-zA-Z0-9]*_?$". -->
+ <metadata name="altname" value="StaticVariableName"/>
+ <property name="applyToPublic" value="true"/>
+ <property name="applyToProtected" value="true"/>
+ <property name="applyToPackage" value="true"/>
+ <property name="applyToPrivate" value="true"/>
+ <property name="format" value="^s[A-Z][a-zA-Z0-9]*_?$"/>
+ <property name="severity" value="warning"/>
+ </module>
+
+ <module name="MemberNameCheck">
+ <!-- Validates non-static members against the supplied expression. -->
+ <metadata name="altname" value="MemberName"/>
+ <property name="applyToPublic" value="false"/>
+ <property name="applyToProtected" value="true"/>
+ <property name="applyToPackage" value="true"/>
+ <property name="applyToPrivate" value="true"/>
+ <property name="format" value="^m[A-Z][a-zA-Z0-9]*$"/>
+ <property name="severity" value="warning"/>
+ </module>
+
+ <module name="MemberNameCheck">
+ <!-- Validates non-static members against the supplied expression. -->
+ <metadata name="altname" value="MemberName"/>
+ <property name="applyToPublic" value="true"/>
+ <property name="applyToProtected" value="false"/>
+ <property name="applyToPackage" value="false"/>
+ <property name="applyToPrivate" value="false"/>
+ <property name="format" value="^[a-z]([^A-Z]|$)[a-zA-Z0-9]*$"/>
+ <property name="severity" value="warning"/>
+ </module>
+
+ <module name="MethodNameCheck">
+ <!-- Validates identifiers for method names. -->
+ <metadata name="altname" value="MethodName"/>
+ <property name="format" value="^[a-z]([^A-Z]|$)[a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$"/>
+ <property name="severity" value="warning"/>
+ </module>
+
+ <module name="ParameterName">
+ <!-- Validates identifiers for method parameters against the
+ expression "^[a-z][a-zA-Z0-9]*$". -->
+ <property name="severity" value="warning"/>
+ </module>
+
+ <module name="LocalFinalVariableName">
+ <!-- Validates identifiers for local final variables against the
+ expression "^[a-z][a-zA-Z0-9]*$". -->
+ <property name="severity" value="warning"/>
+ </module>
+
+ <module name="LocalVariableName">
+ <!-- Validates identifiers for local variables against the
+ expression "^[a-z][a-zA-Z0-9]*$". -->
+ <property name="severity" value="warning"/>
+ </module>
+
+
+ <!--
+
+ LENGTH and CODING CHECKS
+
+ -->
+
+ <module name="LineLength">
+ <!-- Checks if a line is too long. -->
+ <property name="max" value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.max}" default="110"/>
+ <property name="severity" value="error"/>
+
+ <!--
+ The default ignore pattern exempts the following elements:
+ - import statements
+ - long URLs inside comments
+ -->
+
+ <property name="ignorePattern"
+ value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.ignorePattern}"
+ default="^(package .*;\s*)|(import .*;\s*)|( *\* *https?://.*)$"/>
+ </module>
+
+ <module name="LeftCurly">
+ <!-- Checks for placement of the left curly brace ('{'). -->
+ <property name="severity" value="warning"/>
+ </module>
+
+ <module name="RightCurly">
+ <!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on
+ the same line. e.g., the following example is fine:
+ <pre>
+ if {
+ ...
+ } else
+ </pre>
+ -->
+ <!-- This next example is not fine:
+ <pre>
+ if {
+ ...
+ }
+ else
+ </pre>
+ -->
+ <property name="option" value="same"/>
+ <property name="severity" value="warning"/>
+ </module>
+
+ <!-- Checks for braces around if and else blocks -->
+ <module name="NeedBraces">
+ <property name="severity" value="warning"/>
+ <property name="tokens" value="LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO"/>
+ </module>
+
+ <module name="UpperEll">
+ <!-- Checks that long constants are defined with an upper ell.-->
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="FallThrough">
+ <!-- Warn about falling through to the next case statement. Similar to
+ javac -Xlint:fallthrough, but the check is suppressed if a single-line comment
+ on the last non-blank line preceding the fallen-into case contains 'fall through' (or
+ some other variants which we don't publicized to promote consistency).
+ -->
+ <property name="reliefPattern"
+ value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/>
+ <property name="severity" value="error"/>
+ </module>
+
+
+ <!--
+
+ MODIFIERS CHECKS
+
+ -->
+
+ <module name="ModifierOrder">
+ <!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and
+ 8.4.3. The prescribed order is:
+ public, protected, private, abstract, static, final, transient, volatile,
+ synchronized, native, strictfp
+ -->
+ </module>
+
+
+ <!--
+
+ WHITESPACE CHECKS
+
+ -->
+
+ <module name="WhitespaceAround">
+ <!-- Checks that various tokens are surrounded by whitespace.
+ This includes most binary operators and keywords followed
+ by regular or curly braces.
+ -->
+ <property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,
+ BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,
+ EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
+ LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
+ LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,
+ MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,
+ SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="WhitespaceAfter">
+ <!-- Checks that commas, semicolons and typecasts are followed by
+ whitespace.
+ -->
+ <property name="tokens" value="COMMA, SEMI, TYPECAST"/>
+ </module>
+
+ <module name="NoWhitespaceAfter">
+ <!-- Checks that there is no whitespace after various unary operators.
+ Linebreaks are allowed.
+ -->
+ <property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,
+ UNARY_PLUS"/>
+ <property name="allowLineBreaks" value="true"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="NoWhitespaceBefore">
+ <!-- Checks that there is no whitespace before various unary operators.
+ Linebreaks are allowed.
+ -->
+ <property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/>
+ <property name="allowLineBreaks" value="true"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="ParenPad">
+ <!-- Checks that there is no whitespace before close parens or after
+ open parens.
+ -->
+ <property name="severity" value="warning"/>
+ </module>
+
+ </module>
+</module>
+