aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote
diff options
context:
space:
mode:
Diffstat (limited to 'OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote')
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java85
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java50
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java484
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java261
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java27
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java109
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java201
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java198
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java134
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java108
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java35
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java174
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java303
13 files changed, 0 insertions, 2169 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java
deleted file mode 100644
index 832cbc752..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote;
-
-import org.spongycastle.bcpg.HashAlgorithmTags;
-import org.spongycastle.openpgp.PGPEncryptedData;
-import org.sufficientlysecure.keychain.Id;
-
-public class AccountSettings {
- private String mAccountName;
- private long mKeyId = Id.key.none;
- private int mEncryptionAlgorithm;
- private int mHashAlgorithm;
- private int mCompression;
-
- public AccountSettings() {
-
- }
-
- public AccountSettings(String accountName) {
- super();
- this.mAccountName = accountName;
-
- // defaults:
- this.mEncryptionAlgorithm = PGPEncryptedData.AES_256;
- this.mHashAlgorithm = HashAlgorithmTags.SHA512;
- this.mCompression = Id.choice.compression.zlib;
- }
-
- public String getAccountName() {
- return mAccountName;
- }
-
- public void setAccountName(String mAccountName) {
- this.mAccountName = mAccountName;
- }
-
- public long getKeyId() {
- return mKeyId;
- }
-
- public void setKeyId(long scretKeyId) {
- this.mKeyId = scretKeyId;
- }
-
- public int getEncryptionAlgorithm() {
- return mEncryptionAlgorithm;
- }
-
- public void setEncryptionAlgorithm(int encryptionAlgorithm) {
- this.mEncryptionAlgorithm = encryptionAlgorithm;
- }
-
- public int getHashAlgorithm() {
- return mHashAlgorithm;
- }
-
- public void setHashAlgorithm(int hashAlgorithm) {
- this.mHashAlgorithm = hashAlgorithm;
- }
-
- public int getCompression() {
- return mCompression;
- }
-
- public void setCompression(int compression) {
- this.mCompression = compression;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java
deleted file mode 100644
index a3f9f84c9..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote;
-
-public class AppSettings {
- private String mPackageName;
- private byte[] mPackageSignature;
-
- public AppSettings() {
-
- }
-
- public AppSettings(String packageName, byte[] packageSignature) {
- super();
- this.mPackageName = packageName;
- this.mPackageSignature = packageSignature;
- }
-
- public String getPackageName() {
- return mPackageName;
- }
-
- public void setPackageName(String packageName) {
- this.mPackageName = packageName;
- }
-
- public byte[] getPackageSignature() {
- return mPackageSignature;
- }
-
- public void setPackageSignature(byte[] packageSignature) {
- this.mPackageSignature = packageSignature;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
deleted file mode 100644
index b38fea5a9..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote;
-
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-
-import org.openintents.openpgp.IOpenPgpService;
-import org.openintents.openpgp.OpenPgpError;
-import org.openintents.openpgp.OpenPgpSignatureResult;
-import org.openintents.openpgp.util.OpenPgpApi;
-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.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
-import org.sufficientlysecure.keychain.service.PassphraseCacheService;
-import org.sufficientlysecure.keychain.ui.ImportKeysActivity;
-import org.sufficientlysecure.keychain.util.InputData;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Set;
-
-public class OpenPgpService extends RemoteService {
-
- /**
- * Search database for key ids based on emails.
- *
- * @param encryptionUserIds
- * @return
- */
- private Intent getKeyIdsFromEmails(Intent data, String[] encryptionUserIds) {
- // find key ids to given emails in database
- ArrayList<Long> keyIds = new ArrayList<Long>();
-
- boolean missingUserIdsCheck = false;
- boolean duplicateUserIdsCheck = false;
- ArrayList<String> missingUserIds = new ArrayList<String>();
- ArrayList<String> duplicateUserIds = new ArrayList<String>();
-
- for (String email : encryptionUserIds) {
- Uri uri = KeyRings.buildUnifiedKeyRingsFindByEmailUri(email);
- Cursor cur = getContentResolver().query(uri, null, null, null, null);
- if (cur.moveToFirst()) {
- long id = cur.getLong(cur.getColumnIndex(KeyRings.MASTER_KEY_ID));
- keyIds.add(id);
- } else {
- missingUserIdsCheck = true;
- missingUserIds.add(email);
- Log.d(Constants.TAG, "user id missing");
- }
- if (cur.moveToNext()) {
- duplicateUserIdsCheck = true;
- duplicateUserIds.add(email);
- Log.d(Constants.TAG, "more than one user id with the same email");
- }
- }
-
- // convert to long[]
- long[] keyIdsArray = new long[keyIds.size()];
- for (int i = 0; i < keyIdsArray.length; i++) {
- keyIdsArray[i] = keyIds.get(i);
- }
-
- // allow the user to verify pub key selection
- if (missingUserIdsCheck || duplicateUserIdsCheck) {
- // build PendingIntent
- Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
- intent.setAction(RemoteServiceActivity.ACTION_SELECT_PUB_KEYS);
- intent.putExtra(RemoteServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray);
- intent.putExtra(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds);
- intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, duplicateUserIds);
- intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
-
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- // return PendingIntent to be executed by client
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
- return result;
- }
-
- if (keyIdsArray.length == 0) {
- return null;
- }
-
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keyIdsArray);
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
- return result;
- }
-
- private Intent getPassphraseBundleIntent(Intent data, long keyId) {
- // build PendingIntent for passphrase input
- Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
- intent.setAction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE);
- intent.putExtra(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, keyId);
- // pass params through to activity that it can be returned again later to repeat pgp operation
- intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- // return PendingIntent to be executed by client
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
- return result;
- }
-
- private Intent signImpl(Intent data, ParcelFileDescriptor input,
- ParcelFileDescriptor output, AccountSettings accSettings) {
- try {
- boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
-
- // get passphrase from cache, if key has "no" passphrase, this returns an empty String
- String passphrase;
- if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
- passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
- } else {
- passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), accSettings.getKeyId());
- }
- if (passphrase == null) {
- // get PendingIntent for passphrase input, add it to given params and return to client
- Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId());
- return passphraseBundle;
- }
-
- // Get Input- and OutputStream from ParcelFileDescriptor
- InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
- OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
- try {
- long inputLength = is.available();
- InputData inputData = new InputData(is, inputLength);
-
- // sign-only
- PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os);
- builder.enableAsciiArmorOutput(asciiArmor)
- .signatureHashAlgorithm(accSettings.getHashAlgorithm())
- .signatureForceV3(false)
- .signatureKeyId(accSettings.getKeyId())
- .signaturePassphrase(passphrase);
- builder.build().execute();
- } finally {
- is.close();
- os.close();
- }
-
- 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;
- }
- }
-
- private Intent encryptAndSignImpl(Intent data, ParcelFileDescriptor input,
- ParcelFileDescriptor output, AccountSettings accSettings,
- boolean sign) {
- try {
- boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
-
- long[] keyIds;
- if (data.hasExtra(OpenPgpApi.EXTRA_KEY_IDS)) {
- keyIds = data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS);
- } else if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS)) {
- // get key ids based on given user ids
- String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
- // give params through to activity...
- Intent result = getKeyIdsFromEmails(data, userIds);
-
- if (result.getIntExtra(OpenPgpApi.RESULT_CODE, 0) == OpenPgpApi.RESULT_CODE_SUCCESS) {
- keyIds = result.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS);
- } else {
- // if not success -> result contains a PendingIntent for user interaction
- return result;
- }
- } else {
- Intent result = new Intent();
- 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;
- }
-
- // add own key for encryption
- keyIds = Arrays.copyOf(keyIds, keyIds.length + 1);
- keyIds[keyIds.length - 1] = accSettings.getKeyId();
-
- // build InputData and write into OutputStream
- // Get Input- and OutputStream from ParcelFileDescriptor
- InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
- OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
- try {
- long inputLength = is.available();
- InputData inputData = new InputData(is, inputLength);
-
- PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os);
- builder.enableAsciiArmorOutput(asciiArmor)
- .compressionId(accSettings.getCompression())
- .symmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm())
- .encryptionKeyIds(keyIds);
-
- if (sign) {
- String passphrase;
- if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
- passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
- } else {
- passphrase = PassphraseCacheService.getCachedPassphrase(getContext(),
- accSettings.getKeyId());
- }
- if (passphrase == null) {
- // get PendingIntent for passphrase input, add it to given params and return to client
- Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId());
- return passphraseBundle;
- }
-
- // sign and encrypt
- builder.signatureHashAlgorithm(accSettings.getHashAlgorithm())
- .signatureForceV3(false)
- .signatureKeyId(accSettings.getKeyId())
- .signaturePassphrase(passphrase);
- } else {
- // encrypt only
- builder.signatureKeyId(Id.key.none);
- }
- // execute PGP operation!
- builder.build().execute();
- } finally {
- is.close();
- os.close();
- }
-
- 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;
- }
- }
-
- private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input,
- ParcelFileDescriptor output, Set<Long> allowedKeyIds) {
- try {
- // Get Input- and OutputStream from ParcelFileDescriptor
- InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
- OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
-
- Intent result = new Intent();
- try {
-
- String passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
- long inputLength = is.available();
- InputData inputData = new InputData(is, inputLength);
-
- PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os);
- builder.allowSymmetricDecryption(false) // no support for symmetric encryption
- .allowedKeyIds(allowedKeyIds) // allow only private keys associated with
- // accounts of this app
- .passphrase(passphrase);
-
- // TODO: currently does not support binary signed-only content
- PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
-
- if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) {
- // get PendingIntent for passphrase input, add it to given params and return to client
- Intent passphraseBundle =
- getPassphraseBundleIntent(data, decryptVerifyResult.getKeyIdPassphraseNeeded());
- return passphraseBundle;
- } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED ==
- decryptVerifyResult.getStatus()) {
- 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
- Intent intent = new Intent(getBaseContext(), ImportKeysActivity.class);
- intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN);
- intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, signatureResult.getKeyId());
- intent.putExtra(ImportKeysActivity.EXTRA_PENDING_INTENT_DATA, data);
-
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
- }
-
- result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
- }
-
- } finally {
- is.close();
- os.close();
- }
-
- 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;
- }
- }
-
- private Intent getKeyImpl(Intent data) {
- try {
- long keyId = data.getLongExtra(OpenPgpApi.EXTRA_KEY_ID, 0);
-
- if (ProviderHelper.getPGPPublicKeyRing(this, keyId) == null) {
- Intent result = new Intent();
-
- // If keys are not in db we return an additional PendingIntent
- // to retrieve the missing key
- Intent intent = new Intent(getBaseContext(), ImportKeysActivity.class);
- intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN);
- intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, keyId);
- intent.putExtra(ImportKeysActivity.EXTRA_PENDING_INTENT_DATA, data);
-
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- 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);
-
- // TODO: also return PendingIntent that opens the key view activity
-
- 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;
- }
- }
-
- private Intent getKeyIdsImpl(Intent data) {
- // get key ids based on given user ids
- String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
- Intent result = getKeyIdsFromEmails(data, userIds);
- return result;
- }
-
- /**
- * Check requirements:
- * - params != null
- * - has supported API version
- * - is allowed to call the service (access has been granted)
- *
- * @param data
- * @return null if everything is okay, or a Bundle with an error/PendingIntent
- */
- private Intent checkRequirements(Intent data) {
- // params Bundle is required!
- if (data == null) {
- Intent result = new Intent();
- OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!");
- result.putExtra(OpenPgpApi.RESULT_ERROR, error);
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- return result;
- }
-
- // version code is required and needs to correspond to version code of service!
- 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_ERROR, error);
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- return result;
- }
-
- // check if caller is allowed to access openpgp keychain
- Intent result = isAllowed(data);
- if (result != null) {
- return result;
- }
-
- return null;
- }
-
- // TODO: multi-threading
- private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() {
-
- @Override
- public Intent execute(Intent data, ParcelFileDescriptor input, ParcelFileDescriptor output) {
- Intent errorResult = checkRequirements(data);
- if (errorResult != null) {
- return errorResult;
- }
-
- String accName;
- if (data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME) != null) {
- accName = data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME);
- } else {
- accName = "default";
- }
- final AccountSettings accSettings = getAccSettings(accName);
- if (accSettings == null) {
- return getCreateAccountIntent(data, accName);
- }
-
- String action = data.getAction();
- if (OpenPgpApi.ACTION_SIGN.equals(action)) {
- return signImpl(data, input, output, accSettings);
- } else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) {
- return encryptAndSignImpl(data, input, output, accSettings, false);
- } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) {
- return encryptAndSignImpl(data, input, output, accSettings, true);
- } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) {
- String currentPkg = getCurrentCallingPackage();
- Set<Long> allowedKeyIds =
- ProviderHelper.getAllKeyIdsForApp(mContext,
- ApiAccounts.buildBaseUri(currentPkg));
- return decryptAndVerifyImpl(data, input, output, allowedKeyIds);
- } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) {
- return getKeyImpl(data);
- } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) {
- return getKeyIdsImpl(data);
- } else {
- return null;
- }
- }
-
- };
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java
deleted file mode 100644
index 16a800022..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote;
-
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.Signature;
-import android.net.Uri;
-import android.os.Binder;
-
-import org.openintents.openpgp.OpenPgpError;
-import org.openintents.openpgp.util.OpenPgpApi;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * Abstract service class for remote APIs that handle app registration and user input.
- */
-public abstract class RemoteService extends Service {
- Context mContext;
-
- public Context getContext() {
- return mContext;
- }
-
- protected Intent isAllowed(Intent data) {
- try {
- if (isCallerAllowed(false)) {
- return null;
- } else {
- String packageName = getCurrentCallingPackage();
- Log.d(Constants.TAG, "isAllowed packageName: " + packageName);
-
- byte[] packageSignature;
- try {
- packageSignature = getPackageSignature(packageName);
- } catch (NameNotFoundException e) {
- Log.e(Constants.TAG, "Should not happen, returning!", e);
- // return error
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- result.putExtra(OpenPgpApi.RESULT_ERROR,
- new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
- return result;
- }
- Log.e(Constants.TAG, "Not allowed to use service! return PendingIntent for registration!");
-
- Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
- intent.setAction(RemoteServiceActivity.ACTION_REGISTER);
- intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
- intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature);
- intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
-
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
-
- // return PendingIntent to be executed by client
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
-
- return result;
- }
- } catch (WrongPackageSignatureException e) {
- Log.e(Constants.TAG, "wrong signature!", e);
-
- Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
- intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
- intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE,
- getString(R.string.api_error_wrong_signature));
- intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
-
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- // return PendingIntent to be executed by client
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
-
- return result;
- }
- }
-
- private byte[] getPackageSignature(String packageName) throws NameNotFoundException {
- PackageInfo pkgInfo = getPackageManager().getPackageInfo(packageName,
- PackageManager.GET_SIGNATURES);
- Signature[] signatures = pkgInfo.signatures;
- // TODO: Only first signature?!
- byte[] packageSignature = signatures[0].toByteArray();
-
- return packageSignature;
- }
-
- /**
- * Returns package name associated with the UID, which is assigned to the process that sent you the
- * current transaction that is being processed :)
- *
- * @return package name
- */
- protected String getCurrentCallingPackage() {
- // TODO:
- // callingPackages contains more than one entry when sharedUserId has been used...
- String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid());
- String currentPkg = callingPackages[0];
- Log.d(Constants.TAG, "currentPkg: " + currentPkg);
-
- return currentPkg;
- }
-
- /**
- * Retrieves AccountSettings from database for the application calling this remote service
- *
- * @return
- */
- protected AccountSettings getAccSettings(String accountName) {
- String currentPkg = getCurrentCallingPackage();
- Log.d(Constants.TAG, "accountName: " + accountName);
-
- Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(currentPkg, accountName);
-
- AccountSettings settings = ProviderHelper.getApiAccountSettings(this, uri);
-
- return settings; // can be null!
- }
-
- protected Intent getCreateAccountIntent(Intent data, String accountName) {
- String packageName = getCurrentCallingPackage();
- Log.d(Constants.TAG, "accountName: " + accountName);
-
- Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
- intent.setAction(RemoteServiceActivity.ACTION_CREATE_ACCOUNT);
- intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
- intent.putExtra(RemoteServiceActivity.EXTRA_ACC_NAME, accountName);
- intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
-
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- // return PendingIntent to be executed by client
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
-
- return result;
- }
-
- /**
- * Checks if process that binds to this service (i.e. the package name corresponding to the
- * process) is in the list of allowed package names.
- *
- * @param allowOnlySelf allow only Keychain app itself
- * @return true if process is allowed to use this service
- * @throws WrongPackageSignatureException
- */
- private boolean isCallerAllowed(boolean allowOnlySelf) throws WrongPackageSignatureException {
- return isUidAllowed(Binder.getCallingUid(), allowOnlySelf);
- }
-
- private boolean isUidAllowed(int uid, boolean allowOnlySelf)
- throws WrongPackageSignatureException {
- if (android.os.Process.myUid() == uid) {
- return true;
- }
- if (allowOnlySelf) { // barrier
- return false;
- }
-
- String[] callingPackages = getPackageManager().getPackagesForUid(uid);
-
- // is calling package allowed to use this service?
- for (int i = 0; i < callingPackages.length; i++) {
- String currentPkg = callingPackages[i];
-
- if (isPackageAllowed(currentPkg)) {
- return true;
- }
- }
-
- Log.d(Constants.TAG, "Uid is NOT allowed!");
- return false;
- }
-
- /**
- * Checks if packageName is a registered app for the API. Does not return true for own package!
- *
- * @param packageName
- * @return
- * @throws WrongPackageSignatureException
- */
- private boolean isPackageAllowed(String packageName) throws WrongPackageSignatureException {
- Log.d(Constants.TAG, "isPackageAllowed packageName: " + packageName);
-
- ArrayList<String> allowedPkgs = ProviderHelper.getRegisteredApiApps(this);
- Log.d(Constants.TAG, "allowed: " + allowedPkgs);
-
- // check if package is allowed to use our service
- if (allowedPkgs.contains(packageName)) {
- Log.d(Constants.TAG, "Package is allowed! packageName: " + packageName);
-
- // check package signature
- byte[] currentSig;
- try {
- currentSig = getPackageSignature(packageName);
- } catch (NameNotFoundException e) {
- throw new WrongPackageSignatureException(e.getMessage());
- }
-
- byte[] storedSig = ProviderHelper.getApiAppSignature(this, packageName);
- if (Arrays.equals(currentSig, storedSig)) {
- Log.d(Constants.TAG,
- "Package signature is correct! (equals signature from database)");
- return true;
- } else {
- throw new WrongPackageSignatureException(
- "PACKAGE NOT ALLOWED! Signature wrong! (Signature not " +
- "equals signature from database)");
- }
- }
-
- Log.d(Constants.TAG, "Package is NOT allowed! packageName: " + packageName);
- return false;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- mContext = this;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java
deleted file mode 100644
index 6f44a65e9..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote;
-
-public class WrongPackageSignatureException extends Exception {
-
- private static final long serialVersionUID = -8294642703122196028L;
-
- public WrongPackageSignatureException(String message) {
- super(message);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java
deleted file mode 100644
index 123ed526f..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ActionBarHelper;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.AccountSettings;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class AccountSettingsActivity extends ActionBarActivity {
- private Uri mAccountUri;
-
- private AccountSettingsFragment mAccountSettingsFragment;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Inflate a "Done" custom action bar
- ActionBarHelper.setOneButtonView(getSupportActionBar(),
- R.string.api_settings_save, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // "Done"
- save();
- }
- });
-
- setContentView(R.layout.api_account_settings_activity);
-
- mAccountSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_account_settings_fragment);
-
- Intent intent = getIntent();
- mAccountUri = intent.getData();
- if (mAccountUri == null) {
- Log.e(Constants.TAG, "Intent data missing. Should be Uri of app!");
- finish();
- return;
- } else {
- Log.d(Constants.TAG, "uri: " + mAccountUri);
- loadData(mAccountUri);
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- getMenuInflater().inflate(R.menu.api_account_settings, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_account_settings_delete:
- deleteAccount();
- return true;
- case R.id.menu_account_settings_cancel:
- finish();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- private void loadData(Uri accountUri) {
- AccountSettings settings = ProviderHelper.getApiAccountSettings(this, accountUri);
- mAccountSettingsFragment.setAccSettings(settings);
- }
-
- private void deleteAccount() {
- if (getContentResolver().delete(mAccountUri, null, null) <= 0) {
- throw new RuntimeException();
- }
- finish();
- }
-
- private void save() {
- ProviderHelper.updateApiAccount(this, mAccountSettingsFragment.getAccSettings(), mAccountUri);
- finish();
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java
deleted file mode 100644
index 0a3ec3c3b..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.AccountSettings;
-import org.sufficientlysecure.keychain.ui.EditKeyActivity;
-import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment;
-import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter;
-import org.sufficientlysecure.keychain.util.AlgorithmNames;
-
-public class AccountSettingsFragment extends Fragment implements
- SelectSecretKeyLayoutFragment.SelectSecretKeyCallback {
-
- private static final int REQUEST_CODE_CREATE_KEY = 0x00008884;
-
- // model
- private AccountSettings mAccSettings;
-
- // view
- private TextView mAccNameView;
- private Spinner mEncryptionAlgorithm;
- private Spinner mHashAlgorithm;
- private Spinner mCompression;
-
- private SelectSecretKeyLayoutFragment mSelectKeyFragment;
- private BootstrapButton mCreateKeyButton;
-
- KeyValueSpinnerAdapter mEncryptionAdapter;
- KeyValueSpinnerAdapter mHashAdapter;
- KeyValueSpinnerAdapter mCompressionAdapter;
-
- public AccountSettings getAccSettings() {
- return mAccSettings;
- }
-
- public void setAccSettings(AccountSettings accountSettings) {
- this.mAccSettings = accountSettings;
-
- mAccNameView.setText(accountSettings.getAccountName());
- mSelectKeyFragment.selectKey(accountSettings.getKeyId());
- mEncryptionAlgorithm.setSelection(mEncryptionAdapter.getPosition(accountSettings
- .getEncryptionAlgorithm()));
- mHashAlgorithm.setSelection(mHashAdapter.getPosition(accountSettings.getHashAlgorithm()));
- mCompression.setSelection(mCompressionAdapter.getPosition(accountSettings.getCompression()));
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.api_account_settings_fragment, container, false);
- initView(view);
- return view;
- }
-
- /**
- * Set error String on key selection
- *
- * @param error
- */
- public void setErrorOnSelectKeyFragment(String error) {
- mSelectKeyFragment.setError(error);
- }
-
- private void initView(View view) {
- mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getFragmentManager().findFragmentById(
- R.id.api_account_settings_select_key_fragment);
- mSelectKeyFragment.setCallback(this);
-
- mAccNameView = (TextView) view.findViewById(R.id.api_account_settings_acc_name);
- mEncryptionAlgorithm = (Spinner) view
- .findViewById(R.id.api_account_settings_encryption_algorithm);
- mHashAlgorithm = (Spinner) view.findViewById(R.id.api_account_settings_hash_algorithm);
- mCompression = (Spinner) view.findViewById(R.id.api_account_settings_compression);
- mCreateKeyButton = (BootstrapButton) view.findViewById(R.id.api_account_settings_create_key);
-
- mCreateKeyButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- createKey();
- }
- });
-
- AlgorithmNames algorithmNames = new AlgorithmNames(getActivity());
-
- mEncryptionAdapter = new KeyValueSpinnerAdapter(getActivity(),
- algorithmNames.getEncryptionNames());
- mEncryptionAlgorithm.setAdapter(mEncryptionAdapter);
- mEncryptionAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() {
-
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- mAccSettings.setEncryptionAlgorithm((int) id);
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
- }
- });
-
- mHashAdapter = new KeyValueSpinnerAdapter(getActivity(), algorithmNames.getHashNames());
- mHashAlgorithm.setAdapter(mHashAdapter);
- mHashAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() {
-
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- mAccSettings.setHashAlgorithm((int) id);
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
- }
- });
-
- mCompressionAdapter = new KeyValueSpinnerAdapter(getActivity(),
- algorithmNames.getCompressionNames());
- mCompression.setAdapter(mCompressionAdapter);
- mCompression.setOnItemSelectedListener(new OnItemSelectedListener() {
-
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- mAccSettings.setCompression((int) id);
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
- }
- });
- }
-
- private void createKey() {
- Intent intent = new Intent(getActivity(), EditKeyActivity.class);
- intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
- intent.putExtra(EditKeyActivity.EXTRA_GENERATE_DEFAULT_KEYS, true);
- // set default user id to account name
- intent.putExtra(EditKeyActivity.EXTRA_USER_IDS, mAccSettings.getAccountName());
- startActivityForResult(intent, REQUEST_CODE_CREATE_KEY);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case REQUEST_CODE_CREATE_KEY: {
- if (resultCode == Activity.RESULT_OK) {
- // select newly created key
- long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), data.getData());
- mSelectKeyFragment.selectKey(masterKeyId);
- }
- break;
- }
-
- default:
- super.onActivityResult(requestCode, resultCode, data);
-
- break;
- }
- }
-
- /**
- * callback from select secret key fragment
- */
- @Override
- public void onKeySelected(long secretKeyId) {
- mAccSettings.setKeyId(secretKeyId);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java
deleted file mode 100644
index 4d99e1923..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * 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.remote.ui;
-
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.ListFragment;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.support.v4.widget.CursorAdapter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.ui.widget.FixedListView;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class AccountsListFragment extends ListFragment implements
- LoaderManager.LoaderCallbacks<Cursor> {
-
- private static final String ARG_DATA_URI = "uri";
-
- // This is the Adapter being used to display the list's data.
- AccountsAdapter mAdapter;
-
- private Uri mDataUri;
-
- /**
- * Creates new instance of this fragment
- */
- public static AccountsListFragment newInstance(Uri dataUri) {
- AccountsListFragment frag = new AccountsListFragment();
-
- Bundle args = new Bundle();
- args.putParcelable(ARG_DATA_URI, dataUri);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View layout = super.onCreateView(inflater, container,
- savedInstanceState);
- ListView lv = (ListView) layout.findViewById(android.R.id.list);
- ViewGroup parent = (ViewGroup) lv.getParent();
-
- /*
- * http://stackoverflow.com/a/15880684
- * Remove ListView and add FixedListView in its place.
- * This is done here programatically to be still able to use the progressBar of ListFragment.
- *
- * We want FixedListView to be able to put this ListFragment inside a ScrollView
- */
- int lvIndex = parent.indexOfChild(lv);
- parent.removeViewAt(lvIndex);
- FixedListView newLv = new FixedListView(getActivity());
- newLv.setId(android.R.id.list);
- parent.addView(newLv, lvIndex, lv.getLayoutParams());
- return layout;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- mDataUri = getArguments().getParcelable(ARG_DATA_URI);
-
- getListView().setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
- String selectedAccountName = mAdapter.getItemAccountName(position);
- Uri accountUri = mDataUri.buildUpon().appendEncodedPath(selectedAccountName).build();
- Log.d(Constants.TAG, "accountUri: " + accountUri);
-
- // edit account settings
- Intent intent = new Intent(getActivity(), AccountSettingsActivity.class);
- intent.setData(accountUri);
- startActivity(intent);
- }
- });
-
- // Give some text to display if there is no data. In a real
- // application this would come from a resource.
- setEmptyText(getString(R.string.api_settings_accounts_empty));
-
- // We have a menu item to show in action bar.
- setHasOptionsMenu(true);
-
- // Create an empty adapter we will use to display the loaded data.
- mAdapter = new AccountsAdapter(getActivity(), null, 0);
- setListAdapter(mAdapter);
-
- // Prepare the loader. Either re-connect with an existing one,
- // or start a new one.
- getLoaderManager().initLoader(0, null, this);
- }
-
- // These are the Contacts rows that we will retrieve.
- static final String[] PROJECTION = new String[]{
- KeychainContract.ApiAccounts._ID, // 0
- KeychainContract.ApiAccounts.ACCOUNT_NAME // 1
- };
-
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- // This is called when a new Loader needs to be created. This
- // sample only has one Loader, so we don't care about the ID.
-
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), mDataUri, PROJECTION, null, null,
- KeychainContract.ApiAccounts.ACCOUNT_NAME + " COLLATE LOCALIZED ASC");
- }
-
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- mAdapter.swapCursor(data);
- }
-
- public void onLoaderReset(Loader<Cursor> loader) {
- // This is called when the last Cursor provided to onLoadFinished()
- // above is about to be closed. We need to make sure we are no
- // longer using it.
- mAdapter.swapCursor(null);
- }
-
- private class AccountsAdapter extends CursorAdapter {
- private LayoutInflater mInflater;
-
- public AccountsAdapter(Context context, Cursor c, int flags) {
- super(context, c, flags);
-
- mInflater = LayoutInflater.from(context);
- }
-
- /**
- * Similar to CursorAdapter.getItemId().
- * Required to build Uris for api accounts, which are not based on row ids
- *
- * @param position
- * @return
- */
- public String getItemAccountName(int position) {
- if (mDataValid && mCursor != null) {
- if (mCursor.moveToPosition(position)) {
- return mCursor.getString(1);
- } else {
- return null;
- }
- } else {
- return null;
- }
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- TextView text = (TextView) view.findViewById(R.id.api_accounts_adapter_item_name);
-
- String accountName = cursor.getString(1);
- text.setText(accountName);
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.api_accounts_adapter_list_item, null);
- }
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java
deleted file mode 100644
index 818c296c1..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-import android.view.Menu;
-import android.view.MenuItem;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.AppSettings;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class AppSettingsActivity extends ActionBarActivity {
- private Uri mAppUri;
-
- private AppSettingsFragment mSettingsFragment;
- private AccountsListFragment mAccountsListFragment;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // let the actionbar look like Android's contact app
- ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setIcon(android.R.color.transparent);
- actionBar.setHomeButtonEnabled(true);
-
- setContentView(R.layout.api_app_settings_activity);
-
- mSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_app_settings_fragment);
-
- Intent intent = getIntent();
- mAppUri = intent.getData();
- if (mAppUri == null) {
- Log.e(Constants.TAG, "Intent data missing. Should be Uri of app!");
- finish();
- return;
- } else {
- Log.d(Constants.TAG, "uri: " + mAppUri);
- loadData(savedInstanceState, mAppUri);
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- getMenuInflater().inflate(R.menu.api_app_settings, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_api_settings_revoke:
- revokeAccess();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- private void loadData(Bundle savedInstanceState, Uri appUri) {
- AppSettings settings = ProviderHelper.getApiAppSettings(this, appUri);
- mSettingsFragment.setAppSettings(settings);
-
- String appName;
- PackageManager pm = getPackageManager();
- try {
- ApplicationInfo ai = pm.getApplicationInfo(settings.getPackageName(), 0);
- appName = (String) pm.getApplicationLabel(ai);
- } catch (PackageManager.NameNotFoundException e) {
- // fallback
- appName = settings.getPackageName();
- }
- setTitle(appName);
-
- Uri accountsUri = appUri.buildUpon().appendPath(KeychainContract.PATH_ACCOUNTS).build();
- Log.d(Constants.TAG, "accountsUri: " + accountsUri);
- startListFragment(savedInstanceState, accountsUri);
- }
-
- private void startListFragment(Bundle savedInstanceState, Uri dataUri) {
- // However, if we're being restored from a previous state,
- // then we don't need to do anything and should return or else
- // we could end up with overlapping fragments.
- if (savedInstanceState != null) {
- return;
- }
-
- // Create an instance of the fragment
- mAccountsListFragment = AccountsListFragment.newInstance(dataUri);
-
- // Add the fragment to the 'fragment_container' FrameLayout
- // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
- getSupportFragmentManager().beginTransaction()
- .replace(R.id.api_accounts_list_fragment, mAccountsListFragment)
- .commitAllowingStateLoss();
- // do it immediately!
- getSupportFragmentManager().executePendingTransactions();
- }
-
- private void revokeAccess() {
- if (getContentResolver().delete(mAppUri, null, null) <= 0) {
- throw new RuntimeException();
- }
- finish();
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java
deleted file mode 100644
index a6db02708..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.spongycastle.util.encoders.Hex;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.remote.AppSettings;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-public class AppSettingsFragment extends Fragment {
-
- // model
- private AppSettings mAppSettings;
-
- // view
- private TextView mAppNameView;
- private ImageView mAppIconView;
- private TextView mPackageName;
- private TextView mPackageSignature;
-
- public AppSettings getAppSettings() {
- return mAppSettings;
- }
-
- public void setAppSettings(AppSettings appSettings) {
- this.mAppSettings = appSettings;
- updateView(appSettings);
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.api_app_settings_fragment, container, false);
- mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name);
- mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon);
- mPackageName = (TextView) view.findViewById(R.id.api_app_settings_package_name);
- mPackageSignature = (TextView) view.findViewById(R.id.api_app_settings_package_signature);
- return view;
- }
-
- private void updateView(AppSettings appSettings) {
- // get application name and icon from package manager
- String appName;
- Drawable appIcon = null;
- PackageManager pm = getActivity().getApplicationContext().getPackageManager();
- try {
- ApplicationInfo ai = pm.getApplicationInfo(appSettings.getPackageName(), 0);
-
- appName = (String) pm.getApplicationLabel(ai);
- appIcon = pm.getApplicationIcon(ai);
- } catch (NameNotFoundException e) {
- // fallback
- appName = appSettings.getPackageName();
- }
- mAppNameView.setText(appName);
- mAppIconView.setImageDrawable(appIcon);
-
- // advanced info: package name
- mPackageName.setText(appSettings.getPackageName());
-
- // advanced info: package signature SHA-256
- try {
- MessageDigest md = MessageDigest.getInstance("SHA-256");
- md.update(appSettings.getPackageSignature());
- byte[] digest = md.digest();
- String signature = new String(Hex.encode(digest));
-
- mPackageSignature.setText(signature);
- } catch (NoSuchAlgorithmException e) {
- Log.e(Constants.TAG, "Should not happen!", e);
- }
- }
-
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java
deleted file mode 100644
index f86d279f0..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.os.Bundle;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.DrawerActivity;
-
-public class AppsListActivity extends DrawerActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.api_apps_list_activity);
-
- setupDrawerNavigation(savedInstanceState);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java
deleted file mode 100644
index 9d0e6d3ef..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.ListFragment;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.support.v4.widget.CursorAdapter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
-
-public class AppsListFragment extends ListFragment implements
- LoaderManager.LoaderCallbacks<Cursor> {
-
- // This is the Adapter being used to display the list's data.
- RegisteredAppsAdapter mAdapter;
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- getListView().setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
- String selectedPackageName = mAdapter.getItemPackageName(position);
- // edit app settings
- Intent intent = new Intent(getActivity(), AppSettingsActivity.class);
- intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(selectedPackageName));
- startActivity(intent);
- }
- });
-
- // Give some text to display if there is no data. In a real
- // application this would come from a resource.
- setEmptyText(getString(R.string.api_no_apps));
-
- // We have a menu item to show in action bar.
- setHasOptionsMenu(true);
-
- // Create an empty adapter we will use to display the loaded data.
- mAdapter = new RegisteredAppsAdapter(getActivity(), null, 0);
- setListAdapter(mAdapter);
-
- // Prepare the loader. Either re-connect with an existing one,
- // or start a new one.
- getLoaderManager().initLoader(0, null, this);
- }
-
- // These are the Contacts rows that we will retrieve.
- static final String[] PROJECTION = new String[]{
- ApiApps._ID, // 0
- ApiApps.PACKAGE_NAME // 1
- };
-
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- // This is called when a new Loader needs to be created. This
- // sample only has one Loader, so we don't care about the ID.
- // First, pick the base URI to use depending on whether we are
- // currently filtering.
- Uri baseUri = ApiApps.CONTENT_URI;
-
- // 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,
- ApiApps.PACKAGE_NAME + " COLLATE LOCALIZED ASC");
- }
-
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- mAdapter.swapCursor(data);
- }
-
- public void onLoaderReset(Loader<Cursor> loader) {
- // This is called when the last Cursor provided to onLoadFinished()
- // above is about to be closed. We need to make sure we are no
- // longer using it.
- mAdapter.swapCursor(null);
- }
-
- private class RegisteredAppsAdapter extends CursorAdapter {
-
- private LayoutInflater mInflater;
- private PackageManager mPM;
-
- public RegisteredAppsAdapter(Context context, Cursor c, int flags) {
- super(context, c, flags);
-
- mInflater = LayoutInflater.from(context);
- mPM = context.getApplicationContext().getPackageManager();
- }
-
- /**
- * Similar to CursorAdapter.getItemId().
- * Required to build Uris for api apps, which are not based on row ids
- *
- * @param position
- * @return
- */
- public String getItemPackageName(int position) {
- if (mDataValid && mCursor != null) {
- if (mCursor.moveToPosition(position)) {
- return mCursor.getString(1);
- } else {
- return null;
- }
- } else {
- return null;
- }
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name);
- ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon);
-
- String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME));
- if (packageName != null) {
- // get application name
- try {
- ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0);
-
- text.setText(mPM.getApplicationLabel(ai));
- icon.setImageDrawable(mPM.getApplicationIcon(ai));
- } catch (final PackageManager.NameNotFoundException e) {
- // fallback
- text.setText(packageName);
- }
- } else {
- // fallback
- text.setText(packageName);
- }
-
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.api_apps_adapter_list_item, null);
- }
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
deleted file mode 100644
index ab95f2691..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v7.app.ActionBarActivity;
-import android.view.View;
-
-import org.openintents.openpgp.util.OpenPgpApi;
-import org.sufficientlysecure.htmltextview.HtmlTextView;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ActionBarHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.AccountSettings;
-import org.sufficientlysecure.keychain.remote.AppSettings;
-import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment;
-import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.ArrayList;
-
-public class RemoteServiceActivity extends ActionBarActivity {
-
- public static final String ACTION_REGISTER = Constants.INTENT_PREFIX + "API_ACTIVITY_REGISTER";
- public static final String ACTION_CREATE_ACCOUNT = Constants.INTENT_PREFIX
- + "API_ACTIVITY_CREATE_ACCOUNT";
- public static final String ACTION_CACHE_PASSPHRASE = Constants.INTENT_PREFIX
- + "API_ACTIVITY_CACHE_PASSPHRASE";
- public static final String ACTION_SELECT_PUB_KEYS = Constants.INTENT_PREFIX
- + "API_ACTIVITY_SELECT_PUB_KEYS";
- public static final String ACTION_ERROR_MESSAGE = Constants.INTENT_PREFIX
- + "API_ACTIVITY_ERROR_MESSAGE";
-
- public static final String EXTRA_MESSENGER = "messenger";
-
- public static final String EXTRA_DATA = "data";
-
- // passphrase action
- public static final String EXTRA_SECRET_KEY_ID = "secret_key_id";
- // register action
- public static final String EXTRA_PACKAGE_NAME = "package_name";
- public static final String EXTRA_PACKAGE_SIGNATURE = "package_signature";
- // create acc action
- public static final String EXTRA_ACC_NAME = "acc_name";
- // select pub keys action
- public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "master_key_ids";
- public static final String EXTRA_MISSING_USER_IDS = "missing_user_ids";
- public static final String EXTRA_DUBLICATE_USER_IDS = "dublicate_user_ids";
- // error message
- public static final String EXTRA_ERROR_MESSAGE = "error_message";
-
- // register view
- private AppSettingsFragment mAppSettingsFragment;
- // create acc view
- private AccountSettingsFragment mAccSettingsFragment;
- // select pub keys view
- private SelectPublicKeyFragment mSelectFragment;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- handleActions(getIntent(), savedInstanceState);
- }
-
- protected void handleActions(Intent intent, Bundle savedInstanceState) {
-
- String action = intent.getAction();
- final Bundle extras = intent.getExtras();
-
-
- if (ACTION_REGISTER.equals(action)) {
- final String packageName = extras.getString(EXTRA_PACKAGE_NAME);
- final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE);
- Log.d(Constants.TAG, "ACTION_REGISTER packageName: " + packageName);
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(),
- R.string.api_register_allow, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Allow
-
- ProviderHelper.insertApiApp(RemoteServiceActivity.this,
- mAppSettingsFragment.getAppSettings());
-
- // give data through for new service call
- Intent resultData = extras.getParcelable(EXTRA_DATA);
- RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
- RemoteServiceActivity.this.finish();
- }
- }, R.string.api_register_disallow, R.drawable.ic_action_cancel,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Disallow
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
- }
- }
- );
-
- setContentView(R.layout.api_remote_register_app);
-
- mAppSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_app_settings_fragment);
-
- AppSettings settings = new AppSettings(packageName, packageSignature);
- mAppSettingsFragment.setAppSettings(settings);
- } else if (ACTION_CREATE_ACCOUNT.equals(action)) {
- final String packageName = extras.getString(EXTRA_PACKAGE_NAME);
- final String accName = extras.getString(EXTRA_ACC_NAME);
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(),
- R.string.api_settings_save, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Save
-
- // user needs to select a key!
- if (mAccSettingsFragment.getAccSettings().getKeyId() == Id.key.none) {
- mAccSettingsFragment.setErrorOnSelectKeyFragment(
- getString(R.string.api_register_error_select_key));
- } else {
- ProviderHelper.insertApiAccount(RemoteServiceActivity.this,
- KeychainContract.ApiAccounts.buildBaseUri(packageName),
- mAccSettingsFragment.getAccSettings());
-
- // give data through for new service call
- Intent resultData = extras.getParcelable(EXTRA_DATA);
- RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
- RemoteServiceActivity.this.finish();
- }
- }
- }, R.string.api_settings_cancel, R.drawable.ic_action_cancel,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Cancel
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
- }
- }
- );
-
- setContentView(R.layout.api_remote_create_account);
-
- mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_account_settings_fragment);
-
- AccountSettings settings = new AccountSettings(accName);
- mAccSettingsFragment.setAccSettings(settings);
- } else if (ACTION_CACHE_PASSPHRASE.equals(action)) {
- long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID);
- final Intent resultData = extras.getParcelable(EXTRA_DATA);
-
- PassphraseDialogFragment.show(this, secretKeyId,
- new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
- // return given params again, for calling the service method again
- RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
- } else {
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- }
-
- RemoteServiceActivity.this.finish();
- }
- });
-
- } else if (ACTION_SELECT_PUB_KEYS.equals(action)) {
- long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
- ArrayList<String> missingUserIds = intent
- .getStringArrayListExtra(EXTRA_MISSING_USER_IDS);
- ArrayList<String> dublicateUserIds = intent
- .getStringArrayListExtra(EXTRA_DUBLICATE_USER_IDS);
-
- // TODO: do this with spannable instead of HTML to prevent parsing failures with weird user ids
- String text = "<b>" + getString(R.string.api_select_pub_keys_text) + "</b>";
- text += "<br/><br/>";
- if (missingUserIds != null && missingUserIds.size() > 0) {
- text += getString(R.string.api_select_pub_keys_missing_text);
- text += "<br/>";
- text += "<ul>";
- for (String userId : missingUserIds) {
- text += "<li>" + userId + "</li>";
- }
- text += "</ul>";
- text += "<br/>";
- }
- if (dublicateUserIds != null && dublicateUserIds.size() > 0) {
- text += getString(R.string.api_select_pub_keys_dublicates_text);
- text += "<br/>";
- text += "<ul>";
- for (String userId : dublicateUserIds) {
- text += "<li>" + userId + "</li>";
- }
- text += "</ul>";
- }
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(),
- R.string.btn_okay, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // add key ids to params Bundle for new request
- Intent resultData = extras.getParcelable(EXTRA_DATA);
- resultData.putExtra(OpenPgpApi.EXTRA_KEY_IDS,
- mSelectFragment.getSelectedMasterKeyIds());
-
- RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
- RemoteServiceActivity.this.finish();
- }
- }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // cancel
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
- }
- }
- );
-
- setContentView(R.layout.api_remote_select_pub_keys);
-
- // set text on view
- HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_select_pub_keys_text);
- textView.setHtmlFromString(text);
-
- /* Load select pub keys fragment */
- // Check that the activity is using the layout version with
- // the fragment_container FrameLayout
- if (findViewById(R.id.api_select_pub_keys_fragment_container) != null) {
-
- // However, if we're being restored from a previous state,
- // then we don't need to do anything and should return or else
- // we could end up with overlapping fragments.
- if (savedInstanceState != null) {
- return;
- }
-
- // Create an instance of the fragment
- mSelectFragment = SelectPublicKeyFragment.newInstance(selectedMasterKeyIds);
-
- // Add the fragment to the 'fragment_container' FrameLayout
- getSupportFragmentManager().beginTransaction()
- .add(R.id.api_select_pub_keys_fragment_container, mSelectFragment).commit();
- }
- } else if (ACTION_ERROR_MESSAGE.equals(action)) {
- String errorMessage = intent.getStringExtra(EXTRA_ERROR_MESSAGE);
-
- String text = "<font color=\"red\">" + errorMessage + "</font>";
-
- // Inflate a "Done" custom action bar view
- ActionBarHelper.setOneButtonView(getSupportActionBar(),
- R.string.btn_okay, R.drawable.ic_action_done,
- new View.OnClickListener() {
-
- @Override
- public void onClick(View v) {
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
- }
- });
-
- setContentView(R.layout.api_remote_error_message);
-
- // set text on view
- HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_app_error_message_text);
- textView.setHtmlFromString(text);
- } else {
- Log.e(Constants.TAG, "Action does not exist!");
- setResult(RESULT_CANCELED);
- finish();
- }
- }
-}