diff options
Diffstat (limited to 'src')
37 files changed, 0 insertions, 1914 deletions
| diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml deleted file mode 100644 index f1f29cf..0000000 --- a/src/main/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" -    package="org.openintents.openpgp"> - -    <application/> - -</manifest>
\ No newline at end of file diff --git a/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl b/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl deleted file mode 100644 index 2451207..0000000 --- a/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -  -package org.openintents.openpgp; - -interface IOpenPgpService { - -    // see OpenPgpApi for documentation -    Intent execute(in Intent data, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - -}
\ No newline at end of file diff --git a/src/main/java/org/openintents/openpgp/OpenPgpError.java b/src/main/java/org/openintents/openpgp/OpenPgpError.java deleted file mode 100644 index ce8f21f..0000000 --- a/src/main/java/org/openintents/openpgp/OpenPgpError.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Parcelable versioning has been copied from Dashclock Widget - * https://code.google.com/p/dashclock/source/browse/api/src/main/java/com/google/android/apps/dashclock/api/ExtensionData.java - */ -public class OpenPgpError implements Parcelable { -    /** -     * Since there might be a case where new versions of the client using the library getting -     * old versions of the protocol (and thus old versions of this class), we need a versioning -     * system for the parcels sent between the clients and the providers. -     */ -    public static final int PARCELABLE_VERSION = 1; - -    // possible values for errorId -    public static final int CLIENT_SIDE_ERROR = -1; -    public static final int GENERIC_ERROR = 0; -    public static final int INCOMPATIBLE_API_VERSIONS = 1; -    public static final int NO_OR_WRONG_PASSPHRASE = 2; -    public static final int NO_USER_IDS = 3; - -    int errorId; -    String message; - -    public OpenPgpError() { -    } - -    public OpenPgpError(int errorId, String message) { -        this.errorId = errorId; -        this.message = message; -    } - -    public OpenPgpError(OpenPgpError b) { -        this.errorId = b.errorId; -        this.message = b.message; -    } - -    public int getErrorId() { -        return errorId; -    } - -    public void setErrorId(int errorId) { -        this.errorId = errorId; -    } - -    public String getMessage() { -        return message; -    } - -    public void setMessage(String message) { -        this.message = message; -    } - -    public int describeContents() { -        return 0; -    } - -    public void writeToParcel(Parcel dest, int flags) { -        /** -         * NOTE: When adding fields in the process of updating this API, make sure to bump -         * {@link #PARCELABLE_VERSION}. -         */ -        dest.writeInt(PARCELABLE_VERSION); -        // Inject a placeholder that will store the parcel size from this point on -        // (not including the size itself). -        int sizePosition = dest.dataPosition(); -        dest.writeInt(0); -        int startPosition = dest.dataPosition(); -        // version 1 -        dest.writeInt(errorId); -        dest.writeString(message); -        // Go back and write the size -        int parcelableSize = dest.dataPosition() - startPosition; -        dest.setDataPosition(sizePosition); -        dest.writeInt(parcelableSize); -        dest.setDataPosition(startPosition + parcelableSize); -    } - -    public static final Creator<OpenPgpError> CREATOR = new Creator<OpenPgpError>() { -        public OpenPgpError createFromParcel(final Parcel source) { -            int parcelableVersion = source.readInt(); -            int parcelableSize = source.readInt(); -            int startPosition = source.dataPosition(); - -            OpenPgpError error = new OpenPgpError(); -            error.errorId = source.readInt(); -            error.message = source.readString(); - -            // skip over all fields added in future versions of this parcel -            source.setDataPosition(startPosition + parcelableSize); - -            return error; -        } - -        public OpenPgpError[] newArray(final int size) { -            return new OpenPgpError[size]; -        } -    }; -} diff --git a/src/main/java/org/openintents/openpgp/OpenPgpMetadata.java b/src/main/java/org/openintents/openpgp/OpenPgpMetadata.java deleted file mode 100644 index d620a57..0000000 --- a/src/main/java/org/openintents/openpgp/OpenPgpMetadata.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Parcelable versioning has been copied from Dashclock Widget - * https://code.google.com/p/dashclock/source/browse/api/src/main/java/com/google/android/apps/dashclock/api/ExtensionData.java - */ -public class OpenPgpMetadata implements Parcelable { -    /** -     * Since there might be a case where new versions of the client using the library getting -     * old versions of the protocol (and thus old versions of this class), we need a versioning -     * system for the parcels sent between the clients and the providers. -     */ -    public static final int PARCELABLE_VERSION = 1; - -    String filename; -    String mimeType; -    long modificationTime; -    long originalSize; - -    public String getFilename() { -        return filename; -    } - -    public String getMimeType() { -        return mimeType; -    } - -    public long getModificationTime() { -        return modificationTime; -    } - -    public long getOriginalSize() { -        return originalSize; -    } - -    public OpenPgpMetadata() { -    } - -    public OpenPgpMetadata(String filename, String mimeType, long modificationTime, -                           long originalSize) { -        this.filename = filename; -        this.mimeType = mimeType; -        this.modificationTime = modificationTime; -        this.originalSize = originalSize; -    } - -    public OpenPgpMetadata(OpenPgpMetadata b) { -        this.filename = b.filename; -        this.mimeType = b.mimeType; -        this.modificationTime = b.modificationTime; -        this.originalSize = b.originalSize; -    } - -    public int describeContents() { -        return 0; -    } - -    public void writeToParcel(Parcel dest, int flags) { -        /** -         * NOTE: When adding fields in the process of updating this API, make sure to bump -         * {@link #PARCELABLE_VERSION}. -         */ -        dest.writeInt(PARCELABLE_VERSION); -        // Inject a placeholder that will store the parcel size from this point on -        // (not including the size itself). -        int sizePosition = dest.dataPosition(); -        dest.writeInt(0); -        int startPosition = dest.dataPosition(); -        // version 1 -        dest.writeString(filename); -        dest.writeString(mimeType); -        dest.writeLong(modificationTime); -        dest.writeLong(originalSize); -        // Go back and write the size -        int parcelableSize = dest.dataPosition() - startPosition; -        dest.setDataPosition(sizePosition); -        dest.writeInt(parcelableSize); -        dest.setDataPosition(startPosition + parcelableSize); -    } - -    public static final Creator<OpenPgpMetadata> CREATOR = new Creator<OpenPgpMetadata>() { -        public OpenPgpMetadata createFromParcel(final Parcel source) { -            int parcelableVersion = source.readInt(); -            int parcelableSize = source.readInt(); -            int startPosition = source.dataPosition(); - -            OpenPgpMetadata vr = new OpenPgpMetadata(); -            vr.filename = source.readString(); -            vr.mimeType = source.readString(); -            vr.modificationTime = source.readLong(); -            vr.originalSize = source.readLong(); - -            // skip over all fields added in future versions of this parcel -            source.setDataPosition(startPosition + parcelableSize); - -            return vr; -        } - -        public OpenPgpMetadata[] newArray(final int size) { -            return new OpenPgpMetadata[size]; -        } -    }; - -    @Override -    public String toString() { -        String out = "\nfilename: " + filename; -        out += "\nmimeType: " + mimeType; -        out += "\nmodificationTime: " + modificationTime; -        out += "\noriginalSize: " + originalSize; -        return out; -    } - -} diff --git a/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java b/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java deleted file mode 100644 index 7eb06d9..0000000 --- a/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp; - -import android.os.Parcel; -import android.os.Parcelable; - -import org.openintents.openpgp.util.OpenPgpUtils; - -import java.util.ArrayList; -import java.util.Locale; - -/** - * Parcelable versioning has been copied from Dashclock Widget - * https://code.google.com/p/dashclock/source/browse/api/src/main/java/com/google/android/apps/dashclock/api/ExtensionData.java - */ -public class OpenPgpSignatureResult implements Parcelable { -    /** -     * Since there might be a case where new versions of the client using the library getting -     * old versions of the protocol (and thus old versions of this class), we need a versioning -     * system for the parcels sent between the clients and the providers. -     */ -    public static final int PARCELABLE_VERSION = 2; - -    // generic error on signature verification -    public static final int SIGNATURE_ERROR = 0; -    // successfully verified signature, with certified key -    public static final int SIGNATURE_SUCCESS_CERTIFIED = 1; -    // no key was found for this signature verification -    public static final int SIGNATURE_KEY_MISSING = 2; -    // successfully verified signature, but with uncertified key -    public static final int SIGNATURE_SUCCESS_UNCERTIFIED = 3; -    // key has been revoked -    public static final int SIGNATURE_KEY_REVOKED = 4; -    // key is expired -    public static final int SIGNATURE_KEY_EXPIRED = 5; - -    int status; -    boolean signatureOnly; -    String primaryUserId; -    ArrayList<String> userIds; -    long keyId; - -    public int getStatus() { -        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 getPrimaryUserId() { -        return primaryUserId; -    } - -    public void setPrimaryUserId(String primaryUserId) { -        this.primaryUserId = primaryUserId; -    } - -    public ArrayList<String> getUserIds() { -        return userIds; -    } - -    public void setUserIds(ArrayList<String> userIds) { -        this.userIds = userIds; -    } - -    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, ArrayList<String> userIds) { -        this.status = signatureStatus; -        this.signatureOnly = signatureOnly; -        this.primaryUserId = signatureUserId; -        this.keyId = keyId; -        this.userIds = userIds; -    } - -    public OpenPgpSignatureResult(OpenPgpSignatureResult b) { -        this.status = b.status; -        this.primaryUserId = b.primaryUserId; -        this.signatureOnly = b.signatureOnly; -        this.keyId = b.keyId; -        this.userIds = b.userIds; -    } - -    public int describeContents() { -        return 0; -    } - -    public void writeToParcel(Parcel dest, int flags) { -        /** -         * NOTE: When adding fields in the process of updating this API, make sure to bump -         * {@link #PARCELABLE_VERSION}. -         */ -        dest.writeInt(PARCELABLE_VERSION); -        // Inject a placeholder that will store the parcel size from this point on -        // (not including the size itself). -        int sizePosition = dest.dataPosition(); -        dest.writeInt(0); -        int startPosition = dest.dataPosition(); -        // version 1 -        dest.writeInt(status); -        dest.writeByte((byte) (signatureOnly ? 1 : 0)); -        dest.writeString(primaryUserId); -        dest.writeLong(keyId); -        // version 2 -        dest.writeStringList(userIds); -        // Go back and write the size -        int parcelableSize = dest.dataPosition() - startPosition; -        dest.setDataPosition(sizePosition); -        dest.writeInt(parcelableSize); -        dest.setDataPosition(startPosition + parcelableSize); -    } - -    public static final Creator<OpenPgpSignatureResult> CREATOR = new Creator<OpenPgpSignatureResult>() { -        public OpenPgpSignatureResult createFromParcel(final Parcel source) { -            int parcelableVersion = source.readInt(); -            int parcelableSize = source.readInt(); -            int startPosition = source.dataPosition(); - -            OpenPgpSignatureResult vr = new OpenPgpSignatureResult(); -            vr.status = source.readInt(); -            vr.signatureOnly = source.readByte() == 1; -            vr.primaryUserId = source.readString(); -            vr.keyId = source.readLong(); -            vr.userIds = new ArrayList<String>(); -            source.readStringList(vr.userIds); - -            // skip over all fields added in future versions of this parcel -            source.setDataPosition(startPosition + parcelableSize); - -            return vr; -        } - -        public OpenPgpSignatureResult[] newArray(final int size) { -            return new OpenPgpSignatureResult[size]; -        } -    }; - -    @Override -    public String toString() { -        String out = "\nstatus: " + status; -        out += "\nprimaryUserId: " + primaryUserId; -        out += "\nuserIds: " + userIds; -        out += "\nsignatureOnly: " + signatureOnly; -        out += "\nkeyId: " + OpenPgpUtils.convertKeyIdToHex(keyId); -        return out; -    } - -} diff --git a/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java b/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java deleted file mode 100644 index cd1edc5..0000000 --- a/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.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.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class OpenPgpApi { - -    public static final String TAG = "OpenPgp API"; - -    public static final String SERVICE_INTENT = "org.openintents.openpgp.IOpenPgpService"; - -    /** -     * Version history -     * --------------- -     * <p/> -     * 3: -     * - First public stable version -     * <p/> -     * 4: -     * - No changes to existing methods -> backward compatible -     * - Introduction of ACTION_DECRYPT_METADATA, RESULT_METADATA, EXTRA_ORIGINAL_FILENAME, and OpenPgpMetadata parcel -     * - Introduction of internal NFC extras: EXTRA_NFC_SIGNED_HASH, EXTRA_NFC_SIG_CREATION_TIMESTAMP -     * 5: -     * - OpenPgpSignatureResult: new consts SIGNATURE_KEY_REVOKED and SIGNATURE_KEY_EXPIRED -     * - OpenPgpSignatureResult: ArrayList<String> userIds -     * 6: -     * - Deprecate ACTION_SIGN -     * - Introduce ACTION_CLEARTEXT_SIGN and ACTION_DETACHED_SIGN -     * - New extra for ACTION_DETACHED_SIGN: EXTRA_DETACHED_SIGNATURE -     * - New result for ACTION_DECRYPT_VERIFY: RESULT_DETACHED_SIGNATURE -     * - New result for ACTION_DECRYPT_VERIFY: RESULT_CHARSET -     * 7: -     * - Deprecation of ACCOUNT_NAME, please use ACTION_GET_SIGN_KEY_ID to get key id -     * - Introduce EXTRA_SIGN_KEY_ID -     * - New extra for ACTION_ENCRYPT and ACTION_SIGN_AND_ENCRYPT: EXTRA_ENABLE_COMPRESSION (default to true) -     * - Return PendingIntent to view key for signatures -     * - New result for ACTION_DECRYPT_VERIFY: RESULT_TYPE -     * - New ACTION_GET_SIGN_KEY_ID -     * - EXTRA_PASSPHRASE changed from String to char[] -     */ -    public static final int API_VERSION = 7; - -    /** -     * General extras -     * -------------- -     * -     * required extras: -     * int           EXTRA_API_VERSION           (always required) -     * -     * 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) -     */ - -    /** -     * DEPRECATED -     * Same as ACTION_CLEARTEXT_SIGN -     * <p/> -     * optional extras: -     * boolean       EXTRA_REQUEST_ASCII_ARMOR   (DEPRECATED: this makes no sense here) -     * char[]        EXTRA_PASSPHRASE            (key passphrase) -     */ -    public static final String ACTION_SIGN = "org.openintents.openpgp.action.SIGN"; - -    /** -     * Sign text resulting in a cleartext signature -     * Some magic pre-processing of the text is done to convert it to a format usable for -     * cleartext signatures per RFC 4880 before the text is actually signed: -     * - end cleartext with newline -     * - remove whitespaces on line endings -     * <p/> -     * required extras: -     * long          EXTRA_SIGN_KEY_ID           (key id of signing key) -     * <p/> -     * optional extras: -     * char[]        EXTRA_PASSPHRASE            (key passphrase) -     */ -    public static final String ACTION_CLEARTEXT_SIGN = "org.openintents.openpgp.action.CLEARTEXT_SIGN"; - -    /** -     * Sign text or binary data resulting in a detached signature. -     * No OutputStream necessary for ACTION_DETACHED_SIGN (No magic pre-processing like in ACTION_CLEARTEXT_SIGN)! -     * The detached signature is returned separately in RESULT_DETACHED_SIGNATURE. -     * <p/> -     * required extras: -     * long          EXTRA_SIGN_KEY_ID           (key id of signing key) -     * <p/> -     * optional extras: -     * boolean       EXTRA_REQUEST_ASCII_ARMOR   (request ascii armor for detached signature) -     * char[]        EXTRA_PASSPHRASE            (key passphrase) -     * <p/> -     * returned extras: -     * byte[]        RESULT_DETACHED_SIGNATURE -     */ -    public static final String ACTION_DETACHED_SIGN = "org.openintents.openpgp.action.DETACHED_SIGN"; - -    /** -     * Encrypt -     * <p/> -     * 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 -     * <p/> -     * optional extras: -     * boolean       EXTRA_REQUEST_ASCII_ARMOR   (request ascii armor for output) -     * char[]        EXTRA_PASSPHRASE            (key passphrase) -     * String        EXTRA_ORIGINAL_FILENAME     (original filename to be encrypted as metadata) -     * boolean       EXTRA_ENABLE_COMPRESSION    (enable ZLIB compression, default ist true) -     */ -    public static final String ACTION_ENCRYPT = "org.openintents.openpgp.action.ENCRYPT"; - -    /** -     * Sign and encrypt -     * <p/> -     * 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 -     * <p/> -     * optional extras: -     * long          EXTRA_SIGN_KEY_ID           (key id of signing key) -     * boolean       EXTRA_REQUEST_ASCII_ARMOR   (request ascii armor for output) -     * char[]        EXTRA_PASSPHRASE            (key passphrase) -     * String        EXTRA_ORIGINAL_FILENAME     (original filename to be encrypted as metadata) -     * boolean       EXTRA_ENABLE_COMPRESSION    (enable ZLIB compression, default ist true) -     */ -    public static final String ACTION_SIGN_AND_ENCRYPT = "org.openintents.openpgp.action.SIGN_AND_ENCRYPT"; - -    /** -     * Decrypts and verifies given input stream. This methods handles encrypted-only, signed-and-encrypted, -     * and also signed-only input. -     * OutputStream is optional, e.g., for verifying detached signatures! -     * <p/> -     * If OpenPgpSignatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_KEY_MISSING -     * in addition a PendingIntent is returned via RESULT_INTENT to download missing keys. -     * On all other status, in addition a PendingIntent is returned via RESULT_INTENT to open -     * the key view in OpenKeychain. -     * <p/> -     * optional extras: -     * byte[]        EXTRA_DETACHED_SIGNATURE    (detached signature) -     * <p/> -     * returned extras: -     * OpenPgpSignatureResult   RESULT_SIGNATURE -     * OpenPgpDecryptMetadata   RESULT_METADATA -     * String                   RESULT_CHARSET   (charset which was specified in the headers of ascii armored input, if any) -     * int                      RESULT_TYPE -     */ -    public static final String ACTION_DECRYPT_VERIFY = "org.openintents.openpgp.action.DECRYPT_VERIFY"; - -    /** -     * Decrypts the header of an encrypted file to retrieve metadata such as original filename. -     * <p/> -     * This does not decrypt the actual content of the file. -     * <p/> -     * returned extras: -     * OpenPgpDecryptMetadata   RESULT_METADATA -     * String                   RESULT_CHARSET   (charset which was specified in the headers of ascii armored input, if any) -     */ -    public static final String ACTION_DECRYPT_METADATA = "org.openintents.openpgp.action.DECRYPT_METADATA"; - -    /** -     * Select key id for signing -     * <p/> -     * optional extras: -     * String      EXTRA_USER_ID -     * <p/> -     * returned extras: -     * long        EXTRA_SIGN_KEY_ID -     */ -    public static final String ACTION_GET_SIGN_KEY_ID = "org.openintents.openpgp.action.GET_SIGN_KEY_ID"; - -    /** -     * Get key ids based on given user ids (=emails) -     * <p/> -     * required extras: -     * String[]      EXTRA_USER_IDS -     * <p/> -     * returned extras: -     * long[]        RESULT_KEY_IDS -     */ -    public static final String ACTION_GET_KEY_IDS = "org.openintents.openpgp.action.GET_KEY_IDS"; - -    /** -     * This action returns RESULT_CODE_SUCCESS if the OpenPGP Provider already has the key -     * corresponding to the given key id in its database. -     * <p/> -     * 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. -     * <p/> -     * 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"; - -    // DEPRECATED!!! -    public static final String EXTRA_ACCOUNT_NAME = "account_name"; - -    // ACTION_DETACHED_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"; - -    // ACTION_DETACHED_SIGN -    public static final String RESULT_DETACHED_SIGNATURE = "detached_signature"; - -    // ENCRYPT, SIGN_AND_ENCRYPT -    public static final String EXTRA_USER_IDS = "user_ids"; -    public static final String EXTRA_KEY_IDS = "key_ids"; -    public static final String EXTRA_SIGN_KEY_ID = "sign_key_id"; -    // optional extras: -    public static final String EXTRA_PASSPHRASE = "passphrase"; -    public static final String EXTRA_ORIGINAL_FILENAME = "original_filename"; -    public static final String EXTRA_ENABLE_COMPRESSION = "enable_compression"; - -    // GET_SIGN_KEY_ID -    public static final String EXTRA_USER_ID = "user_id"; - -    // GET_KEY -    public static final String EXTRA_KEY_ID = "key_id"; -    public static final String RESULT_KEY_IDS = "key_ids"; - -    /* Service Intent returns */ -    public static final String RESULT_CODE = "result_code"; - -    // get actual error object from RESULT_ERROR -    public static final int RESULT_CODE_ERROR = 0; -    // success! -    public static final int RESULT_CODE_SUCCESS = 1; -    // 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 EXTRA_DETACHED_SIGNATURE = "detached_signature"; -    public static final String RESULT_SIGNATURE = "signature"; -    public static final String RESULT_METADATA = "metadata"; -    // This will be the charset which was specified in the headers of ascii armored input, if any -    public static final String RESULT_CHARSET = "charset"; - -    public static final String RESULT_TYPE = "type"; -    public static final int RESULT_TYPE_UNENCRYPTED_UNSIGNED = 0; -    public static final int RESULT_TYPE_ENCRYPTED = 1; -    public static final int RESULT_TYPE_SIGNED = 2; - -    // INTERNAL, should not be used -    public static final String EXTRA_CALL_UUID1 = "call_uuid1"; -    public static final String EXTRA_CALL_UUID2 = "call_uuid2"; - -    IOpenPgpService mService; -    Context mContext; - -    public OpenPgpApi(Context context, IOpenPgpService service) { -        this.mContext = context; -        this.mService = service; -    } - -    public interface IOpenPgpCallback { -        void onReturn(final Intent result); -    } - -    private class OpenPgpAsyncTask extends AsyncTask<Void, Integer, Intent> { -        Intent data; -        InputStream is; -        OutputStream os; -        IOpenPgpCallback callback; - -        private OpenPgpAsyncTask(Intent data, InputStream is, OutputStream os, IOpenPgpCallback callback) { -            this.data = data; -            this.is = is; -            this.os = os; -            this.callback = callback; -        } - -        @Override -        protected Intent doInBackground(Void... unused) { -            return executeApi(data, is, os); -        } - -        protected void onPostExecute(Intent result) { -            callback.onReturn(result); -        } - -    } - -    @TargetApi(Build.VERSION_CODES.HONEYCOMB) -    public void executeApiAsync(Intent data, InputStream is, OutputStream os, IOpenPgpCallback callback) { -        OpenPgpAsyncTask task = new OpenPgpAsyncTask(data, is, os, callback); - -        // don't serialize async tasks! -        // http://commonsware.com/blog/2012/04/20/asynctask-threading-regression-confirmed.html -        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { -            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); -        } else { -            task.execute((Void[]) null); -        } -    } - -    /** -     * InputStream and OutputStreams are always closed after operating on them! -     * -     * @param data -     * @param is -     * @param os -     * @return -     */ -    public Intent executeApi(Intent data, InputStream is, OutputStream os) { -        ParcelFileDescriptor input = null; -        ParcelFileDescriptor output = null; -        try { -            // always send version from client -            data.putExtra(EXTRA_API_VERSION, OpenPgpApi.API_VERSION); - -            Intent result; - -            // pipe the input and output -            if (is != null) { -                input = ParcelFileDescriptorUtil.pipeFrom(is, -                        new ParcelFileDescriptorUtil.IThreadListener() { - -                            @Override -                            public void onThreadFinished(Thread thread) { -                                //Log.d(OpenPgpApi.TAG, "Copy to service finished"); -                            } -                        } -                ); -            } -            if (os != null) { -                output = ParcelFileDescriptorUtil.pipeTo(os, -                        new ParcelFileDescriptorUtil.IThreadListener() { - -                            @Override -                            public void onThreadFinished(Thread thread) { -                                //Log.d(OpenPgpApi.TAG, "Service finished writing!"); -                            } -                        } -                ); -            } - -            // blocks until result is ready -            result = mService.execute(data, input, output); - -            // set class loader to current context to allow unparcelling -            // of OpenPgpError and OpenPgpSignatureResult -            // http://stackoverflow.com/a/3806769 -            result.setExtrasClassLoader(mContext.getClassLoader()); - -            return result; -        } catch (Exception e) { -            Log.e(OpenPgpApi.TAG, "Exception in executeApi call", e); -            Intent result = new Intent(); -            result.putExtra(RESULT_CODE, RESULT_CODE_ERROR); -            result.putExtra(RESULT_ERROR, -                    new OpenPgpError(OpenPgpError.CLIENT_SIDE_ERROR, e.getMessage())); -            return result; -        } finally { -            // close() is required to halt the TransferThread -            if (output != null) { -                try { -                    output.close(); -                } catch (IOException e) { -                    Log.e(OpenPgpApi.TAG, "IOException when closing ParcelFileDescriptor!", e); -                } -            } -            if (input != null) { -                try { -                    input.close(); -                } catch (IOException e) { -                    Log.e(OpenPgpApi.TAG, "IOException when closing ParcelFileDescriptor!", e); -                } -            } -        } -    } - -} diff --git a/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java b/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java deleted file mode 100644 index 4bf4cec..0000000 --- a/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp.util; - -import android.app.AlertDialog.Builder; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.ResolveInfo; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.preference.DialogPreference; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.util.Log; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ListAdapter; -import android.widget.TextView; - -import org.openintents.openpgp.R; - -import java.util.ArrayList; -import java.util.List; - -/** - * Does not extend ListPreference, but is very similar to it! - * http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/android/preference/ListPreference.java/?v=source - */ -public class OpenPgpAppPreference extends DialogPreference { -    private static final String OPENKEYCHAIN_PACKAGE = "org.sufficientlysecure.keychain"; -    private static final String MARKET_INTENT_URI_BASE = "market://details?id=%s"; -    private static final Intent MARKET_INTENT = new Intent(Intent.ACTION_VIEW, Uri.parse( -            String.format(MARKET_INTENT_URI_BASE, OPENKEYCHAIN_PACKAGE))); - -    private static final ArrayList<String> PROVIDER_BLACKLIST = new ArrayList<String>(); - -    static { -        // Unfortunately, the current released version of APG includes a broken version of the API -        PROVIDER_BLACKLIST.add("org.thialfihar.android.apg"); -    } - -    private ArrayList<OpenPgpProviderEntry> mLegacyList = new ArrayList<>(); -    private ArrayList<OpenPgpProviderEntry> mList = new ArrayList<>(); - -    private String mSelectedPackage; - -    public OpenPgpAppPreference(Context context, AttributeSet attrs) { -        super(context, attrs); -        populateAppList(); -    } - -    public OpenPgpAppPreference(Context context) { -        this(context, null); -    } - -    /** -     * Public method to add new entries for legacy applications -     * -     * @param packageName -     * @param simpleName -     * @param icon -     */ -    public void addLegacyProvider(int position, String packageName, String simpleName, Drawable icon) { -        mLegacyList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon)); -    } - -    @Override -    protected void onPrepareDialogBuilder(Builder builder) { - -        // do again, maybe an app has now been installed -        populateAppList(); - -        // Init ArrayAdapter with OpenPGP Providers -        ListAdapter adapter = new ArrayAdapter<OpenPgpProviderEntry>(getContext(), -                android.R.layout.select_dialog_singlechoice, android.R.id.text1, mList) { -            public View getView(int position, View convertView, ViewGroup parent) { -                // User super class to create the View -                View v = super.getView(position, convertView, parent); -                TextView tv = (TextView) v.findViewById(android.R.id.text1); - -                // Put the image on the TextView -                tv.setCompoundDrawablesWithIntrinsicBounds(mList.get(position).icon, null, -                        null, null); - -                // Add margin between image and text (support various screen densities) -                int dp10 = (int) (10 * getContext().getResources().getDisplayMetrics().density + 0.5f); -                tv.setCompoundDrawablePadding(dp10); - -                return v; -            } -        }; - -        builder.setSingleChoiceItems(adapter, getIndexOfProviderList(mSelectedPackage), -                new DialogInterface.OnClickListener() { - -                    @Override -                    public void onClick(DialogInterface dialog, int which) { -                        OpenPgpProviderEntry entry = mList.get(which); - -                        if (entry.intent != null) { -                            /* -                             * Intents are called as activity -                             * -                             * Current approach is to assume the user installed the app. -                             * If he does not, the selected package is not valid. -                             * -                             * However  applications should always consider this could happen, -                             * as the user might remove the currently used OpenPGP app. -                             */ -                            getContext().startActivity(entry.intent); -                            return; -                        } - -                        mSelectedPackage = entry.packageName; - -                        /* -                         * Clicking on an item simulates the positive button click, and dismisses -                         * the dialog. -                         */ -                        OpenPgpAppPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE); -                        dialog.dismiss(); -                    } -                }); - -        /* -         * The typical interaction for list-based dialogs is to have click-on-an-item dismiss the -         * dialog instead of the user having to press 'Ok'. -         */ -        builder.setPositiveButton(null, null); -    } - -    @Override -    protected void onDialogClosed(boolean positiveResult) { -        super.onDialogClosed(positiveResult); - -        if (positiveResult && (mSelectedPackage != null)) { -            save(); -        } -    } - -    private void save() { -        // Give the client a chance to ignore this change if they deem it -        // invalid -        if (!callChangeListener(mSelectedPackage)) { -            // They don't want the value to be set -            return; -        } - -        setAndPersist(mSelectedPackage); -    } - -    private void setAndPersist(String packageName) { -        mSelectedPackage = packageName; - -        // Save to persistent storage (this method will make sure this -        // preference should be persistent, along with other useful checks) -        persistString(mSelectedPackage); - -        // Data has changed, notify so UI can be refreshed! -        notifyChanged(); - -        // also update summary with selected provider -        updateSummary(mSelectedPackage); -    } - -    private void updateSummary(String packageName) { -        String summary = getEntryByValue(packageName); -        setSummary(summary); -    } - -    @Override -    public CharSequence getSummary() { -        return getEntryByValue(mSelectedPackage); -    } - -    private int getIndexOfProviderList(String packageName) { -        for (OpenPgpProviderEntry app : mList) { -            if (app.packageName.equals(packageName)) { -                return mList.indexOf(app); -            } -        } - -        // default is "none" -        return 0; -    } - -    /** -     * Public API -     */ -    public String getEntry() { -        return getEntryByValue(mSelectedPackage); -    } - -    /** -     * Public API -     */ -    public String getValue() { -        return mSelectedPackage; -    } - -    /** -     * Public API -     */ -    public void setValue(String packageName) { -        setAndPersist(packageName); -    } - -    @Override -    protected Object onGetDefaultValue(TypedArray a, int index) { -        return a.getString(index); -    } - -    @Override -    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { -        if (restoreValue) { -            // Restore state -            mSelectedPackage = getPersistedString(mSelectedPackage); -            updateSummary(mSelectedPackage); -        } else { -            String value = (String) defaultValue; -            setAndPersist(value); -            updateSummary(value); -        } -    } - -    public String getEntryByValue(String packageName) { -        for (OpenPgpProviderEntry app : mList) { -            if (app.packageName.equals(packageName) && app.intent == null) { -                return app.simpleName; -            } -        } - -        return getContext().getString(R.string.openpgp_list_preference_none); -    } - -    private void populateAppList() { -        mList.clear(); - -        // add "none"-entry -        mList.add(0, new OpenPgpProviderEntry("", -                getContext().getString(R.string.openpgp_list_preference_none), -                getContext().getResources().getDrawable(R.drawable.ic_action_cancel_launchersize))); - -        // add all additional (legacy) providers -        mList.addAll(mLegacyList); - -        // search for OpenPGP providers... -        ArrayList<OpenPgpProviderEntry> providerList = new ArrayList<>(); -        Intent intent = new Intent(OpenPgpApi.SERVICE_INTENT); -        List<ResolveInfo> resInfo = getContext().getPackageManager().queryIntentServices(intent, 0); -        if (!resInfo.isEmpty()) { -            for (ResolveInfo resolveInfo : resInfo) { -                if (resolveInfo.serviceInfo == null) -                    continue; - -                String packageName = resolveInfo.serviceInfo.packageName; -                String simpleName = String.valueOf(resolveInfo.serviceInfo.loadLabel(getContext() -                        .getPackageManager())); -                Drawable icon = resolveInfo.serviceInfo.loadIcon(getContext().getPackageManager()); - -                if (!PROVIDER_BLACKLIST.contains(packageName)) { -                    providerList.add(new OpenPgpProviderEntry(packageName, simpleName, icon)); -                } -            } -        } - -        if (providerList.isEmpty()) { -            // add install links if provider list is empty -            resInfo = getContext().getPackageManager().queryIntentActivities -                    (MARKET_INTENT, 0); -            for (ResolveInfo resolveInfo : resInfo) { -                Intent marketIntent = new Intent(MARKET_INTENT); -                marketIntent.setPackage(resolveInfo.activityInfo.packageName); -                Drawable icon = resolveInfo.activityInfo.loadIcon(getContext().getPackageManager()); -                String marketName = String.valueOf(resolveInfo.activityInfo.applicationInfo -                        .loadLabel(getContext().getPackageManager())); -                String simpleName = String.format(getContext().getString(R.string -                        .openpgp_install_openkeychain_via), marketName); -                mList.add(new OpenPgpProviderEntry(OPENKEYCHAIN_PACKAGE, simpleName, -                        icon, marketIntent)); -            } -        } else { -            // add provider -            mList.addAll(providerList); -        } -    } - -    private static class OpenPgpProviderEntry { -        private String packageName; -        private String simpleName; -        private Drawable icon; -        private Intent intent; - -        public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon) { -            this.packageName = packageName; -            this.simpleName = simpleName; -            this.icon = icon; -        } - -        public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon, Intent intent) { -            this(packageName, simpleName, icon); -            this.intent = intent; -        } - -        @Override -        public String toString() { -            return simpleName; -        } -    } -} diff --git a/src/main/java/org/openintents/openpgp/util/OpenPgpKeyPreference.java b/src/main/java/org/openintents/openpgp/util/OpenPgpKeyPreference.java deleted file mode 100644 index 6343285..0000000 --- a/src/main/java/org/openintents/openpgp/util/OpenPgpKeyPreference.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp.util; - -import android.app.Activity; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.IntentSender; -import android.content.res.TypedArray; -import android.os.Parcel; -import android.os.Parcelable; -import android.preference.Preference; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.util.Log; - -import org.openintents.openpgp.IOpenPgpService; -import org.openintents.openpgp.OpenPgpError; -import org.openintents.openpgp.R; - -public class OpenPgpKeyPreference extends Preference { -    private long mKeyId; -    private String mOpenPgpProvider; -    private OpenPgpServiceConnection mServiceConnection; -    private String mDefaultUserId; - -    public static final int REQUEST_CODE_KEY_PREFERENCE = 9999; - -    public OpenPgpKeyPreference(Context context, AttributeSet attrs) { -        super(context, attrs); -    } - -    @Override -    public CharSequence getSummary() { -        return (mKeyId == 0) ? getContext().getString(R.string.openpgp_no_key_selected) -                : getContext().getString(R.string.openpgp_key_selected); -    } - -    private void updateEnabled() { -        if (TextUtils.isEmpty(mOpenPgpProvider)) { -            setEnabled(false); -        } else { -            setEnabled(true); -        } -    } - -    public void setOpenPgpProvider(String packageName) { -        mOpenPgpProvider = packageName; -        updateEnabled(); -    } - -    public void setDefaultUserId(String userId) { -        mDefaultUserId = userId; -    } - -    @Override -    protected void onClick() { -        // bind to service -        mServiceConnection = new OpenPgpServiceConnection( -                getContext().getApplicationContext(), -                mOpenPgpProvider, -                new OpenPgpServiceConnection.OnBound() { -                    @Override -                    public void onBound(IOpenPgpService service) { -                        Log.d(OpenPgpApi.TAG, "onBound!"); - -                        Intent data = new Intent(); -                        data.setAction(OpenPgpApi.ACTION_GET_SIGN_KEY_ID); -                        data.putExtra(OpenPgpApi.EXTRA_USER_ID, mDefaultUserId); - -                        OpenPgpApi api = new OpenPgpApi(getContext(), mServiceConnection.getService()); -                        api.executeApiAsync(data, null, null, new MyCallback(REQUEST_CODE_KEY_PREFERENCE)); -                    } - -                    @Override -                    public void onError(Exception e) { -                        Log.e(OpenPgpApi.TAG, "exception when binding!", e); -                    } -                } -        ); -        mServiceConnection.bindToService(); -    } - -    private class MyCallback implements OpenPgpApi.IOpenPgpCallback { -        int requestCode; - -        private MyCallback(int requestCode) { -            this.requestCode = requestCode; -        } - -        @Override -        public void onReturn(Intent result) { -            switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { -                case OpenPgpApi.RESULT_CODE_SUCCESS: { -                    Log.e(OpenPgpApi.TAG, "RESULT_CODE_SUCCESS: Should not happen!"); - -                    break; -                } -                case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: { - -                    PendingIntent pi = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT); -                    try { -                        Activity act = (Activity) getContext(); -                        act.startIntentSenderFromChild( -                                act, pi.getIntentSender(), -                                requestCode, null, 0, 0, 0); -                    } catch (IntentSender.SendIntentException e) { -                        Log.e(OpenPgpApi.TAG, "SendIntentException", e); -                    } -                    break; -                } -                case OpenPgpApi.RESULT_CODE_ERROR: { -                    OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR); -                    Log.e(OpenPgpApi.TAG, "RESULT_CODE_ERROR: " + error.getMessage()); - -                    break; -                } -            } -        } -    } - -    private void save(long newValue) { -        // Give the client a chance to ignore this change if they deem it -        // invalid -        if (!callChangeListener(newValue)) { -            // They don't want the value to be set -            return; -        } - -        setAndPersist(newValue); -    } - -    /** -     * Public API -     */ -    public void setValue(long keyId) { -        setAndPersist(keyId); -    } - -    /** -     * Public API -     */ -    public long getValue() { -        return mKeyId; -    } - -    private void setAndPersist(long newValue) { -        mKeyId = newValue; - -        // Save to persistent storage (this method will make sure this -        // preference should be persistent, along with other useful checks) -        persistLong(mKeyId); - -        // Data has changed, notify so UI can be refreshed! -        notifyChanged(); -    } - -    @Override -    protected Object onGetDefaultValue(TypedArray a, int index) { -        // This preference type's value type is Long, so we read the default -        // value from the attributes as an Integer. -        return (long) a.getInteger(index, 0); -    } - -    @Override -    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { -        if (restoreValue) { -            // Restore state -            mKeyId = getPersistedLong(mKeyId); -        } else { -            // Set state -            long value = (Long) defaultValue; -            setAndPersist(value); -        } -    } - -    @Override -    protected Parcelable onSaveInstanceState() { -        /* -         * Suppose a client uses this preference type without persisting. We -         * must save the instance state so it is able to, for example, survive -         * orientation changes. -         */ - -        final Parcelable superState = super.onSaveInstanceState(); -        if (isPersistent()) { -            // No need to save instance state since it's persistent -            return superState; -        } - -        // Save the instance state -        final SavedState myState = new SavedState(superState); -        myState.keyId = mKeyId; -        myState.openPgpProvider = mOpenPgpProvider; -        myState.defaultUserId = mDefaultUserId; -        return myState; -    } - -    @Override -    protected void onRestoreInstanceState(Parcelable state) { -        if (!state.getClass().equals(SavedState.class)) { -            // Didn't save state for us in onSaveInstanceState -            super.onRestoreInstanceState(state); -            return; -        } - -        // Restore the instance state -        SavedState myState = (SavedState) state; -        super.onRestoreInstanceState(myState.getSuperState()); -        mKeyId = myState.keyId; -        mOpenPgpProvider = myState.openPgpProvider; -        mDefaultUserId = myState.defaultUserId; -        notifyChanged(); -    } - -    /** -     * SavedState, a subclass of {@link BaseSavedState}, will store the state -     * of MyPreference, a subclass of Preference. -     * <p/> -     * It is important to always call through to super methods. -     */ -    private static class SavedState extends BaseSavedState { -        long keyId; -        String openPgpProvider; -        String defaultUserId; - -        public SavedState(Parcel source) { -            super(source); - -            keyId = source.readInt(); -            openPgpProvider = source.readString(); -            defaultUserId = source.readString(); -        } - -        @Override -        public void writeToParcel(Parcel dest, int flags) { -            super.writeToParcel(dest, flags); - -            dest.writeLong(keyId); -            dest.writeString(openPgpProvider); -            dest.writeString(defaultUserId); -        } - -        public SavedState(Parcelable superState) { -            super(superState); -        } - -        public static final Parcelable.Creator<SavedState> CREATOR = -                new Parcelable.Creator<SavedState>() { -                    public SavedState createFromParcel(Parcel in) { -                        return new SavedState(in); -                    } - -                    public SavedState[] newArray(int size) { -                        return new SavedState[size]; -                    } -                }; -    } - -    public boolean handleOnActivityResult(int requestCode, int resultCode, Intent data) { -        if (requestCode == REQUEST_CODE_KEY_PREFERENCE && resultCode == Activity.RESULT_OK) { -            long keyId = data.getLongExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, 0); -            save(keyId); -            return true; -        } else { -            return false; -        } -    } - -}
\ No newline at end of file diff --git a/src/main/java/org/openintents/openpgp/util/OpenPgpServiceConnection.java b/src/main/java/org/openintents/openpgp/util/OpenPgpServiceConnection.java deleted file mode 100644 index bbc8645..0000000 --- a/src/main/java/org/openintents/openpgp/util/OpenPgpServiceConnection.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp.util; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.IBinder; - -import org.openintents.openpgp.IOpenPgpService; - -public class OpenPgpServiceConnection { - -    // callback interface -    public interface OnBound { -        public void onBound(IOpenPgpService service); - -        public void onError(Exception e); -    } - -    private Context mApplicationContext; - -    private IOpenPgpService mService; -    private String mProviderPackageName; - -    private OnBound mOnBoundListener; - -    /** -     * Create new connection -     * -     * @param context -     * @param providerPackageName specify package name of OpenPGP provider, -     *                            e.g., "org.sufficientlysecure.keychain" -     */ -    public OpenPgpServiceConnection(Context context, String providerPackageName) { -        this.mApplicationContext = context.getApplicationContext(); -        this.mProviderPackageName = providerPackageName; -    } - -    /** -     * Create new connection with callback -     * -     * @param context -     * @param providerPackageName specify package name of OpenPGP provider, -     *                            e.g., "org.sufficientlysecure.keychain" -     * @param onBoundListener     callback, executed when connection to service has been established -     */ -    public OpenPgpServiceConnection(Context context, String providerPackageName, -                                    OnBound onBoundListener) { -        this(context, providerPackageName); -        this.mOnBoundListener = onBoundListener; -    } - -    public IOpenPgpService getService() { -        return mService; -    } - -    public boolean isBound() { -        return (mService != null); -    } - -    private ServiceConnection mServiceConnection = new ServiceConnection() { -        public void onServiceConnected(ComponentName name, IBinder service) { -            mService = IOpenPgpService.Stub.asInterface(service); -            if (mOnBoundListener != null) { -                mOnBoundListener.onBound(mService); -            } -        } - -        public void onServiceDisconnected(ComponentName name) { -            mService = null; -        } -    }; - -    /** -     * If not already bound, bind to service! -     * -     * @return -     */ -    public void bindToService() { -        // if not already bound... -        if (mService == null) { -            try { -                Intent serviceIntent = new Intent(OpenPgpApi.SERVICE_INTENT); -                // NOTE: setPackage is very important to restrict the intent to this provider only! -                serviceIntent.setPackage(mProviderPackageName); -                boolean connect = mApplicationContext.bindService(serviceIntent, mServiceConnection, -                        Context.BIND_AUTO_CREATE); -                if (!connect) { -                    throw new Exception("bindService() returned false!"); -                } -            } catch (Exception e) { -                if (mOnBoundListener != null) { -                    mOnBoundListener.onError(e); -                } -            } -        } else { -            // already bound, but also inform client about it with callback -            if (mOnBoundListener != null) { -                mOnBoundListener.onBound(mService); -            } -        } -    } - -    public void unbindFromService() { -        mApplicationContext.unbindService(mServiceConnection); -    } - -} diff --git a/src/main/java/org/openintents/openpgp/util/OpenPgpUtils.java b/src/main/java/org/openintents/openpgp/util/OpenPgpUtils.java deleted file mode 100644 index ad5f47b..0000000 --- a/src/main/java/org/openintents/openpgp/util/OpenPgpUtils.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp.util; - -import java.util.List; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.ResolveInfo; -import android.text.TextUtils; - -public class OpenPgpUtils { - -    public static final Pattern PGP_MESSAGE = Pattern.compile( -            ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", -            Pattern.DOTALL); - -    public static final Pattern PGP_SIGNED_MESSAGE = Pattern.compile( -            ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", -            Pattern.DOTALL); - -    public static final int PARSE_RESULT_NO_PGP = -1; -    public static final int PARSE_RESULT_MESSAGE = 0; -    public static final int PARSE_RESULT_SIGNED_MESSAGE = 1; - -    public static int parseMessage(String message) { -        Matcher matcherSigned = PGP_SIGNED_MESSAGE.matcher(message); -        Matcher matcherMessage = PGP_MESSAGE.matcher(message); - -        if (matcherMessage.matches()) { -            return PARSE_RESULT_MESSAGE; -        } else if (matcherSigned.matches()) { -            return PARSE_RESULT_SIGNED_MESSAGE; -        } else { -            return PARSE_RESULT_NO_PGP; -        } -    } - -    public static boolean isAvailable(Context context) { -        Intent intent = new Intent(OpenPgpApi.SERVICE_INTENT); -        List<ResolveInfo> resInfo = context.getPackageManager().queryIntentServices(intent, 0); -        return !resInfo.isEmpty(); -    } - -    public static String convertKeyIdToHex(long keyId) { -        return "0x" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId); -    } - -    private static String convertKeyIdToHex32bit(long keyId) { -        String hexString = Long.toHexString(keyId & 0xffffffffL).toLowerCase(Locale.ENGLISH); -        while (hexString.length() < 8) { -            hexString = "0" + hexString; -        } -        return hexString; -    } - - -    private static final Pattern USER_ID_PATTERN = Pattern.compile("^(.*?)(?: \\((.*)\\))?(?: <(.*)>)?$"); - -    /** -     * Splits userId string into naming part, email part, and comment part -     * <p/> -     * User ID matching: -     * http://fiddle.re/t4p6f -     * -     * @param userId -     * @return theParsedUserInfo -     */ -    public static UserId splitUserId(final String userId) { -        if (!TextUtils.isEmpty(userId)) { -            final Matcher matcher = USER_ID_PATTERN.matcher(userId); -            if (matcher.matches()) { -                return new UserId(matcher.group(1), matcher.group(3), matcher.group(2)); -            } -        } -        return new UserId(null, null, null); -    } - -    /** -     * Returns a composed user id. Returns null if name is null! -     * -     * @param name -     * @param email -     * @param comment -     * @return -     */ -    public static String createUserId(UserId userId) { -        String userIdString = userId.name; // consider name a required value -        if (userIdString != null && !TextUtils.isEmpty(userId.comment)) { -            userIdString += " (" + userId.comment + ")"; -        } -        if (userIdString != null && !TextUtils.isEmpty(userId.email)) { -            userIdString += " <" + userId.email + ">"; -        } - -        return userIdString; -    } - -    public static class UserId { -        public final String name; -        public final String email; -        public final String comment; - -        public UserId(String name, String email, String comment) { -            this.name = name; -            this.email = email; -            this.comment = comment; -        } -    } -} diff --git a/src/main/java/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java b/src/main/java/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java deleted file mode 100644 index b9492f9..0000000 --- a/src/main/java/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de> - *               2013 Florian Schmaus <flo@geekplace.eu> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp.util; - -import android.os.ParcelFileDescriptor; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Partially based on <a href="http://stackoverflow.com/questions/18212152/">Stackoverflow: Transfer InputStream to another Service (across process boundaries)</a> - **/ -public class ParcelFileDescriptorUtil { - -    public interface IThreadListener { -        void onThreadFinished(final Thread thread); -    } - -    public static ParcelFileDescriptor pipeFrom(InputStream inputStream, IThreadListener listener) -            throws IOException { -        ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); -        ParcelFileDescriptor readSide = pipe[0]; -        ParcelFileDescriptor writeSide = pipe[1]; - -        // start the transfer thread -        new TransferThread(inputStream, new ParcelFileDescriptor.AutoCloseOutputStream(writeSide), -                listener) -                .start(); - -        return readSide; -    } - -    public static ParcelFileDescriptor pipeTo(OutputStream outputStream, IThreadListener listener) -            throws IOException { -        ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); -        ParcelFileDescriptor readSide = pipe[0]; -        ParcelFileDescriptor writeSide = pipe[1]; - -        // start the transfer thread -        new TransferThread(new ParcelFileDescriptor.AutoCloseInputStream(readSide), outputStream, -                listener) -                .start(); - -        return writeSide; -    } - -    static class TransferThread extends Thread { -        final InputStream mIn; -        final OutputStream mOut; -        final IThreadListener mListener; - -        TransferThread(InputStream in, OutputStream out, IThreadListener listener) { -            super("ParcelFileDescriptor Transfer Thread"); -            mIn = in; -            mOut = out; -            mListener = listener; -            setDaemon(true); -        } - -        @Override -        public void run() { -            byte[] buf = new byte[1024]; -            int len; - -            try { -                while ((len = mIn.read(buf)) > 0) { -                    mOut.write(buf, 0, len); -                } -                mOut.flush(); // just to be safe -            } catch (IOException e) { -                //Log.e(OpenPgpApi.TAG, "TransferThread" + getId() + ": writing failed", e); -            } finally { -                try { -                    mIn.close(); -                } catch (IOException e) { -                    //Log.e(OpenPgpApi.TAG, "TransferThread" + getId(), e); -                } -                try { -                    mOut.close(); -                } catch (IOException e) { -                    //Log.e(OpenPgpApi.TAG, "TransferThread" + getId(), e); -                } -            } -            if (mListener != null) { -                //Log.d(OpenPgpApi.TAG, "TransferThread " + getId() + " finished!"); -                mListener.onThreadFinished(this); -            } -        } -    } -} diff --git a/src/main/res/drawable-hdpi/ic_action_cancel_launchersize.png b/src/main/res/drawable-hdpi/ic_action_cancel_launchersize.pngBinary files differ deleted file mode 100644 index 71b9118..0000000 --- a/src/main/res/drawable-hdpi/ic_action_cancel_launchersize.png +++ /dev/null diff --git a/src/main/res/drawable-hdpi/ic_action_cancel_launchersize_light.png b/src/main/res/drawable-hdpi/ic_action_cancel_launchersize_light.pngBinary files differ deleted file mode 100644 index 73b1d08..0000000 --- a/src/main/res/drawable-hdpi/ic_action_cancel_launchersize_light.png +++ /dev/null diff --git a/src/main/res/drawable-mdpi/ic_action_cancel_launchersize.png b/src/main/res/drawable-mdpi/ic_action_cancel_launchersize.pngBinary files differ deleted file mode 100644 index 270abf4..0000000 --- a/src/main/res/drawable-mdpi/ic_action_cancel_launchersize.png +++ /dev/null diff --git a/src/main/res/drawable-mdpi/ic_action_cancel_launchersize_light.png b/src/main/res/drawable-mdpi/ic_action_cancel_launchersize_light.pngBinary files differ deleted file mode 100644 index d841821..0000000 --- a/src/main/res/drawable-mdpi/ic_action_cancel_launchersize_light.png +++ /dev/null diff --git a/src/main/res/drawable-xhdpi/ic_action_cancel_launchersize.png b/src/main/res/drawable-xhdpi/ic_action_cancel_launchersize.pngBinary files differ deleted file mode 100644 index 1e3571f..0000000 --- a/src/main/res/drawable-xhdpi/ic_action_cancel_launchersize.png +++ /dev/null diff --git a/src/main/res/drawable-xhdpi/ic_action_cancel_launchersize_light.png b/src/main/res/drawable-xhdpi/ic_action_cancel_launchersize_light.pngBinary files differ deleted file mode 100644 index d505046..0000000 --- a/src/main/res/drawable-xhdpi/ic_action_cancel_launchersize_light.png +++ /dev/null diff --git a/src/main/res/drawable-xxhdpi/ic_action_cancel_launchersize.png b/src/main/res/drawable-xxhdpi/ic_action_cancel_launchersize.pngBinary files differ deleted file mode 100644 index 5204460..0000000 --- a/src/main/res/drawable-xxhdpi/ic_action_cancel_launchersize.png +++ /dev/null diff --git a/src/main/res/drawable-xxhdpi/ic_action_cancel_launchersize_light.png b/src/main/res/drawable-xxhdpi/ic_action_cancel_launchersize_light.pngBinary files differ deleted file mode 100644 index d6fb86b..0000000 --- a/src/main/res/drawable-xxhdpi/ic_action_cancel_launchersize_light.png +++ /dev/null diff --git a/src/main/res/values-cs/strings.xml b/src/main/res/values-cs/strings.xml deleted file mode 100644 index c9fe1fa..0000000 --- a/src/main/res/values-cs/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources> -  <string name="openpgp_list_preference_none">Žádný</string> -  <string name="openpgp_install_openkeychain_via">Instalovat OpenKeychain pomocí %s</string> -</resources> diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml deleted file mode 100644 index 91e800a..0000000 --- a/src/main/res/values-de/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources> -  <string name="openpgp_list_preference_none">Keine Auswahl</string> -  <string name="openpgp_install_openkeychain_via">Installiere OpenKeychain mit %s</string> -</resources> diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml deleted file mode 100644 index da8979b..0000000 --- a/src/main/res/values-es/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources> -  <string name="openpgp_list_preference_none">Ninguno</string> -  <string name="openpgp_install_openkeychain_via">Instalar OpenKeychain mediante %s</string> -</resources> diff --git a/src/main/res/values-et/strings.xml b/src/main/res/values-et/strings.xml deleted file mode 100644 index c757504..0000000 --- a/src/main/res/values-et/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources/> diff --git a/src/main/res/values-fi/strings.xml b/src/main/res/values-fi/strings.xml deleted file mode 100644 index c757504..0000000 --- a/src/main/res/values-fi/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources/> diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml deleted file mode 100644 index 9b36df2..0000000 --- a/src/main/res/values-fr/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources> -  <string name="openpgp_list_preference_none">Aucun</string> -  <string name="openpgp_install_openkeychain_via">Installer OpenKeychain par %s</string> -</resources> diff --git a/src/main/res/values-is/strings.xml b/src/main/res/values-is/strings.xml deleted file mode 100644 index c757504..0000000 --- a/src/main/res/values-is/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources/> diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml deleted file mode 100644 index 23e8e80..0000000 --- a/src/main/res/values-it/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources> -  <string name="openpgp_list_preference_none">Nessuno</string> -  <string name="openpgp_install_openkeychain_via">Installa OpenKeychain via %s</string> -</resources> diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml deleted file mode 100644 index 5e337f5..0000000 --- a/src/main/res/values-ja/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources> -  <string name="openpgp_list_preference_none">無し</string> -  <string name="openpgp_install_openkeychain_via">%s 経由でOpenKeychainをインストール</string> -</resources> diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml deleted file mode 100644 index c757504..0000000 --- a/src/main/res/values-nl/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources/> diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml deleted file mode 100644 index c757504..0000000 --- a/src/main/res/values-pl/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources/> diff --git a/src/main/res/values-pt/strings.xml b/src/main/res/values-pt/strings.xml deleted file mode 100644 index c757504..0000000 --- a/src/main/res/values-pt/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources/> diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml deleted file mode 100644 index e8fd1dd..0000000 --- a/src/main/res/values-ru/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources> -  <string name="openpgp_list_preference_none">Нет</string> -  <string name="openpgp_install_openkeychain_via">Установить OpenKeychain через %s</string> -</resources> diff --git a/src/main/res/values-sl/strings.xml b/src/main/res/values-sl/strings.xml deleted file mode 100644 index 20bf70b..0000000 --- a/src/main/res/values-sl/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources> -  <string name="openpgp_list_preference_none">Brez</string> -  <string name="openpgp_install_openkeychain_via">Namesti OpenKeychain prek %s</string> -</resources> diff --git a/src/main/res/values-tr/strings.xml b/src/main/res/values-tr/strings.xml deleted file mode 100644 index c757504..0000000 --- a/src/main/res/values-tr/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources/> diff --git a/src/main/res/values-uk/strings.xml b/src/main/res/values-uk/strings.xml deleted file mode 100644 index baf600a..0000000 --- a/src/main/res/values-uk/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources> -  <string name="openpgp_list_preference_none">Жоден</string> -  <string name="openpgp_install_openkeychain_via">Встановити OpenKeychain через %s</string> -</resources> diff --git a/src/main/res/values-zh/strings.xml b/src/main/res/values-zh/strings.xml deleted file mode 100644 index c757504..0000000 --- a/src/main/res/values-zh/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources/> diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml deleted file mode 100644 index a45524f..0000000 --- a/src/main/res/values/strings.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - -    <string name="openpgp_list_preference_none">None</string> -    <string name="openpgp_install_openkeychain_via">Install OpenKeychain via %s</string> -    <string name="openpgp_no_key_selected">No key selected</string> -    <string name="openpgp_key_selected">Key has been selected</string> - -</resources>
\ No newline at end of file | 
