diff options
140 files changed, 2329 insertions, 1087 deletions
diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..54db1a965 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: java +jdk: oraclejdk7 +before_install: + # Install base Android SDK + - sudo apt-get update -qq + - if [ `uname -m` = x86_64 ]; then sudo apt-get install -qq --force-yes libgd2-xpm ia32-libs; fi + - wget http://dl.google.com/android/android-sdk_r22.3-linux.tgz + - tar xzf android-sdk_r22.3-linux.tgz + - export ANDROID_HOME=$PWD/android-sdk-linux + - 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.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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 749229115..10f112f23 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! @@ -68,30 +69,12 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> - - <!-- <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.KeyListSecretActivity" android:configChanges="orientation|screenSize|keyboardHidden|keyboard" android:label="@string/title_manage_secret_keys" 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.EditKeyActivity" @@ -121,30 +104,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" @@ -276,7 +241,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" @@ -454,10 +428,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 --> 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..4428c7133 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -51,7 +51,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/ExportHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java index 21676a2a7..8f2c6c83d 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 @@ -160,7 +160,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/pgp/PgpConversionHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java index 20d446824..a30e0718f 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 @@ -76,7 +76,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) { @@ -125,7 +125,7 @@ public class PgpConversionHelper { /** * Convert from PGPSecretKey to byte[] * - * @param keysBytes + * @param key * @return */ public static byte[] PGPSecretKeyToBytes(PGPSecretKey key) { @@ -141,7 +141,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/PgpImportExport.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index a7a574ee7..9d9cd4d11 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; @@ -90,8 +84,8 @@ public class PgpImportExport { 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) { 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..e1ca88fb0 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); 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 781f36758..3b60ffc87 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 @@ -304,7 +304,7 @@ public class KeychainProvider extends ContentProvider { /** * Returns type of the query (secret/public) * - * @param uri + * @param match * @return */ private int getKeyType(int match) { @@ -862,7 +862,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 9bee42973..68d9f801b 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 @@ -23,8 +23,6 @@ import java.util.ArrayList; import java.util.Date; import org.spongycastle.bcpg.ArmoredOutputStream; -import org.spongycastle.bcpg.UserAttributePacket; -import org.spongycastle.bcpg.UserAttributeSubpacket; import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKeyRing; @@ -628,7 +626,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 3904a91d8..313655766 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,6 +44,7 @@ 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; @@ -181,13 +182,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"; @@ -203,8 +198,16 @@ public class KeychainIntentService extends IntentService implements ProgressDial Messenger mMessenger; + private boolean mIsCanceled; + public KeychainIntentService() { - super("ApgService"); + super("KeychainIntentService"); + } + + @Override + public void onDestroy() { + super.onDestroy(); + this.mIsCanceled = true; } /** @@ -481,15 +484,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) { @@ -743,7 +748,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 { @@ -815,6 +820,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial } private void sendErrorToHandler(Exception e) { + // Service was canceled. Do not send error to handler. + if (this.mIsCanceled) + return; + Log.e(Constants.TAG, "ApgService Exception: ", e); e.printStackTrace(); @@ -824,6 +833,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial } private void sendMessageToHandler(Integer arg1, Integer arg2, Bundle data) { + // Service was canceled. Do not send message to handler. + if (this.mIsCanceled) + return; + Message msg = Message.obtain(); msg.arg1 = arg1; if (arg2 != null) { @@ -851,10 +864,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 dfea7eb04..65c756f9a 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,6 +21,7 @@ import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; import org.sufficientlysecure.keychain.R; import android.app.Activity; +import android.content.DialogInterface.OnCancelListener; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -55,9 +56,15 @@ public class KeychainIntentServiceHandler extends Handler { } public KeychainIntentServiceHandler(Activity activity, int progressDialogMessageId, int progressDialogStyle) { + this(activity, progressDialogMessageId, progressDialogStyle, false, null); + } + + public KeychainIntentServiceHandler(Activity activity, int progressDialogMessageId, + int progressDialogStyle, boolean cancelable, + OnCancelListener onCancelListener) { this.mActivity = activity; this.mProgressDialogFragment = ProgressDialogFragment.newInstance(progressDialogMessageId, - progressDialogStyle); + progressDialogStyle, cancelable, onCancelListener); } public void showProgressDialog(FragmentActivity activity) { 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/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index aab6b81d9..9a56d768e 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 @@ -249,7 +249,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements finish(); } } - }; + } }; // Create a new Messenger for the communication back @@ -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..c111ed33b 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; @@ -690,11 +692,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 +713,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/DrawerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java index 53a57c4cd..08ca262c3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity; +import org.sufficientlysecure.keychain.util.Log; import android.app.Activity; import android.content.Context; @@ -52,6 +53,7 @@ public class DrawerActivity extends ActionBarActivity { private static Class[] mItemsClass = new Class[] { KeyListPublicActivity.class, EncryptActivity.class, DecryptActivity.class, ImportKeysActivity.class, KeyListSecretActivity.class, RegisteredAppsListActivity.class }; + private Class mSelectedItem; private static final int MENU_ID_PREFERENCE = 222; private static final int MENU_ID_HELP = 223; @@ -94,6 +96,17 @@ public class DrawerActivity extends ActionBarActivity { getSupportActionBar().setTitle(mTitle); // creates call to onPrepareOptionsMenu() supportInvalidateOptionsMenu(); + + // call intent activity if selected + if(mSelectedItem != null) { + finish(); + overridePendingTransition(0, 0); + + Intent intent = new Intent(DrawerActivity.this, mSelectedItem); + startActivity(intent); + // disable animation of activity start + overridePendingTransition(0, 0); + } } public void onDrawerOpened(View drawerView) { @@ -182,14 +195,8 @@ public class DrawerActivity extends ActionBarActivity { mDrawerList.setItemChecked(position, true); // setTitle(mDrawerTitles[position]); mDrawerLayout.closeDrawer(mDrawerList); - - finish(); - overridePendingTransition(0, 0); - - Intent intent = new Intent(this, mItemsClass[position]); - startActivity(intent); - // disable animation of activity start - overridePendingTransition(0, 0); + // set selected class + mSelectedItem = mItemsClass[position]; } /** 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 73426e32d..898b0e67a 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 @@ -44,8 +44,10 @@ import org.sufficientlysecure.keychain.ui.widget.UserIdEditor; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; +import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -90,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; @@ -148,7 +150,7 @@ public class EditKeyActivity extends ActionBarActivity { Bundle extras = intent.getExtras(); - mCurrentPassPhrase = ""; + mCurrentPassphrase = ""; if (extras != null) { // if userId is given, prefill the fields @@ -163,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); } } @@ -173,19 +175,31 @@ public class EditKeyActivity extends ActionBarActivity { if (generateDefaultKeys) { // Send all information needed to service generate keys in other thread - Intent serviceIntent = new Intent(this, KeychainIntentService.class); + final Intent serviceIntent = new Intent(this, KeychainIntentService.class); serviceIntent.setAction(KeychainIntentService.ACTION_GENERATE_DEFAULT_RSA_KEYS); // 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) { + this, R.string.progress_generating, ProgressDialog.STYLE_SPINNER, true, + + new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + // Stop key generation on cancel + stopService(serviceIntent); + EditKeyActivity.this.setResult(Activity.RESULT_CANCELED); + EditKeyActivity.this.finish(); + } + }) { + + @Override public void handleMessage(Message message) { // handle messages by standard ApgHandler first super.handleMessage(message); @@ -210,7 +224,7 @@ public class EditKeyActivity extends ActionBarActivity { buildLayout(); } - }; + } }; // Create a new Messenger for the communication back @@ -267,9 +281,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(); } } @@ -359,14 +373,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); } } @@ -396,7 +410,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; } @@ -415,7 +429,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 @@ -435,7 +449,7 @@ public class EditKeyActivity extends ActionBarActivity { updatePassPhraseButtonText(); - mChangePassPhrase.setOnClickListener(new OnClickListener() { + mChangePassphrase.setOnClickListener(new OnClickListener() { public void onClick(View v) { showSetPassphraseDialog(); } @@ -450,10 +464,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); } } }); @@ -492,7 +506,7 @@ public class EditKeyActivity extends ActionBarActivity { if (passphrase == null) { showPassphraseDialog(masterKeyId, masterCanSign); } else { - mCurrentPassPhrase = passphrase; + mCurrentPassphrase = passphrase; finallySaveClicked(); } } catch (PgpGeneralException e) { @@ -511,7 +525,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)); @@ -547,7 +561,7 @@ public class EditKeyActivity extends ActionBarActivity { setResult(RESULT_OK, data); finish(); } - }; + } }; // Create a new Messenger for the communication back @@ -682,7 +696,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..b486fc151 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 @@ -101,13 +101,14 @@ 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; @@ -436,14 +437,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 +551,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; @@ -650,6 +651,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 +669,6 @@ public class EncryptActivity extends DrawerActivity { } } } - - ; }; // Create a new Messenger for the communication back @@ -766,8 +774,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. @@ -809,6 +817,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/KeyListPublicFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java index c28d57627..f14fadd77 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java @@ -33,6 +33,7 @@ import se.emilsjolander.stickylistheaders.ApiLevelTooLowException; import se.emilsjolander.stickylistheaders.StickyListHeadersListView; import android.annotation.SuppressLint; +import android.annotation.TargetApi; import android.content.Intent; import android.database.Cursor; import android.net.Uri; @@ -45,13 +46,18 @@ 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.support.v4.view.MenuItemCompat; +import android.support.v7.widget.SearchView; +import android.text.TextUtils; 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.ListView; @@ -63,24 +69,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 KeyListPublicFragment extends Fragment implements AdapterView.OnItemClickListener, +public class KeyListPublicFragment extends Fragment implements SearchView.OnQueryTextListener, AdapterView.OnItemClickListener, LoaderManager.LoaderCallbacks<Cursor> { private KeyListPublicAdapter 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_public_fragment, container, false); + View root = inflater.inflate(R.layout.key_list_public_fragment, container, false); + + mStickyList = (StickyListHeadersListView) root.findViewById(R.id.key_list_public_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 @@ -92,8 +111,7 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte 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 @@ -104,7 +122,12 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte } }); - return view; + // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097 + mListContainer = root.findViewById(R.id.key_list_public_list_container); + mProgressContainer = root.findViewById(R.id.key_list_public_progress_container); + mListShown = true; + + return root; } /** @@ -115,9 +138,6 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - mStickyList = (StickyListHeadersListView) getActivity().findViewById(R.id.list); - - mStickyList.setOnItemClickListener(this); mStickyList.setAreHeadersSticky(true); mStickyList.setDrawingListUnderStickyHeader(false); mStickyList.setFastScrollEnabled(true); @@ -127,7 +147,7 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte } // 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_public_empty)); /* * ActionBarSherlock does not support MultiChoiceModeListener. Thus multi-selection is only @@ -137,8 +157,6 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte 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(); @@ -172,13 +190,20 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte showDeleteKeyDialog(mode, ids); break; } + case R.id.menu_key_list_public_multi_select_all: { + //Select all + int localCount = mStickyList.getCount(); + for (int k = 0; k < localCount; k++) { + mStickyList.setItemChecked(k, true); + } + break; + } } return true; } @Override public void onDestroyActionMode(ActionMode mode) { - count = 0; mAdapter.clearSelection(); } @@ -186,13 +211,11 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte 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 = mAdapter.getCurrentCheckedPosition().size(); String keysSelected = getResources().getQuantityString( R.plurals.key_list_selected_keys, count, count); mode.setTitle(keysSelected); @@ -201,9 +224,12 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte }); } - // 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 KeyListPublicAdapter(getActivity(), null, Id.type.public_key, USER_ID_INDEX); @@ -231,10 +257,15 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte // 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.buildPublicKeyRingsUri(); - + 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 @@ -245,13 +276,13 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte 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 @@ -277,6 +308,7 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte startActivity(viewIntent); } + @TargetApi(11) public void encrypt(ActionMode mode, long[] keyRingRowIds) { // get master key ids from row ids long[] keyRingIds = new long[keyRingRowIds.length]; @@ -298,6 +330,7 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte * * @param keyRingRowIds */ + @TargetApi(11) public void showDeleteKeyDialog(final ActionMode mode, long[] keyRingRowIds) { // Message is received after key is deleted Handler returnHandler = new Handler() { @@ -332,4 +365,68 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog"); } -}
\ No newline at end of file + + @Override + public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { + // Get the searchview + MenuItem searchItem = menu.findItem(R.id.menu_key_list_public_search); + mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem); + + // Execute this when searching + mSearchView.setOnQueryTextListener(this); + + 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); + } +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java index f9d267f27..9a5477762 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java @@ -17,7 +17,6 @@ package org.sufficientlysecure.keychain.ui; -import java.util.ArrayList; import java.util.Set; import org.sufficientlysecure.keychain.Id; @@ -29,6 +28,7 @@ import org.sufficientlysecure.keychain.ui.adapter.KeyListSecretAdapter; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import android.annotation.SuppressLint; +import android.annotation.TargetApi; import android.content.Intent; import android.database.Cursor; import android.net.Uri; @@ -49,12 +49,10 @@ import android.widget.AdapterView; import android.widget.ListView; import android.widget.AbsListView.MultiChoiceModeListener; import android.widget.AdapterView.OnItemClickListener; -import android.widget.Toast; public class KeyListSecretFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener { - private KeyListSecretActivity mKeyListSecretActivity; private KeyListSecretAdapter mAdapter; /** @@ -65,8 +63,6 @@ public class KeyListSecretFragment extends ListFragment implements public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - mKeyListSecretActivity = (KeyListSecretActivity) getActivity(); - getListView().setOnItemClickListener(this); // Give some text to display if there is no data. In a real @@ -81,8 +77,6 @@ public class KeyListSecretFragment extends ListFragment implements getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); getListView().setMultiChoiceModeListener(new MultiChoiceModeListener() { - private int count = 0; - @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { android.view.MenuInflater inflater = getActivity().getMenuInflater(); @@ -112,13 +106,20 @@ public class KeyListSecretFragment extends ListFragment implements showDeleteKeyDialog(mode, ids); break; } + case R.id.menu_key_list_public_multi_select_all: { + //Select all + int localCount = getListView().getCount(); + for (int k = 0; k < localCount; k++) { + getListView().setItemChecked(k, true); + } + break; + } } return true; } @Override public void onDestroyActionMode(ActionMode mode) { - count = 0; mAdapter.clearSelection(); } @@ -126,13 +127,12 @@ public class KeyListSecretFragment extends ListFragment implements 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 = getListView().getCheckedItemCount(); String keysSelected = getResources().getQuantityString( R.plurals.key_list_selected_keys, count, count); mode.setTitle(keysSelected); @@ -148,7 +148,7 @@ public class KeyListSecretFragment extends ListFragment implements setListShown(false); // Create an empty adapter we will use to display the loaded data. - mAdapter = new KeyListSecretAdapter(mKeyListSecretActivity, null, 0); + mAdapter = new KeyListSecretAdapter(getActivity(), null, 0); setListAdapter(mAdapter); // Prepare the loader. Either re-connect with an existing one, @@ -198,7 +198,7 @@ public class KeyListSecretFragment extends ListFragment implements */ @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { - Intent editIntent = new Intent(mKeyListSecretActivity, EditKeyActivity.class); + Intent editIntent = new Intent(getActivity(), EditKeyActivity.class); editIntent.setData(KeychainContract.KeyRings.buildSecretKeyRingsUri(Long.toString(id))); editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY); startActivityForResult(editIntent, 0); @@ -209,6 +209,7 @@ public class KeyListSecretFragment extends ListFragment implements * * @param keyRingRowIds */ + @TargetApi(11) public void showDeleteKeyDialog(final ActionMode mode, long[] keyRingRowIds) { // Message is received after key is deleted Handler returnHandler = new Handler() { 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/SelectPublicKeyFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java index 59b46dd00..6e338979a 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); + 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,31 +290,21 @@ 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 @@ -250,4 +331,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/UploadKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java index 550d3047d..574d837d2 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 @@ -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 0a452bc8a..390de9ab9 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 @@ -88,12 +88,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.putParcelable(ViewKeyCertsFragment.ARG_DATA_URI, mDataUri); 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 @@ -154,7 +154,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/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java index 4a7a9c93a..01b6deeaa 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 @@ -152,9 +152,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable { // selected is default this.selected = true; - if (pgpKeyRing instanceof PGPSecretKeyRing) { - secretKey = true; - } else { + if ( !(pgpKeyRing instanceof PGPSecretKeyRing) ) { secretKey = false; } 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 7ca7bc998..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 @@ -102,7 +102,7 @@ public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper /** * Reads all PGPKeyRing objects from input * - * @param keyringBytes + * @param inputData * @return */ private void generateListOfKeyrings(InputData inputData) { @@ -115,7 +115,7 @@ public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper // 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 { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java index 257136cbd..086d2c178 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java @@ -36,7 +36,6 @@ import android.support.v4.widget.CursorAdapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.RelativeLayout; import android.widget.TextView; /** @@ -223,7 +222,7 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea */ // default color v.setBackgroundColor(Color.TRANSPARENT); - if (mSelection.get(position) != null) { + if (mSelection.get(position) != null && mSelection.get(position).booleanValue()) { // this is a selected position, change color! v.setBackgroundColor(parent.getResources().getColor(R.color.emphasis)); } 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 a859bb045..c4e305984 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 @@ -83,7 +83,7 @@ public class DeleteFileDialogFragment extends DialogFragment { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); ProgressDialogFragment deletingDialog = ProgressDialogFragment.newInstance( - R.string.progress_deleting_securely, ProgressDialog.STYLE_HORIZONTAL); + 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 +95,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 9b5d233e8..6c62d14e0 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 @@ -21,28 +21,40 @@ import android.app.Activity; import android.app.Dialog; import android.app.ProgressDialog; import android.content.DialogInterface; +import android.content.DialogInterface.OnCancelListener; import android.content.DialogInterface.OnKeyListener; import android.os.Bundle; import android.support.v4.app.DialogFragment; 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_STYLE = "style"; + private static final String ARG_CANCELABLE = "cancelable"; + + private OnCancelListener mOnCancelListener; /** * Creates new instance of this fragment * - * @param id + * @param messageId + * @param style + * @param cancelable * @return */ - public static ProgressDialogFragment newInstance(int messageId, int style) { + public static ProgressDialogFragment newInstance(int messageId, int style, boolean cancelable, + OnCancelListener onCancelListener) { ProgressDialogFragment frag = new ProgressDialogFragment(); Bundle args = new Bundle(); args.putInt(ARG_MESSAGE_ID, messageId); args.putInt(ARG_STYLE, style); + args.putBoolean(ARG_CANCELABLE, cancelable); frag.setArguments(args); + frag.mOnCancelListener = onCancelListener; + return frag; } @@ -60,7 +72,6 @@ public class ProgressDialogFragment extends DialogFragment { /** * Updates progress of dialog * - * @param messageId * @param progress * @param max */ @@ -74,7 +85,7 @@ public class ProgressDialogFragment extends DialogFragment { /** * Updates progress of dialog * - * @param messageId + * @param message * @param progress * @param max */ @@ -86,12 +97,20 @@ public class ProgressDialogFragment extends DialogFragment { dialog.setMax(max); } + @Override + public void onCancel(DialogInterface dialog) { + super.onCancel(dialog); + + if (this.mOnCancelListener != null) + this.mOnCancelListener.onCancel(dialog); + } + /** * Creates dialog */ @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - Activity activity = getActivity(); + final Activity activity = getActivity(); ProgressDialog dialog = new ProgressDialog(activity); dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); @@ -100,10 +119,22 @@ public class ProgressDialogFragment extends DialogFragment { int messageId = getArguments().getInt(ARG_MESSAGE_ID); int style = getArguments().getInt(ARG_STYLE); + boolean cancelable = getArguments().getBoolean(ARG_CANCELABLE); dialog.setMessage(getString(messageId)); 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(); + } + }); + } + // Disable the back button OnKeyListener keyListener = new OnKeyListener() { 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..75a885bdd 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(); } }); @@ -205,7 +226,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 +256,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 +283,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 57865b032..99622106f 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 @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui.widget; import android.app.ProgressDialog; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.os.Message; @@ -211,7 +212,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor private void createKey() { // Send all information needed to service to edit key in other thread - Intent intent = new Intent(mActivity, KeychainIntentService.class); + final Intent intent = new Intent(mActivity, KeychainIntentService.class); intent.setAction(KeychainIntentService.ACTION_GENERATE_KEY); @@ -219,18 +220,18 @@ 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); @@ -238,7 +239,12 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor // show progress dialog mGeneratingDialog = ProgressDialogFragment.newInstance(R.string.progress_generating, - ProgressDialog.STYLE_SPINNER); + 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, @@ -255,7 +261,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/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index 61fe13ffb..921d22f21 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 @@ -32,6 +34,7 @@ import java.util.List; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.Locale; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -172,11 +175,11 @@ public class HkpKeyServer extends KeyServer { if (e.getCode() == 404) { return results; } else { - if (e.getData().toLowerCase().contains("no keys found")) { + if (e.getData().toLowerCase(Locale.US).contains("no keys found")) { return results; - } else if (e.getData().toLowerCase().contains("too many")) { + } else if (e.getData().toLowerCase(Locale.US).contains("too many")) { throw new TooManyResponses(); - } else if (e.getData().toLowerCase().contains("insufficient")) { + } else if (e.getData().toLowerCase(Locale.US).contains("insufficient")) { throw new InsufficientQuery(); } } 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_search.png b/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_search.png Binary files differnew file mode 100644 index 000000000..f594b4e48 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_search.png 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 Binary files differnew file mode 100644 index 000000000..287ae2fb0 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_secure.png 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 Binary files differnew file mode 100644 index 000000000..fc0dd57b6 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/drawable-hdpi/ic_action_select_all.png 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 Binary files differnew file mode 100644 index 000000000..f6719d228 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_search.png 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 Binary files differnew file mode 100644 index 000000000..d49217234 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_secure.png 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 Binary files differnew file mode 100644 index 000000000..da37d7a6e --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/drawable-mdpi/ic_action_select_all.png 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 Binary files differnew file mode 100644 index 000000000..aad535e97 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_search.png 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 Binary files differnew file mode 100644 index 000000000..2a0898381 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_secure.png 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 Binary files differnew file mode 100644 index 000000000..af37a3680 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/drawable-xhdpi/ic_action_select_all.png 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 Binary files differnew file mode 100644 index 000000000..9c0ea3ca0 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_search.png 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 Binary files differnew file mode 100644 index 000000000..d8c094ed8 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_secure.png 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 Binary files differnew file mode 100644 index 000000000..aa5937eab --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/drawable-xxhdpi/ic_action_select_all.png diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml index c60416494..aa9d59004 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml @@ -6,7 +6,7 @@ <LinearLayout android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:padding="16dp" android:orientation="vertical"> @@ -26,4 +26,4 @@ tools:layout="@layout/api_app_settings_fragment" /> </LinearLayout> -</ScrollView>
\ No newline at end of file +</ScrollView> diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml index d4fb5103a..d83c8e87d 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml @@ -6,7 +6,7 @@ <LinearLayout android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:padding="16dp" android:orientation="vertical"> @@ -18,4 +18,4 @@ tools:layout="@layout/api_app_settings_fragment" /> </LinearLayout> -</ScrollView>
\ No newline at end of file +</ScrollView> 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/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/encrypt_activity.xml b/OpenPGP-Keychain/src/main/res/layout/encrypt_activity.xml index 678f2bd4e..e716b033a 100644 --- a/OpenPGP-Keychain/src/main/res/layout/encrypt_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/encrypt_activity.xml @@ -82,7 +82,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 +92,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 +135,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 +144,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 +153,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 +162,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" /> @@ -291,6 +291,19 @@ 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" 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_public_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/key_list_public_fragment.xml index f3a21e1bf..db82c8771 100644 --- a/OpenPGP-Keychain/src/main/res/layout/key_list_public_fragment.xml +++ b/OpenPGP-Keychain/src/main/res/layout/key_list_public_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_public_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_public_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_public_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_public_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 diff --git a/OpenPGP-Keychain/src/main/res/layout/key_list_public_item.xml b/OpenPGP-Keychain/src/main/res/layout/key_list_public_item.xml index 9307ab2e5..f07d60214 100644 --- a/OpenPGP-Keychain/src/main/res/layout/key_list_public_item.xml +++ b/OpenPGP-Keychain/src/main/res/layout/key_list_public_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_alignParentLeft="true" android:layout_alignParentStart="true" /> diff --git a/OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml b/OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml index 1ed86f730..7d5492265 100644 --- a/OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml +++ b/OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml @@ -13,7 +13,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_preference.xml b/OpenPGP-Keychain/src/main/res/layout/key_server_preference.xml index 8b99e5d2f..4a09e4240 100644 --- a/OpenPGP-Keychain/src/main/res/layout/key_server_preference.xml +++ b/OpenPGP-Keychain/src/main/res/layout/key_server_preference.xml @@ -71,8 +71,8 @@ <LinearLayout android:id="@+id/editors" android:layout_width="fill_parent" - android:layout_height="fill_parent" + android:layout_height="wrap_content" android:orientation="vertical" /> </ScrollView> -</LinearLayout>
\ No newline at end of file +</LinearLayout> 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/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_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_public.xml b/OpenPGP-Keychain/src/main/res/menu/key_list_public.xml index cdd755dc3..35a8f3926 100644 --- a/OpenPGP-Keychain/src/main/res/menu/key_list_public.xml +++ b/OpenPGP-Keychain/src/main/res/menu/key_list_public.xml @@ -11,5 +11,10 @@ android:id="@+id/menu_key_list_public_export" app:showAsAction="never" android:title="@string/menu_export_keys" /> - + <item + android:id="@+id/menu_key_list_public_search" + android:title="@string/menu_search" + android:icon="@drawable/ic_action_search" + app:actionViewClass="android.support.v7.widget.SearchView" + app:showAsAction="ifRoom" /> </menu>
\ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/menu/key_list_public_multi.xml b/OpenPGP-Keychain/src/main/res/menu/key_list_public_multi.xml index f7b415441..d30ee5e8f 100644 --- a/OpenPGP-Keychain/src/main/res/menu/key_list_public_multi.xml +++ b/OpenPGP-Keychain/src/main/res/menu/key_list_public_multi.xml @@ -2,7 +2,12 @@ <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item + android:id="@+id/menu_key_list_public_multi_select_all" + android:icon="@drawable/ic_action_select_all" + android:title="@string/menu_select_all" /> + <item android:id="@+id/menu_key_list_public_multi_encrypt" + android:icon="@drawable/ic_action_secure" android:title="@string/menu_encrypt_to" /> <item android:id="@+id/menu_key_list_public_multi_delete" diff --git a/OpenPGP-Keychain/src/main/res/menu/key_list_secret_multi.xml b/OpenPGP-Keychain/src/main/res/menu/key_list_secret_multi.xml index 9cfab9fd3..a3375c7e8 100644 --- a/OpenPGP-Keychain/src/main/res/menu/key_list_secret_multi.xml +++ b/OpenPGP-Keychain/src/main/res/menu/key_list_secret_multi.xml @@ -2,6 +2,10 @@ <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item + android:id="@+id/menu_key_list_public_multi_select_all" + android:icon="@drawable/ic_action_select_all" + android:title="@string/menu_select_all" /> + <item android:id="@+id/menu_key_list_public_multi_delete" android:icon="@drawable/ic_action_discard" android:title="@string/menu_delete_key" /> 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/values-de/strings.xml b/OpenPGP-Keychain/src/main/res/values-de/strings.xml index 09b4fdb23..ea1e550e3 100644 --- a/OpenPGP-Keychain/src/main/res/values-de/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-de/strings.xml @@ -13,9 +13,9 @@ <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_change_passphrase">Passwort ändern</string> <string name="title_set_passphrase">Passwort setzen</string> - <string name="title_send_email">E-Mail senden...</string> + <string name="title_send_email">E-Mail senden…</string> <string name="title_encrypt_to_file">In eine Datei verschlüsseln</string> <string name="title_decrypt_to_file">In eine Datei entschlüsseln</string> <string name="title_import_keys">Schlüssel importieren</string> @@ -163,7 +163,7 @@ <string name="dsa">DSA</string> <string name="elgamal">ElGamal</string> <string name="rsa">RSA</string> - <string name="filemanager_title_open">Öffnen...</string> + <string name="filemanager_title_open">Öffnen…</string> <string name="warning">Warnung</string> <string name="error">Fehler</string> <string name="error_message">Fehler: %s</string> @@ -266,46 +266,47 @@ <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_saving">speichern...</string> - <string name="progress_importing">importieren...</string> - <string name="progress_exporting">exportieren...</string> - <string name="progress_generating">erstelle Schlüssel, dies kann bis zu 3 Minuten dauern...</string> - <string name="progress_building_key">erstelle Schlüssel...</string> - <string name="progress_preparing_master_key">Hauptschlüssel wird vorbereitet...</string> - <string name="progress_certifying_master_key">Hauptschlüssel wird beglaubigt...</string> - <string name="progress_building_master_key">erstelle Hauptring...</string> - <string name="progress_adding_sub_keys">füge Unterschlüssel hinzu...</string> - <string name="progress_saving_key_ring">Schlüssel wird gespeichert...</string> + <string name="progress_saving">speichern…</string> + <string name="progress_importing">importieren…</string> + <string name="progress_exporting">exportieren…</string> + <string name="progress_generating">erstelle Schlüssel, dies kann bis zu 3 Minuten dauern…</string> + <string name="progress_building_key">erstelle Schlüssel…</string> + <string name="progress_preparing_master_key">Hauptschlüssel wird vorbereitet…</string> + <string name="progress_certifying_master_key">Hauptschlüssel wird beglaubigt…</string> + <string name="progress_building_master_key">erstelle Hauptring…</string> + <string name="progress_adding_sub_keys">füge Unterschlüssel hinzu…</string> + <string name="progress_saving_key_ring">Schlüssel wird gespeichert…</string> <plurals name="progress_exporting_key"> <item quantity="one">Schlüssel wird exportiert…</item> <item quantity="other">Schlüssel werden exportiert…</item> </plurals> - <string name="progress_extracting_signature_key">extrahiere Signaturschlüssel...</string> - <string name="progress_extracting_key">extrahiere Schlüssel...</string> - <string name="progress_preparing_streams">Datenstrom wird vorbereitet...</string> - <string name="progress_encrypting">Daten werden verschlüsselt...</string> - <string name="progress_decrypting">Daten werden entschlüsselt...</string> - <string name="progress_preparing_signature">Signatur wird vorbereitet...</string> - <string name="progress_generating_signature">Signatur wird erstellt...</string> - <string name="progress_processing_signature">Signatur wird verarbeitet...</string> - <string name="progress_verifying_signature">Signatur wird verifiziert...</string> - <string name="progress_signing">signiere...</string> - <string name="progress_reading_data">Daten werden gelesen...</string> - <string name="progress_finding_key">Schlüssel wird gesucht...</string> - <string name="progress_decompressing_data">Daten werden entpackt...</string> - <string name="progress_verifying_integrity">Integrität wird überprüft...</string> - <string name="progress_deleting_securely">\'%s\' wird sicher gelöscht...</string> - <string name="progress_querying">Anfrage wird gestellt...</string> + <string name="progress_extracting_signature_key">extrahiere Signaturschlüssel…</string> + <string name="progress_extracting_key">extrahiere Schlüssel…</string> + <string name="progress_preparing_streams">Datenstrom wird vorbereitet…</string> + <string name="progress_encrypting">Daten werden verschlüsselt…</string> + <string name="progress_decrypting">Daten werden entschlüsselt…</string> + <string name="progress_preparing_signature">Signatur wird vorbereitet…</string> + <string name="progress_generating_signature">Signatur wird erstellt…</string> + <string name="progress_processing_signature">Signatur wird verarbeitet…</string> + <string name="progress_verifying_signature">Signatur wird verifiziert…</string> + <string name="progress_signing">signiere…</string> + <string name="progress_reading_data">Daten werden gelesen…</string> + <string name="progress_finding_key">Schlüssel wird gesucht…</string> + <string name="progress_decompressing_data">Daten werden entpackt…</string> + <string name="progress_verifying_integrity">Integrität wird überprüft…</string> + <string name="progress_deleting_securely">\'%s\' wird sicher gelöscht…</string> + <string name="progress_querying">Anfrage wird gestellt…</string> <!--action strings--> <string name="hint_public_keys">Öffentliche Schlüssel suchen</string> <string name="hint_secret_keys">Private Schlüssel suchen</string> - <string name="action_share_key_with">Teile Schlüssel über...</string> + <string name="action_share_key_with">Teile Schlüssel über…</string> <!--key bit length selections--> <string name="key_size_512">512</string> <string name="key_size_1024">1024</string> @@ -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-es-rCO/strings.xml b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml index 6efe9548d..d1f0bd75b 100644 --- a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml @@ -10,9 +10,9 @@ <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_change_passphrase">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_send_email">Enviar correo electrónico…</string> <string name="title_encrypt_to_file">Cifrar a archivo</string> <string name="title_decrypt_to_file">Descifrar a archivo</string> <string name="title_import_keys">Importar claves</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..de680337f 100644 --- a/OpenPGP-Keychain/src/main/res/values-es/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-es/strings.xml @@ -13,9 +13,9 @@ <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 la frase de contraseña</string> <string name="title_set_passphrase">Establecer frase de contraseña</string> - <string name="title_send_email">Enviar email...</string> + <string name="title_send_email">Enviar email…</string> <string name="title_encrypt_to_file">Cifrar hacia archivo</string> <string name="title_decrypt_to_file">Descifrar hacia archivo</string> <string name="title_import_keys">Importar claves</string> @@ -61,7 +61,7 @@ <string name="btn_next">Siguiente</string> <string name="btn_back">Volver</string> <string name="btn_clipboard">Portapapeles</string> - <string name="btn_share">Compartir con...</string> + <string name="btn_share">Compartir con…</string> <string name="btn_lookup_key">Buscar clave</string> <!--menu--> <string name="menu_preferences">Ajustes</string> @@ -80,10 +80,10 @@ <string name="menu_update_key">Actualizar desde servidor de claves</string> <string name="menu_export_key_to_server">Cargar al servidor de claves</string> <string name="menu_share">Compartir</string> - <string name="menu_share_title_fingerprint">Compartir la huella digital...</string> - <string name="menu_share_title">Compartir la clave completa...</string> - <string name="menu_share_default_fingerprint">con...</string> - <string name="menu_share_default">con...</string> + <string name="menu_share_title_fingerprint">Compartir la huella digital…</string> + <string name="menu_share_title">Compartir la clave completa…</string> + <string name="menu_share_default_fingerprint">con…</string> + <string name="menu_share_default">con…</string> <string name="menu_share_qr_code">con código QR</string> <string name="menu_share_qr_code_fingerprint">con código QR</string> <string name="menu_share_nfc">con NFC</string> @@ -91,7 +91,7 @@ <string name="menu_sign_key"> Clave de firma</string> <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_encrypt_to">Cifrar hacia…</string> <!--label--> <string name="label_sign">Firmar</string> <string name="label_message">Mensaje</string> @@ -163,7 +163,7 @@ <string name="dsa">DSA</string> <string name="elgamal">ElGamal</string> <string name="rsa">RSA</string> - <string name="filemanager_title_open">Abrir...</string> + <string name="filemanager_title_open">Abrir…</string> <string name="warning">Advertencia</string> <string name="error">Error</string> <string name="error_message">Error: %s</string> @@ -266,46 +266,49 @@ <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_saving">guardando...</string> - <string name="progress_importing">importando...</string> - <string name="progress_exporting">exportando...</string> - <string name="progress_generating">generando la clave, esto puede tardar más de 3 minutos...</string> - <string name="progress_building_key">construyendo la clave...</string> - <string name="progress_preparing_master_key">preparando la clave maestra...</string> - <string name="progress_certifying_master_key">certificando la clave maestra...</string> - <string name="progress_building_master_key">construyendo el anillo maestro...</string> - <string name="progress_adding_sub_keys">añadiendo las subclaves...</string> - <string name="progress_saving_key_ring">guardando claves...</string> + <string name="progress_saving">guardando…</string> + <string name="progress_importing">importando…</string> + <string name="progress_exporting">exportando…</string> + <string name="progress_generating">generando la clave, esto puede tardar más de 3 minutos…</string> + <string name="progress_building_key">construyendo la clave…</string> + <string name="progress_preparing_master_key">preparando la clave maestra…</string> + <string name="progress_certifying_master_key">certificando la clave maestra…</string> + <string name="progress_building_master_key">construyendo el anillo maestro…</string> + <string name="progress_adding_sub_keys">añadiendo las subclaves…</string> + <string name="progress_saving_key_ring">guardando claves…</string> <plurals name="progress_exporting_key"> - <item quantity="one">exportando clave...</item> - <item quantity="other">exportando claves...</item> + <item quantity="one">exportando clave…</item> + <item quantity="other">exportando claves…</item> </plurals> - <string name="progress_extracting_signature_key">extrayendo la clave de firma...</string> - <string name="progress_extracting_key">extrayendo la clave...</string> - <string name="progress_preparing_streams">preparando las transmisiones...</string> - <string name="progress_encrypting">cifrando los datos...</string> - <string name="progress_decrypting">descifrando los datos...</string> - <string name="progress_preparing_signature">preparando la firma...</string> - <string name="progress_generating_signature">generando la firma...</string> - <string name="progress_processing_signature">procesando la firma...</string> - <string name="progress_verifying_signature">verificando la firma...</string> - <string name="progress_signing">firmando...</string> - <string name="progress_reading_data">leyendo los datos...</string> - <string name="progress_finding_key">localizando la clave...</string> - <string name="progress_decompressing_data">descomprimiendo los datos...</string> - <string name="progress_verifying_integrity">verificando la integridad...</string> + <string name="progress_extracting_signature_key">extrayendo la clave de firma…</string> + <string name="progress_extracting_key">extrayendo la clave…</string> + <string name="progress_preparing_streams">preparando las transmisiones…</string> + <string name="progress_encrypting">cifrando los datos…</string> + <string name="progress_decrypting">descifrando los datos…</string> + <string name="progress_preparing_signature">preparando la firma…</string> + <string name="progress_generating_signature">generando la firma…</string> + <string name="progress_processing_signature">procesando la firma…</string> + <string name="progress_verifying_signature">verificando la firma…</string> + <string name="progress_signing">firmando…</string> + <string name="progress_reading_data">leyendo los datos…</string> + <string name="progress_finding_key">localizando la clave…</string> + <string name="progress_decompressing_data">descomprimiendo los datos…</string> + <string name="progress_verifying_integrity">verificando la integridad…</string> <string name="progress_deleting_securely">borrando \'%s\' de forma segura…</string> - <string name="progress_querying">consultando...</string> + <string name="progress_querying">consultando…</string> <!--action strings--> <string name="hint_public_keys">Buscar claves públicas</string> <string name="hint_secret_keys">Buscar claves secretas</string> - <string name="action_share_key_with">Compartir la clave con...</string> + <string name="action_share_key_with">Compartir la clave con…</string> <!--key bit length selections--> <string name="key_size_512">512</string> <string name="key_size_1024">1024</string> @@ -337,10 +340,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> @@ -371,7 +374,7 @@ <item quantity="one">1 clave seleccionada.</item> <item quantity="other">%d claves seleccionadas.</item> </plurals> - <string name="key_list_empty_text1">Aún no hay claves disponibles...</string> + <string name="key_list_empty_text1">Aún no hay claves disponibles…</string> <string name="key_list_empty_text2">Puedes empezar por</string> <string name="key_list_empty_text3">o</string> <string name="key_list_empty_button_create">crear tu propia clave</string> diff --git a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml index bf66756cf..aa9b59287 100644 --- a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml @@ -13,9 +13,9 @@ <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">Changer 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_email">Envoyer un courriel…</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> @@ -61,7 +61,7 @@ <string name="btn_next">Suivant</string> <string name="btn_back">Retour</string> <string name="btn_clipboard">Presse-papiers</string> - <string name="btn_share">Partager avec...</string> + <string name="btn_share">Partager avec…</string> <string name="btn_lookup_key">Rechercher la clef</string> <!--menu--> <string name="menu_preferences">Paramètres</string> @@ -80,10 +80,10 @@ <string name="menu_update_key">Mettre à jour depuis le serveur de clefs</string> <string name="menu_export_key_to_server">Téléverser vers le serveur de clefs</string> <string name="menu_share">Partager</string> - <string name="menu_share_title_fingerprint">Partager l\'empreinte...</string> - <string name="menu_share_title">Partager la clef entière...</string> - <string name="menu_share_default_fingerprint">avec...</string> - <string name="menu_share_default">avec...</string> + <string name="menu_share_title_fingerprint">Partager l\'empreinte…</string> + <string name="menu_share_title">Partager la clef entière…</string> + <string name="menu_share_default_fingerprint">avec…</string> + <string name="menu_share_default">avec…</string> <string name="menu_share_qr_code">par un code QR</string> <string name="menu_share_qr_code_fingerprint">par un code QR</string> <string name="menu_share_nfc">par la NFC</string> @@ -91,7 +91,7 @@ <string name="menu_sign_key">Signer la clef</string> <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_encrypt_to">Chiffrer vers…</string> <!--label--> <string name="label_sign">Signer</string> <string name="label_message">Message</string> @@ -163,7 +163,7 @@ <string name="dsa">DSA</string> <string name="elgamal">ElGamal</string> <string name="rsa">RSA</string> - <string name="filemanager_title_open">Ouvrir...</string> + <string name="filemanager_title_open">Ouvrir…</string> <string name="warning">Avertissement</string> <string name="error">Erreur</string> <string name="error_message">Erreur : %s</string> @@ -275,40 +275,40 @@ </plurals> <!--progress dialogs, usually ending in '…'--> <string name="progress_done">fait.</string> - <string name="progress_saving">sauvegarde...</string> - <string name="progress_importing">importation...</string> - <string name="progress_exporting">exportation...</string> - <string name="progress_generating">génération de la clef, ceci peut prendre jusqu\'à 3 minutes...</string> - <string name="progress_building_key">assemblage de la clef...</string> - <string name="progress_preparing_master_key">préparation de la clef maîtresse...</string> - <string name="progress_certifying_master_key">certification de la clef maîtresse...</string> - <string name="progress_building_master_key">assemblage du trousseau maître...</string> - <string name="progress_adding_sub_keys">ajout des sous-clefs...</string> - <string name="progress_saving_key_ring">sauvegarde de la clef...</string> + <string name="progress_saving">sauvegarde…</string> + <string name="progress_importing">importation…</string> + <string name="progress_exporting">exportation…</string> + <string name="progress_generating">génération de la clef, ceci peut prendre jusqu\'à 3 minutes…</string> + <string name="progress_building_key">assemblage de la clef…</string> + <string name="progress_preparing_master_key">préparation de la clef maîtresse…</string> + <string name="progress_certifying_master_key">certification de la clef maîtresse…</string> + <string name="progress_building_master_key">assemblage du trousseau maître…</string> + <string name="progress_adding_sub_keys">ajout des sous-clefs…</string> + <string name="progress_saving_key_ring">sauvegarde de la clef…</string> <plurals name="progress_exporting_key"> - <item quantity="one">exportation de la clef...</item> - <item quantity="other">exportation des clefs...</item> + <item quantity="one">exportation de la clef…</item> + <item quantity="other">exportation des clefs…</item> </plurals> - <string name="progress_extracting_signature_key">extraction de la clef de signature...</string> - <string name="progress_extracting_key">extraction de la clef...</string> - <string name="progress_preparing_streams">préparation des flux...</string> - <string name="progress_encrypting">chiffrement des données...</string> - <string name="progress_decrypting">déchiffrement des données...</string> - <string name="progress_preparing_signature">préparation de la signature...</string> - <string name="progress_generating_signature">génération de la signature...</string> - <string name="progress_processing_signature">traitement de la signature...</string> - <string name="progress_verifying_signature">vérification de la signature...</string> - <string name="progress_signing">signature...</string> - <string name="progress_reading_data">lecture des données...</string> - <string name="progress_finding_key">recherche de la clef...</string> - <string name="progress_decompressing_data">décompression des données...</string> - <string name="progress_verifying_integrity">vérification de l\'intégrité...</string> - <string name="progress_deleting_securely">suppression sûre de « %s »...</string> - <string name="progress_querying">interrogation...</string> + <string name="progress_extracting_signature_key">extraction de la clef de signature…</string> + <string name="progress_extracting_key">extraction de la clef…</string> + <string name="progress_preparing_streams">préparation des flux…</string> + <string name="progress_encrypting">chiffrement des données…</string> + <string name="progress_decrypting">déchiffrement des données…</string> + <string name="progress_preparing_signature">préparation de la signature…</string> + <string name="progress_generating_signature">génération de la signature…</string> + <string name="progress_processing_signature">traitement de la signature…</string> + <string name="progress_verifying_signature">vérification de la signature…</string> + <string name="progress_signing">signature…</string> + <string name="progress_reading_data">lecture des données…</string> + <string name="progress_finding_key">recherche de la clef…</string> + <string name="progress_decompressing_data">décompression des données…</string> + <string name="progress_verifying_integrity">vérification de l\'intégrité…</string> + <string name="progress_deleting_securely">suppression sûre de « %s »…</string> + <string name="progress_querying">interrogation…</string> <!--action strings--> <string name="hint_public_keys">Rechercher des clefs publiques</string> <string name="hint_secret_keys">Rechercher des clefs secrètes</string> - <string name="action_share_key_with">Partager la clef avec...</string> + <string name="action_share_key_with">Partager la clef avec…</string> <!--key bit length selections--> <string name="key_size_512">512</string> <string name="key_size_1024">1024</string> @@ -340,10 +340,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> @@ -374,7 +374,7 @@ <item quantity="one">1 clef choisie</item> <item quantity="other">%d clefs choisies</item> </plurals> - <string name="key_list_empty_text1">Aucune clef encore disponible...</string> + <string name="key_list_empty_text1">Aucune clef encore disponible…</string> <string name="key_list_empty_text2">Vous pouvez commencer par</string> <string name="key_list_empty_text3">ou</string> <string name="key_list_empty_button_create">créer votre propre clef</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..825115bc9 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,9 @@ <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_email">Invia Mail…</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> @@ -61,7 +61,7 @@ <string name="btn_next">Prossimo</string> <string name="btn_back">Precedente</string> <string name="btn_clipboard">Appunti</string> - <string name="btn_share">Condividi con...</string> + <string name="btn_share">Condividi con…</string> <string name="btn_lookup_key">Chiave di ricerca</string> <!--menu--> <string name="menu_preferences">Impostazioni</string> @@ -80,10 +80,10 @@ <string name="menu_update_key">Aggiorna dal server delle chiavi</string> <string name="menu_export_key_to_server">Carica chiave nel server</string> <string name="menu_share">Condividi</string> - <string name="menu_share_title_fingerprint">Condivi impronta...</string> - <string name="menu_share_title">Condividi intera chiave...</string> + <string name="menu_share_title_fingerprint">Condivi impronta…</string> + <string name="menu_share_title">Condividi intera chiave…</string> <string name="menu_share_default_fingerprint">con..</string> - <string name="menu_share_default">con...</string> + <string name="menu_share_default">con…</string> <string name="menu_share_qr_code">con Codice QR</string> <string name="menu_share_qr_code_fingerprint">con Codice QR</string> <string name="menu_share_nfc">con NFC</string> @@ -91,7 +91,7 @@ <string name="menu_sign_key">Firma chiave</string> <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_encrypt_to">Codifica su…</string> <!--label--> <string name="label_sign">Firma</string> <string name="label_message">Messaggio</string> @@ -163,7 +163,7 @@ <string name="dsa">DSA</string> <string name="elgamal">ElGamal</string> <string name="rsa">RSA</string> - <string name="filemanager_title_open">Apri...</string> + <string name="filemanager_title_open">Apri…</string> <string name="warning">Attenzione</string> <string name="error">Errore</string> <string name="error_message">Errore: %s</string> @@ -275,40 +275,40 @@ </plurals> <!--progress dialogs, usually ending in '…'--> <string name="progress_done">fatto.</string> - <string name="progress_saving">salvataggio...</string> - <string name="progress_importing">importazione...</string> - <string name="progress_exporting">esportazione...</string> - <string name="progress_generating">generazione chiave, richiede fino a 3 minuti...</string> - <string name="progress_building_key">fabbricazione chiave...</string> - <string name="progress_preparing_master_key">preparazione chiave principale...</string> - <string name="progress_certifying_master_key">certificazione chiave principale...</string> - <string name="progress_building_master_key">fabbricazione portachiavi principale...</string> - <string name="progress_adding_sub_keys">aggiunta sottochiavi...</string> - <string name="progress_saving_key_ring">salvataggio chiavi...</string> + <string name="progress_saving">salvataggio…</string> + <string name="progress_importing">importazione…</string> + <string name="progress_exporting">esportazione…</string> + <string name="progress_generating">generazione chiave, richiede fino a 3 minuti…</string> + <string name="progress_building_key">fabbricazione chiave…</string> + <string name="progress_preparing_master_key">preparazione chiave principale…</string> + <string name="progress_certifying_master_key">certificazione chiave principale…</string> + <string name="progress_building_master_key">fabbricazione portachiavi principale…</string> + <string name="progress_adding_sub_keys">aggiunta sottochiavi…</string> + <string name="progress_saving_key_ring">salvataggio chiavi…</string> <plurals name="progress_exporting_key"> - <item quantity="one">esportazione chiave...</item> - <item quantity="other">esportazione chiavi...</item> + <item quantity="one">esportazione chiave…</item> + <item quantity="other">esportazione chiavi…</item> </plurals> - <string name="progress_extracting_signature_key">estrazione chiavi di firma...</string> - <string name="progress_extracting_key">estrazione chiave...</string> - <string name="progress_preparing_streams">preparazione flussi...</string> - <string name="progress_encrypting">codifica dati...</string> - <string name="progress_decrypting">decodifica dati...</string> - <string name="progress_preparing_signature">preparazione firma...</string> - <string name="progress_generating_signature">generazione firma...</string> - <string name="progress_processing_signature">elaborazione firma...</string> - <string name="progress_verifying_signature">verifica firma...</string> - <string name="progress_signing">firma...</string> - <string name="progress_reading_data">lettura dati...</string> - <string name="progress_finding_key">ricerca chiave...</string> - <string name="progress_decompressing_data">decompressione dati...</string> - <string name="progress_verifying_integrity">verifica integrita\'...</string> - <string name="progress_deleting_securely">eliminazione sicura di \'%s\'...</string> - <string name="progress_querying">interrogazione...</string> + <string name="progress_extracting_signature_key">estrazione chiavi di firma…</string> + <string name="progress_extracting_key">estrazione chiave…</string> + <string name="progress_preparing_streams">preparazione flussi…</string> + <string name="progress_encrypting">codifica dati…</string> + <string name="progress_decrypting">decodifica dati…</string> + <string name="progress_preparing_signature">preparazione firma…</string> + <string name="progress_generating_signature">generazione firma…</string> + <string name="progress_processing_signature">elaborazione firma…</string> + <string name="progress_verifying_signature">verifica firma…</string> + <string name="progress_signing">firma…</string> + <string name="progress_reading_data">lettura dati…</string> + <string name="progress_finding_key">ricerca chiave…</string> + <string name="progress_decompressing_data">decompressione dati…</string> + <string name="progress_verifying_integrity">verifica integrita\'…</string> + <string name="progress_deleting_securely">eliminazione sicura di \'%s\'…</string> + <string name="progress_querying">interrogazione…</string> <!--action strings--> <string name="hint_public_keys">Ricerca Chiavi Pubbliche</string> <string name="hint_secret_keys">Cerca Chiave Privata</string> - <string name="action_share_key_with">Condividi chiave con...</string> + <string name="action_share_key_with">Condividi chiave con…</string> <!--key bit length selections--> <string name="key_size_512">512</string> <string name="key_size_1024">1024</string> @@ -340,10 +340,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> @@ -374,7 +374,7 @@ <item quantity="one">1 chiave selezionata.</item> <item quantity="other">%d chiavi selezionate.</item> </plurals> - <string name="key_list_empty_text1">Nessuna chiave disponibile...</string> + <string name="key_list_empty_text1">Nessuna chiave disponibile…</string> <string name="key_list_empty_text2">Puoi iniziare da</string> <string name="key_list_empty_text3">o</string> <string name="key_list_empty_button_create">creazione della tua chiave</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..97d5a72f4 100644 --- a/OpenPGP-Keychain/src/main/res/values-ja/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-ja/strings.xml @@ -13,9 +13,9 @@ <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_email">メールの送信…</string> <string name="title_encrypt_to_file">暗号化してファイルに</string> <string name="title_decrypt_to_file">復号化してファイルに</string> <string name="title_import_keys">鍵のインポート</string> @@ -61,7 +61,7 @@ <string name="btn_next">次</string> <string name="btn_back">戻る</string> <string name="btn_clipboard">クリップボード</string> - <string name="btn_share">共有...</string> + <string name="btn_share">共有…</string> <string name="btn_lookup_key">鍵検出</string> <!--menu--> <string name="menu_preferences">設定</string> @@ -80,10 +80,10 @@ <string name="menu_update_key">鍵サーバからの更新</string> <string name="menu_export_key_to_server">鍵サーバへのアップロード</string> <string name="menu_share">共有</string> - <string name="menu_share_title_fingerprint">指紋の共有...</string> - <string name="menu_share_title">すべての鍵の共有...</string> - <string name="menu_share_default_fingerprint">...(指紋)</string> - <string name="menu_share_default">...(鍵)</string> + <string name="menu_share_title_fingerprint">指紋の共有…</string> + <string name="menu_share_title">すべての鍵の共有…</string> + <string name="menu_share_default_fingerprint">…(指紋)</string> + <string name="menu_share_default">…(鍵)</string> <string name="menu_share_qr_code">QRコードで共有(鍵)</string> <string name="menu_share_qr_code_fingerprint">QRコードで共有(指紋)</string> <string name="menu_share_nfc">NFCで共有</string> @@ -91,7 +91,7 @@ <string name="menu_sign_key">鍵を署名</string> <string name="menu_beam_preferences">Beamの設定</string> <string name="menu_key_edit_cancel">キャンセル</string> - <string name="menu_encrypt_to">暗号化...</string> + <string name="menu_encrypt_to">暗号化…</string> <!--label--> <string name="label_sign">署名</string> <string name="label_message">メッセージ</string> @@ -161,7 +161,7 @@ <string name="dsa">DSA</string> <string name="elgamal">ElGamal</string> <string name="rsa">RSA</string> - <string name="filemanager_title_open">開く...</string> + <string name="filemanager_title_open">開く…</string> <string name="warning">注意</string> <string name="error">エラー</string> <string name="error_message">エラー: %s</string> @@ -266,39 +266,39 @@ </plurals> <!--progress dialogs, usually ending in '…'--> <string name="progress_done">完了。</string> - <string name="progress_saving">保存...</string> - <string name="progress_importing">インポート...</string> - <string name="progress_exporting">エクスポート...</string> - <string name="progress_generating">鍵の生成、3分ほどかかります...</string> - <string name="progress_building_key">鍵の構築中...</string> - <string name="progress_preparing_master_key">主鍵の準備中...</string> - <string name="progress_certifying_master_key">主鍵の検証中...</string> - <string name="progress_building_master_key">主鍵輪の構築中...</string> - <string name="progress_adding_sub_keys">副鍵の追加中...</string> - <string name="progress_saving_key_ring">鍵の保存...</string> + <string name="progress_saving">保存…</string> + <string name="progress_importing">インポート…</string> + <string name="progress_exporting">エクスポート…</string> + <string name="progress_generating">鍵の生成、3分ほどかかります…</string> + <string name="progress_building_key">鍵の構築中…</string> + <string name="progress_preparing_master_key">主鍵の準備中…</string> + <string name="progress_certifying_master_key">主鍵の検証中…</string> + <string name="progress_building_master_key">主鍵輪の構築中…</string> + <string name="progress_adding_sub_keys">副鍵の追加中…</string> + <string name="progress_saving_key_ring">鍵の保存…</string> <plurals name="progress_exporting_key"> - <item quantity="other">鍵のエクスポート...</item> + <item quantity="other">鍵のエクスポート…</item> </plurals> - <string name="progress_extracting_signature_key">署名鍵の取り出し中...</string> - <string name="progress_extracting_key">鍵の取り出し中...</string> - <string name="progress_preparing_streams">ストリームの準備中...</string> - <string name="progress_encrypting">データの暗号化中...</string> - <string name="progress_decrypting">データの復号化中...</string> - <string name="progress_preparing_signature">署名の準備中...</string> - <string name="progress_generating_signature">署名の生成中...</string> - <string name="progress_processing_signature">署名処理中...</string> - <string name="progress_verifying_signature">署名の検証中...</string> - <string name="progress_signing">署名中...</string> - <string name="progress_reading_data">データ読み込み中...</string> - <string name="progress_finding_key">鍵検索中...</string> - <string name="progress_decompressing_data">データの展開中...</string> - <string name="progress_verifying_integrity">完全性の検証中...</string> + <string name="progress_extracting_signature_key">署名鍵の取り出し中…</string> + <string name="progress_extracting_key">鍵の取り出し中…</string> + <string name="progress_preparing_streams">ストリームの準備中…</string> + <string name="progress_encrypting">データの暗号化中…</string> + <string name="progress_decrypting">データの復号化中…</string> + <string name="progress_preparing_signature">署名の準備中…</string> + <string name="progress_generating_signature">署名の生成中…</string> + <string name="progress_processing_signature">署名処理中…</string> + <string name="progress_verifying_signature">署名の検証中…</string> + <string name="progress_signing">署名中…</string> + <string name="progress_reading_data">データ読み込み中…</string> + <string name="progress_finding_key">鍵検索中…</string> + <string name="progress_decompressing_data">データの展開中…</string> + <string name="progress_verifying_integrity">完全性の検証中…</string> <string name="progress_deleting_securely">\'%s\' を完全に削除中…</string> - <string name="progress_querying">要求中...</string> + <string name="progress_querying">要求中…</string> <!--action strings--> <string name="hint_public_keys">公開鍵の検索</string> <string name="hint_secret_keys">秘密鍵の検索</string> - <string name="action_share_key_with">鍵の共有...</string> + <string name="action_share_key_with">鍵の共有…</string> <!--key bit length selections--> <string name="key_size_512">512</string> <string name="key_size_1024">1024</string> @@ -329,10 +329,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> @@ -362,7 +362,7 @@ <plurals name="key_list_selected_keys"> <item quantity="other">%d の鍵を選択。</item> </plurals> - <string name="key_list_empty_text1">すでにその鍵は存在しません...</string> + <string name="key_list_empty_text1">すでにその鍵は存在しません…</string> <string name="key_list_empty_text2">で始める</string> <string name="key_list_empty_text3">もしくは</string> <string name="key_list_empty_button_create">あなた所有の鍵を作る</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..863932a80 100644 --- a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml @@ -10,9 +10,9 @@ <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_change_passphrase">Wachtwoord wijzigen</string> <string name="title_set_passphrase">Wachtwoord instellen</string> - <string name="title_send_email">E-mail verzenden...</string> + <string name="title_send_email">E-mail verzenden…</string> <string name="title_encrypt_to_file">Versleutelen naar bestand</string> <string name="title_decrypt_to_file">Ontsleutelen naar bestand</string> <string name="title_import_keys">Sleutels importeren</string> @@ -109,7 +109,7 @@ <string name="dsa">DSA</string> <string name="elgamal">ElGamal</string> <string name="rsa">RSA</string> - <string name="filemanager_title_open">Openen...</string> + <string name="filemanager_title_open">Openen…</string> <string name="warning">Waarschuwing</string> <string name="error">Fout</string> <string name="error_message">Fout: %s</string> @@ -172,34 +172,34 @@ <string name="error_nothing_import">Niets te importeren</string> <!--progress dialogs, usually ending in '…'--> <string name="progress_done">gereed.</string> - <string name="progress_saving">opslaan...</string> - <string name="progress_importing">importeren...</string> - <string name="progress_exporting">exporteren...</string> - <string name="progress_building_key">sleutel maken...</string> - <string name="progress_preparing_master_key">hoofdsleutel voorbereiden...</string> - <string name="progress_certifying_master_key">hoofdsleutel certificeren...</string> - <string name="progress_building_master_key">hoofdsleutelbos maken...</string> - <string name="progress_adding_sub_keys">sub-sleutels toevoegen...</string> - <string name="progress_extracting_signature_key">ondertekeningssleutel uitpakken...</string> - <string name="progress_extracting_key">sleutel uitpakken...</string> - <string name="progress_preparing_streams">streams voorbereiden...</string> - <string name="progress_encrypting">gegevens versleutelen...</string> - <string name="progress_decrypting">gegevens ontsleutelen...</string> - <string name="progress_preparing_signature">handtekening voorbereiden...</string> - <string name="progress_generating_signature">handtekening genereren...</string> - <string name="progress_processing_signature">handtekening verwerken...</string> - <string name="progress_verifying_signature">handtekening verifiëren...</string> - <string name="progress_signing">ondertekenen...</string> - <string name="progress_reading_data">gegevens lezen...</string> - <string name="progress_finding_key">sleutel opzoeken...</string> - <string name="progress_decompressing_data">gegevens decomprimeren...</string> - <string name="progress_verifying_integrity">integriteit verifiëren...</string> - <string name="progress_deleting_securely">\'%s\' veilig verwijderen...</string> - <string name="progress_querying">opvragen...</string> + <string name="progress_saving">opslaan…</string> + <string name="progress_importing">importeren…</string> + <string name="progress_exporting">exporteren…</string> + <string name="progress_building_key">sleutel maken…</string> + <string name="progress_preparing_master_key">hoofdsleutel voorbereiden…</string> + <string name="progress_certifying_master_key">hoofdsleutel certificeren…</string> + <string name="progress_building_master_key">hoofdsleutelbos maken…</string> + <string name="progress_adding_sub_keys">sub-sleutels toevoegen…</string> + <string name="progress_extracting_signature_key">ondertekeningssleutel uitpakken…</string> + <string name="progress_extracting_key">sleutel uitpakken…</string> + <string name="progress_preparing_streams">streams voorbereiden…</string> + <string name="progress_encrypting">gegevens versleutelen…</string> + <string name="progress_decrypting">gegevens ontsleutelen…</string> + <string name="progress_preparing_signature">handtekening voorbereiden…</string> + <string name="progress_generating_signature">handtekening genereren…</string> + <string name="progress_processing_signature">handtekening verwerken…</string> + <string name="progress_verifying_signature">handtekening verifiëren…</string> + <string name="progress_signing">ondertekenen…</string> + <string name="progress_reading_data">gegevens lezen…</string> + <string name="progress_finding_key">sleutel opzoeken…</string> + <string name="progress_decompressing_data">gegevens decomprimeren…</string> + <string name="progress_verifying_integrity">integriteit verifiëren…</string> + <string name="progress_deleting_securely">\'%s\' veilig verwijderen…</string> + <string name="progress_querying">opvragen…</string> <!--action strings--> <string name="hint_public_keys">Publieke sleutels zoeken</string> <string name="hint_secret_keys">Privésleutels zoeken</string> - <string name="action_share_key_with">Sleutel delen met...</string> + <string name="action_share_key_with">Sleutel delen met…</string> <!--key bit length selections--> <string name="key_size_512">512</string> <string name="key_size_1024">1024</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..f69cf8789 100644 --- a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml @@ -13,9 +13,9 @@ <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_email">Отправить…</string> <string name="title_encrypt_to_file">Зашифровать в файл</string> <string name="title_decrypt_to_file">Расшифровать в файл</string> <string name="title_import_keys">Импорт ключей</string> @@ -61,7 +61,7 @@ <string name="btn_next">Далее</string> <string name="btn_back">Назад</string> <string name="btn_clipboard">Буфер обмена</string> - <string name="btn_share">Поделиться...</string> + <string name="btn_share">Поделиться…</string> <string name="btn_lookup_key">Найти ключ</string> <!--menu--> <string name="menu_preferences">Настройки</string> @@ -79,9 +79,9 @@ <string name="menu_key_server">Импорт с сервера ключей</string> <string name="menu_update_key">Обновить с сервера ключей</string> <string name="menu_export_key_to_server">Загрузить на сервер ключей</string> - <string name="menu_share">Отправить...</string> - <string name="menu_share_title_fingerprint">Отправить отпечаток...</string> - <string name="menu_share_title">Отправить ключ...</string> + <string name="menu_share">Отправить…</string> + <string name="menu_share_title_fingerprint">Отправить отпечаток…</string> + <string name="menu_share_title">Отправить ключ…</string> <string name="menu_share_default_fingerprint">Отправить</string> <string name="menu_share_default">Отправить</string> <string name="menu_share_qr_code">QR код</string> @@ -91,7 +91,7 @@ <string name="menu_sign_key">Подписать ключ</string> <string name="menu_beam_preferences">Настройки Beam</string> <string name="menu_key_edit_cancel">Отмена</string> - <string name="menu_encrypt_to">Зашифровать....</string> + <string name="menu_encrypt_to">Зашифровать….</string> <!--label--> <string name="label_sign">Подписать</string> <string name="label_message">Сообщение</string> @@ -115,7 +115,7 @@ <string name="label_key_servers">Серверы ключей</string> <string name="label_key_id">ID ключа</string> <string name="label_creation">Создан</string> - <string name="label_expiry">Годен до...</string> + <string name="label_expiry">Годен до…</string> <string name="label_usage">Применение</string> <string name="label_key_size">Размер ключа</string> <string name="label_main_user_id">Основной ID пользователя</string> @@ -165,7 +165,7 @@ <string name="dsa">DSA</string> <string name="elgamal">ElGamal</string> <string name="rsa">RSA</string> - <string name="filemanager_title_open">Открыть...</string> + <string name="filemanager_title_open">Открыть…</string> <string name="warning">Внимание</string> <string name="error">Ошибка</string> <string name="error_message">Ошибка: %s</string> @@ -284,41 +284,41 @@ </plurals> <!--progress dialogs, usually ending in '…'--> <string name="progress_done">готово.</string> - <string name="progress_saving">сохранение...</string> - <string name="progress_importing">импорт...</string> - <string name="progress_exporting">экспорт...</string> - <string name="progress_generating">создание ключа. это может занять до 3 минут...</string> - <string name="progress_building_key">создание ключа...</string> - <string name="progress_preparing_master_key">подготовка основного ключа...</string> - <string name="progress_certifying_master_key">сертификация основного ключа...</string> - <string name="progress_building_master_key">создание основной связки...</string> - <string name="progress_adding_sub_keys">добавление доп. ключей...</string> - <string name="progress_saving_key_ring">сохранение ключа...</string> + <string name="progress_saving">сохранение…</string> + <string name="progress_importing">импорт…</string> + <string name="progress_exporting">экспорт…</string> + <string name="progress_generating">создание ключа. это может занять до 3 минут…</string> + <string name="progress_building_key">создание ключа…</string> + <string name="progress_preparing_master_key">подготовка основного ключа…</string> + <string name="progress_certifying_master_key">сертификация основного ключа…</string> + <string name="progress_building_master_key">создание основной связки…</string> + <string name="progress_adding_sub_keys">добавление доп. ключей…</string> + <string name="progress_saving_key_ring">сохранение ключа…</string> <plurals name="progress_exporting_key"> - <item quantity="one">экспорт ключа...</item> - <item quantity="few">экспорт ключей...</item> - <item quantity="other">экспорт ключей...</item> + <item quantity="one">экспорт ключа…</item> + <item quantity="few">экспорт ключей…</item> + <item quantity="other">экспорт ключей…</item> </plurals> - <string name="progress_extracting_signature_key">извлечение подписи ключа...</string> - <string name="progress_extracting_key">извлечение ключа...</string> - <string name="progress_preparing_streams">подготовка к передаче...</string> - <string name="progress_encrypting">шифрование данных...</string> - <string name="progress_decrypting">расшифровка данных...</string> - <string name="progress_preparing_signature">подготовка подписи...</string> - <string name="progress_generating_signature">формирование подписи...</string> - <string name="progress_processing_signature">обработка подписи...</string> - <string name="progress_verifying_signature">проверка подписи...</string> - <string name="progress_signing">подписание...</string> - <string name="progress_reading_data">чтение данных...</string> - <string name="progress_finding_key">поиск ключа...</string> - <string name="progress_decompressing_data">распаковка данных...</string> - <string name="progress_verifying_integrity">проверка целостности...</string> - <string name="progress_deleting_securely">безопасное удаление \'%s\'...</string> - <string name="progress_querying">запрос...</string> + <string name="progress_extracting_signature_key">извлечение подписи ключа…</string> + <string name="progress_extracting_key">извлечение ключа…</string> + <string name="progress_preparing_streams">подготовка к передаче…</string> + <string name="progress_encrypting">шифрование данных…</string> + <string name="progress_decrypting">расшифровка данных…</string> + <string name="progress_preparing_signature">подготовка подписи…</string> + <string name="progress_generating_signature">формирование подписи…</string> + <string name="progress_processing_signature">обработка подписи…</string> + <string name="progress_verifying_signature">проверка подписи…</string> + <string name="progress_signing">подписание…</string> + <string name="progress_reading_data">чтение данных…</string> + <string name="progress_finding_key">поиск ключа…</string> + <string name="progress_decompressing_data">распаковка данных…</string> + <string name="progress_verifying_integrity">проверка целостности…</string> + <string name="progress_deleting_securely">безопасное удаление \'%s\'…</string> + <string name="progress_querying">запрос…</string> <!--action strings--> <string name="hint_public_keys">Найти публичные ключи</string> <string name="hint_secret_keys">Найти секретные ключи</string> - <string name="action_share_key_with">Отправить...</string> + <string name="action_share_key_with">Отправить…</string> <!--key bit length selections--> <string name="key_size_512">512</string> <string name="key_size_1024">1024</string> @@ -386,7 +386,7 @@ <item quantity="few">%d ключей выбрано.</item> <item quantity="other">%d ключей выбрано.</item> </plurals> - <string name="key_list_empty_text1">У вас пока нет ключей...</string> + <string name="key_list_empty_text1">У вас пока нет ключей…</string> <string name="key_list_empty_text2">Но Вы можете</string> <string name="key_list_empty_text3">или</string> <string name="key_list_empty_button_create">создать свой ключ</string> diff --git a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml index 5bb5225b5..4f1becaa1 100644 --- a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml @@ -76,7 +76,7 @@ <string name="dsa">DSA</string> <string name="elgamal">ElGamal</string> <string name="rsa">RSA</string> - <string name="filemanager_title_open">Aç...</string> + <string name="filemanager_title_open">Aç…</string> <string name="warning">Uyarı</string> <string name="error">Hata</string> <string name="error_message">Hata: %s</string> @@ -96,17 +96,17 @@ <string name="error_corrupt_data">bozuk veri</string> <!--progress dialogs, usually ending in '…'--> <string name="progress_done">bitti.</string> - <string name="progress_saving">kaydediliyor...</string> - <string name="progress_importing">alıyor...</string> - <string name="progress_exporting">veriyor...</string> - <string name="progress_building_key">anahtar oluşturuluyor...</string> - <string name="progress_preparing_signature">imza hazırlanıyor...</string> - <string name="progress_generating_signature">imza oluşturuluyor...</string> - <string name="progress_processing_signature">imza işleniyor...</string> - <string name="progress_verifying_signature">imza doğrulanıyor...</string> - <string name="progress_signing">imzalanıyor...</string> - <string name="progress_reading_data">veri okunuyor...</string> - <string name="progress_finding_key">anahtar bulunuyor...</string> + <string name="progress_saving">kaydediliyor…</string> + <string name="progress_importing">alıyor…</string> + <string name="progress_exporting">veriyor…</string> + <string name="progress_building_key">anahtar oluşturuluyor…</string> + <string name="progress_preparing_signature">imza hazırlanıyor…</string> + <string name="progress_generating_signature">imza oluşturuluyor…</string> + <string name="progress_processing_signature">imza işleniyor…</string> + <string name="progress_verifying_signature">imza doğrulanıyor…</string> + <string name="progress_signing">imzalanıyor…</string> + <string name="progress_reading_data">veri okunuyor…</string> + <string name="progress_finding_key">anahtar bulunuyor…</string> <!--action strings--> <!--key bit length selections--> <string name="key_size_512">512</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..8997ef5ce 100644 --- a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-uk/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> @@ -351,10 +351,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..5848fb8db 100644 --- a/OpenPGP-Keychain/src/main/res/values-zh/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-zh/strings.xml @@ -24,7 +24,7 @@ <string name="menu_copy_to_clipboard">复制到剪贴板</string> <string name="menu_sign_key">签署密钥</string> <string name="menu_key_edit_cancel">取消</string> - <string name="menu_encrypt_to">加密到...</string> + <string name="menu_encrypt_to">加密到…</string> <!--label--> <string name="label_sign">签署</string> <string name="label_message">讯息</string> @@ -64,7 +64,7 @@ <string name="choice_4hours">4小时</string> <string name="choice_8hours">8小时</string> <string name="choice_forever">永远</string> - <string name="filemanager_title_open">打开...</string> + <string name="filemanager_title_open">打开…</string> <string name="warning">警告</string> <string name="error">错误</string> <!--sentences--> @@ -106,13 +106,13 @@ <string name="error_wrong_passphrase">错误的密语</string> <!--progress dialogs, usually ending in '…'--> <string name="progress_done">完成。</string> - <string name="progress_saving">保存...</string> - <string name="progress_importing">导入中...</string> - <string name="progress_exporting">导出中...</string> + <string name="progress_saving">保存…</string> + <string name="progress_importing">导入中…</string> + <string name="progress_exporting">导出中…</string> <string name="progress_building_key">建立密钥</string> <string name="progress_preparing_master_key">正在准备主密钥</string> - <string name="progress_verifying_signature">正在验证签名...</string> - <string name="progress_signing">正在签名...</string> + <string name="progress_verifying_signature">正在验证签名…</string> + <string name="progress_signing">正在签名…</string> <string name="progress_reading_data">正在读取数据</string> <string name="progress_finding_key">正在查找密钥</string> <string name="progress_querying">正在查询</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 14ed7c7da..cd016c41e 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> @@ -96,6 +97,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 +111,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 +130,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> @@ -144,6 +150,7 @@ <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_key_servers"> <item quantity="one">%d keyserver</item> @@ -302,6 +309,7 @@ <!-- progress dialogs, usually ending in '…' --> <string name="progress_done">done.</string> + <string name="progress_cancel">cancel</string> <string name="progress_saving">saving…</string> <string name="progress_importing">importing…</string> <string name="progress_exporting">exporting…</string> @@ -377,10 +385,10 @@ <string name="import_clipboard_button">Get key from clipboard</string> <!-- Intent labels --> - <string name="intent_decrypt_file">OpenKeychain: Decrypt File</string> - <string name="intent_import_key">OpenKeychain: Import Key</string> - <string name="intent_send_encrypt">OpenKeychain: Encrypt</string> - <string name="intent_send_decrypt">OpenKeychain: Decrypt</string> + <string name="intent_decrypt_file">Decrypt File with OpenKeychain</string> + <string name="intent_import_key">Import Key with OpenKeychain</string> + <string name="intent_send_encrypt">Encrypt with OpenKeychain</string> + <string name="intent_send_decrypt">Decrypt with OpenKeychain</string> <!-- Remote API --> <string name="api_no_apps">No registered applications!\n\nThird-party applications can request access to OpenKeychain. After granting access, they will be listed here.</string> 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 @@ -1,9 +1,11 @@ # OpenKeychain (for Android) -OpenKeychain is an OpenPGP implementation for Android. -The development began as a fork of Android Privacy Guard (APG). +OpenKeychain is an OpenPGP implementation for Android. +For a more detailed description and installation instructions go to http://www.openkeychain.org . -see http://sufficientlysecure.org/keychain +### Travis CI Build Status + +[](https://travis-ci.org/openpgp-keychain/openpgp-keychain) ## How to help the project? @@ -30,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`` @@ -53,65 +55,17 @@ I am using the newest [Android Studio](http://developer.android.com/sdk/installi * Select the "OpenPGP-Keychain-API" folder if you want to develop on the API example 3. Import project from external model -> choose Gradle -## Keychain API - -### Intent API -All Intents require user interaction, e.g. to finally encrypt the user needs to press the "Encrypt" button. -To do automatic encryption/decryption/sign/verify use the OpenPGP Remote API. - -#### Android Intent actions: - -* ``android.intent.action.VIEW`` connected to .gpg and .asc files: Import Key and Decrypt -* ``android.intent.action.SEND`` connected to all mime types (text/plain and every binary data like files and images): Encrypt and Decrypt - -#### OpenKeychain Intent actions: - -* ``org.sufficientlysecure.keychain.action.ENCRYPT`` - * To encrypt or sign text, use extra ``text`` (type: ``String``) - * or set data ``Uri`` (``intent.setData()``) pointing to a file - * Enable ASCII Armor for file encryption (encoding to Radix-64, 33% overhead) by adding the extra ``ascii_armor`` with value ``true`` -* ``org.sufficientlysecure.keychain.action.DECRYPT`` - * To decrypt or verify text, use extra ``text`` (type: ``String``) - * or set data ``Uri`` (``intent.setData()``) pointing to a file -* ``org.sufficientlysecure.keychain.action.IMPORT_KEY`` - * Extras: ``key_bytes`` (type: ``byte[]``) - * or set data ``Uri`` (``intent.setData()``) pointing to a file -* ``org.sufficientlysecure.keychain.action.IMPORT_KEY_FROM_KEYSERVER`` - * Extras: ``query`` (type: ``String``) - * or ``fingerprint`` (type: ``String``) -* ``org.sufficientlysecure.keychain.action.IMPORT_KEY_FROM_QR_CODE`` - * without extras, starts Barcode Scanner to get QR Code - -#### OpenKeychain special registered Intents: -* ``android.intent.action.VIEW`` with URIs following the ``openpgp4fpr`` schema. For example: ``openpgp4fpr:73EE2314F65FA92EC2390D3A718C070100012282``. This is used in QR Codes, but could also be embedded into your website. (compatible with Monkeysphere's and Guardian Project's QR Codes) -* NFC (``android.nfc.action.NDEF_DISCOVERED``) on mime type ``application/pgp-keys`` (as specified in http://tools.ietf.org/html/rfc3156, section 7) - -### OpenPGP Remote API -To do fast encryption/decryption/sign/verify operations without user interaction bind to the OpenPGP remote service. - -#### Try out the API -Keychain: https://play.google.com/store/apps/details?id=org.sufficientlysecure.keychain -API Demo: https://play.google.com/store/apps/details?id=org.sufficientlysecure.keychain.demo - -#### Design -All apps wanting to use this generic API -just need to include the AIDL files and connect to the service. Other -OpenPGP apps can implement a service based on this AIDL definition. - -The API is designed to be as easy as possible to use by apps like K-9 Mail. -The service definition defines sign, encrypt, signAndEncrypt, decryptAndVerify, and getKeyIds. - -As can be seen in the API Demo, the apps themselves never need to handle key ids directly. -You can use user ids (emails) to define recipients. -If more than one public key exists for an email, OpenKeychain will handle the problem by showing a selection screen. Additionally, it is also possible to use key ids. +## OpenKeychain's API -Also app devs never need to fiddle with private keys. -On first operation, OpenKeychain shows an activity to allow or disallow access, while also allowing to choose the private key used for this app. -Please try the Demo app out to see how it works. +OpenKeychain provides two APIs, namely the Intent API and the Remote OpenPGP API. +The Intent API can be used without permissions to start OpenKeychain's activities for cryptographic operations, import of keys, etc. +However, it always requires user input, so that no malicious application can use this API without user intervention. +The Remote OpenPGP API is more sophisticated and allows to to operations without user interaction in the background. +When utilizing this API, OpenKeychain asks the user on first use to grant access for the calling client application. -#### Integration -Copy the api library from "libraries/keychain-api-library" to your project and add it as an dependency to your gradle build. -Inspect the ode found in "OpenPGP-Keychain-API" to understand how to use the API. +More technical information and examples about these APIs can be found in the project's wiki: +* [Intent API](https://github.com/openpgp-keychain/openpgp-keychain/wiki/Intent-API) +* [Remote OpenPGP API](https://github.com/openpgp-keychain/openpgp-keychain/wiki/OpenPGP-API) ## Libraries @@ -162,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 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' |