aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain')
-rw-r--r--OpenKeychain/build.gradle22
-rw-r--r--OpenKeychain/src/main/AndroidManifest.xml5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java14
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java20
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java11
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java30
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java34
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java1
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectAllowedKeysActivity.java115
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java32
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java34
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java21
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java48
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java16
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java22
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PassphraseEditText.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthBarView.java (renamed from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthBarView.java)5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthView.java (renamed from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthView.java)3
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_content_copy_black_24dp.pngbin0 -> 284 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_share_black_24dp.pngbin0 -> 499 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_content_copy_black_24dp.pngbin0 -> 214 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_share_black_24dp.pngbin0 -> 355 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_content_copy_black_24dp.pngbin0 -> 304 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_share_black_24dp.pngbin0 -> 614 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_content_copy_black_24dp.pngbin0 -> 397 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_share_black_24dp.pngbin0 -> 804 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_content_copy_black_24dp.pngbin0 -> 480 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_share_black_24dp.pngbin0 -> 1052 bytes
-rw-r--r--OpenKeychain/src/main/res/layout/api_remote_select_allowed_keys.xml38
-rw-r--r--OpenKeychain/src/main/res/layout/create_yubikey_wait_fragment.xml3
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_file_fragment.xml2
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_result_include.xml136
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_text_activity.xml2
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml2
-rw-r--r--OpenKeychain/src/main/res/layout/key_list_item.xml16
-rw-r--r--OpenKeychain/src/main/res/layout/main_activity.xml17
-rw-r--r--OpenKeychain/src/main/res/layout/passphrase_repeat_dialog.xml2
-rw-r--r--OpenKeychain/src/main/res/layout/toolbar_result_decrypt.xml145
-rw-r--r--OpenKeychain/src/main/res/menu/decrypt_menu.xml4
-rw-r--r--OpenKeychain/src/main/res/values/strings.xml16
-rw-r--r--OpenKeychain/src/main/res/values/themes.xml9
52 files changed, 579 insertions, 316 deletions
diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle
index cc5e01aca..14d82ec46 100644
--- a/OpenKeychain/build.gradle
+++ b/OpenKeychain/build.gradle
@@ -6,10 +6,10 @@ dependencies {
// NOTE: libraries are pinned to a specific build, see below
// from local Android SDK
- compile 'com.android.support:support-v4:22.0.0'
- compile 'com.android.support:appcompat-v7:22.0.0'
- compile 'com.android.support:recyclerview-v7:22.0.0'
- compile 'com.android.support:cardview-v7:22.0.0'
+ compile 'com.android.support:support-v4:22.1.1'
+ compile 'com.android.support:appcompat-v7:22.1.1'
+ compile 'com.android.support:recyclerview-v7:22.1.0'
+ compile 'com.android.support:cardview-v7:22.1.0'
// UI testing libs
androidTestCompile 'com.android.support.test:runner:0.2'
@@ -28,7 +28,7 @@ dependencies {
compile "com.splitwise:tokenautocomplete:1.3.3@aar"
compile 'se.emilsjolander:stickylistheaders:2.6.0'
compile 'org.sufficientlysecure:html-textview:1.1'
- compile 'com.mikepenz.materialdrawer:library:2.7.9@aar'
+ compile 'com.mikepenz.materialdrawer:library:2.8.2@aar'
compile 'com.mikepenz.iconics:library:0.9.1@aar'
compile 'com.mikepenz.iconics:octicons-typeface:2.2.0@aar'
compile 'com.mikepenz.iconics:meteocons-typeface:1.1.1@aar'
@@ -51,10 +51,10 @@ dependencies {
// Comment out the libs referenced as git submodules!
dependencyVerification {
verify = [
- 'com.android.support:support-v4:355a11466727e8ba00e239416aec55ac3cd3fb4ffc9d20c4a33373085c050bd1',
- 'com.android.support:appcompat-v7:40114cb756fecffa4a51c5645593cf64509c576594f77e41e801368051115c7b',
- 'com.android.support:recyclerview-v7:859ed80e3761f8fc3126901260b208505120b5678bcf36ad2cfe9c453958b9c7',
- 'com.android.support:cardview-v7:4c03f2acce9925aa4f8845cb8cb37b3772c712b2438ff15f76c9e3d3bc63ead7',
+ 'com.android.support:support-v4:1e2e4d35ac7fd30db5ce3bc177b92e4d5af86acef2ef93e9221599d733346f56',
+ 'com.android.support:appcompat-v7:9a2355537c2f01cf0b95523605c18606b8d824017e6e94a05c77b0cfc8f21c96',
+ 'com.android.support:recyclerview-v7:522d323079a29bcd76173bd9bc7535223b4af3e5eefef9d9287df1f9e54d0c10',
+ 'com.android.support:cardview-v7:8dc99af71fec000baa4470c3907755264f15f816920861bc015b2babdbb49807',
'com.eftimoff:android-patternview:cec80e7265b8d8278b3c55b5fcdf551e4600ac2c8bf60d8dd76adca538af0b1e',
'com.journeyapps:zxing-android-embedded:702a4f58154dbd9baa80f66b6a15410f7a4d403f3e73b66537a8bfb156b4b718',
'com.journeyapps:zxing-android-integration:562737821b6d34c899b6fd2234ce0a8a31e02ff1fd7c59f6211961ce9767c7c8',
@@ -65,7 +65,7 @@ dependencyVerification {
'com.splitwise:tokenautocomplete:20bee71cc59b3828eb000b684d46ddf738efd56b8fee453a509cd16fda42c8cb',
'se.emilsjolander:stickylistheaders:8c05981ec5725be33f7cee5e68c13f3db49cd5c75f1aaeb04024920b1ef96ad4',
'org.sufficientlysecure:html-textview:ca24b1522be88378634093815ce9ff1b4920c72e7513a045a7846e14069ef988',
- 'com.mikepenz.materialdrawer:library:3ef80c6e1ca1b29cfcbb27fa7927c02b2246e068c17fe52283703c4897449923',
+ 'com.mikepenz.materialdrawer:library:970317ed1a3cb96317f7b8d62ff592b3103eb46dfd68d9b244e7143623dc6d7a',
'com.mikepenz.iconics:library:4698a36ee4c2af765d0a85779c61474d755b90d66a59020105b6760a8a909e9e',
'com.mikepenz.iconics:octicons-typeface:67ed7d456a9ce5f5307b85f955797bfb3dd674e2f6defb31c6b8bbe2ede290be',
'com.mikepenz.iconics:meteocons-typeface:39a8a9e70cd8287cdb119af57a672a41dd09240dba6697f5a0dbda1ccc33298b',
@@ -80,7 +80,7 @@ dependencyVerification {
// 'OpenKeychain.extern.KeybaseLib:Lib:c91cda4a75692d8664644cd17d8ac962ce5bc0e266ea26673a639805f1eccbdf',
// 'OpenKeychain.extern:safeslinger-exchange:d222721bb35408daaab9f46449364b2657112705ee571d7532f81cbeb9c4a73f',
// 'OpenKeychain.extern.snackbar:lib:52357426e5275412e2063bdf6f0e6b957a3ea74da45e0aef35d22d9afc542e23',
- 'com.android.support:support-annotations:ab6b131ab0e1edd165d21fb4c3edadeacbee9539aa166f7f7cbae05b60dc207a',
+ 'com.android.support:support-annotations:7bc07519aa613b186001160403bcfd68260fa82c61cc7e83adeedc9b862b94ae',
]
}
diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml
index 8c66176fd..6bc61460a 100644
--- a/OpenKeychain/src/main/AndroidManifest.xml
+++ b/OpenKeychain/src/main/AndroidManifest.xml
@@ -741,6 +741,11 @@
android:label="@string/app_name"
android:launchMode="singleTop" />
<activity
+ android:name=".remote.ui.SelectAllowedKeysActivity"
+ android:exported="false"
+ android:label="@string/app_name"
+ android:launchMode="singleTop" />
+ <activity
android:name=".remote.ui.AppSettingsActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:exported="false">
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java
index d26ccbe57..710dbf8aa 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java
@@ -24,6 +24,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
+import android.graphics.Bitmap;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build;
@@ -40,6 +41,8 @@ import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.TlsHelper;
import java.security.Security;
+import java.util.HashMap;
+
public class KeychainApplication extends Application {
@@ -100,6 +103,17 @@ public class KeychainApplication extends Application {
checkConsolidateRecovery();
}
+ public static HashMap<String,Bitmap> qrCodeCache = new HashMap<>();
+
+ @Override
+ public void onTrimMemory(int level) {
+ super.onTrimMemory(level);
+
+ if (level >= TRIM_MEMORY_UI_HIDDEN) {
+ qrCodeCache.clear();
+ }
+ }
+
/**
* Restart consolidate process if it has been interruped before
*/
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java
index 90ec3053f..bf2349734 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
package org.sufficientlysecure.keychain.pgp;
@@ -32,7 +50,7 @@ public class PgpCertifyOperation {
OperationLog log,
int indent,
CertifyAction action,
- Map<ByteBuffer,byte[]> signedHashes,
+ Map<ByteBuffer, byte[]> signedHashes,
Date creationTimestamp) {
if (!secretKey.isMasterKey()) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java
index 8ecb30cdd..9073e81b9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java
@@ -178,13 +178,20 @@ public class PgpSignEncryptOperation extends BaseOperation {
case PIN:
case PATTERN:
case PASSPHRASE: {
- if (cryptoInput.getPassphrase() == null) {
+ Passphrase localPassphrase = cryptoInput.getPassphrase();
+ if (localPassphrase == null) {
+ try {
+ localPassphrase = getCachedPassphrase(signingKeyRing.getMasterKeyId(), signingKey.getKeyId());
+ } catch (PassphraseCacheInterface.NoSecretKeyException ignored) {
+ }
+ }
+ if (localPassphrase == null) {
log.add(LogType.MSG_PSE_PENDING_PASSPHRASE, indent + 1);
return new PgpSignEncryptResult(log, RequiredInputParcel.createRequiredSignPassphrase(
signingKeyRing.getMasterKeyId(), signingKey.getKeyId(),
cryptoInput.getSignatureTime()));
}
- if (!signingKey.unlock(cryptoInput.getPassphrase())) {
+ if (!signingKey.unlock(localPassphrase)) {
log.add(LogType.MSG_PSE_ERROR_BAD_PASSPHRASE, indent);
return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java
index a65d222da..6dd4a1633 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java
@@ -31,10 +31,12 @@ import android.provider.OpenableColumns;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.util.DatabaseUtil;
+import org.sufficientlysecure.keychain.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.util.UUID;
public class TemporaryStorageProvider extends ContentProvider {
@@ -44,7 +46,7 @@ public class TemporaryStorageProvider extends ContentProvider {
private static final String COLUMN_NAME = "name";
private static final String COLUMN_TIME = "time";
private static final Uri BASE_URI = Uri.parse("content://org.sufficientlysecure.keychain.tempstorage/");
- private static final int DB_VERSION = 1;
+ private static final int DB_VERSION = 2;
public static Uri createFile(Context context, String targetName) {
ContentValues contentValues = new ContentValues();
@@ -66,7 +68,7 @@ public class TemporaryStorageProvider extends ContentProvider {
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_FILES + " (" +
- COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ COLUMN_ID + " TEXT PRIMARY KEY, " +
COLUMN_NAME + " TEXT, " +
COLUMN_TIME + " INTEGER" +
");");
@@ -74,7 +76,17 @@ public class TemporaryStorageProvider extends ContentProvider {
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-
+ Log.d(Constants.TAG, "Upgrading files db from " + oldVersion + " to " + newVersion);
+
+ switch (oldVersion) {
+ case 1:
+ db.execSQL("DROP TABLE IF EXISTS files");
+ db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_FILES + " (" +
+ COLUMN_ID + " TEXT PRIMARY KEY, " +
+ COLUMN_NAME + " TEXT, " +
+ COLUMN_TIME + " INTEGER" +
+ ");");
+ }
}
}
@@ -82,13 +94,13 @@ public class TemporaryStorageProvider extends ContentProvider {
private File getFile(Uri uri) throws FileNotFoundException {
try {
- return getFile(Integer.parseInt(uri.getLastPathSegment()));
+ return getFile(uri.getLastPathSegment());
} catch (NumberFormatException e) {
throw new FileNotFoundException();
}
}
- private File getFile(int id) {
+ private File getFile(String id) {
return new File(getContext().getCacheDir(), "temp/" + id);
}
@@ -133,13 +145,15 @@ public class TemporaryStorageProvider extends ContentProvider {
if (!values.containsKey(COLUMN_TIME)) {
values.put(COLUMN_TIME, System.currentTimeMillis());
}
+ String uuid = UUID.randomUUID().toString();
+ values.put(COLUMN_ID, uuid);
int insert = (int) db.getWritableDatabase().insert(TABLE_FILES, null, values);
try {
- getFile(insert).createNewFile();
+ getFile(uuid).createNewFile();
} catch (IOException e) {
return null;
}
- return Uri.withAppendedPath(BASE_URI, Long.toString(insert));
+ return Uri.withAppendedPath(BASE_URI, uuid);
}
@Override
@@ -152,7 +166,7 @@ public class TemporaryStorageProvider extends ContentProvider {
selectionArgs, null, null, null);
if (files != null) {
while (files.moveToNext()) {
- getFile(files.getInt(0)).delete();
+ getFile(files.getString(0)).delete();
}
files.close();
return db.getWritableDatabase().delete(TABLE_FILES, selection, selectionArgs);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
index c51edf59c..badc3c131 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
@@ -34,6 +34,7 @@ import org.openintents.openpgp.util.OpenPgpApi;
import org.spongycastle.bcpg.CompressionAlgorithmTags;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel;
import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
import org.sufficientlysecure.keychain.pgp.PgpConstants;
@@ -47,6 +48,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
+import org.sufficientlysecure.keychain.remote.ui.SelectAllowedKeysActivity;
import org.sufficientlysecure.keychain.remote.ui.SelectSignKeyIdActivity;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
@@ -205,6 +207,18 @@ public class OpenPgpService extends RemoteService {
PendingIntent.FLAG_CANCEL_CURRENT);
}
+ private PendingIntent getSelectAllowedKeysIntent(Intent data) {
+ // If signature is unknown we return an _additional_ PendingIntent
+ // to retrieve the missing key
+ Intent intent = new Intent(getBaseContext(), SelectAllowedKeysActivity.class);
+ intent.putExtra(SelectAllowedKeysActivity.EXTRA_SERVICE_INTENT, data);
+ intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(getCurrentCallingPackage()));
+
+ return PendingIntent.getActivity(getBaseContext(), 0,
+ intent,
+ PendingIntent.FLAG_CANCEL_CURRENT);
+ }
+
private PendingIntent getShowKeyPendingIntent(long masterKeyId) {
Intent intent = new Intent(getBaseContext(), ViewKeyActivity.class);
intent.setData(KeyRings.buildGenericKeyRingUri(masterKeyId));
@@ -476,13 +490,12 @@ public class OpenPgpService extends RemoteService {
}
String currentPkg = getCurrentCallingPackage();
- Set<Long> allowedKeyIds;
+ Set<Long> allowedKeyIds = mProviderHelper.getAllowedKeyIdsForApp(
+ KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg));
+
if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 7) {
- allowedKeyIds = mProviderHelper.getAllKeyIdsForApp(
- ApiAccounts.buildBaseUri(currentPkg));
- } else {
- allowedKeyIds = mProviderHelper.getAllowedKeyIdsForApp(
- KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg));
+ allowedKeyIds.addAll(mProviderHelper.getAllKeyIdsForApp(
+ ApiAccounts.buildBaseUri(currentPkg)));
}
long inputLength = is.available();
@@ -575,6 +588,15 @@ public class OpenPgpService extends RemoteService {
return result;
} else {
LogEntryParcel errorMsg = pgpResult.getLog().getLast();
+
+ if (errorMsg.mType == OperationResult.LogType.MSG_DC_ERROR_NO_KEY) {
+ // allow user to select allowed keys
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_INTENT, getSelectAllowedKeysIntent(data));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
+ return result;
+ }
+
throw new Exception(getString(errorMsg.mType.getMsgId()));
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
index f312c0d44..5facde64f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
@@ -45,6 +45,7 @@ import org.sufficientlysecure.keychain.util.Log;
import java.util.ArrayList;
+// TODO: make extensible BaseRemoteServiceActivity and extend these cases from it
public class RemoteServiceActivity extends BaseActivity {
public static final String ACTION_REGISTER = Constants.INTENT_PREFIX + "API_ACTIVITY_REGISTER";
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectAllowedKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectAllowedKeysActivity.java
new file mode 100644
index 000000000..767106ff0
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectAllowedKeysActivity.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2015 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.view.View;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.ui.base.BaseActivity;
+import org.sufficientlysecure.keychain.util.Log;
+
+public class SelectAllowedKeysActivity extends BaseActivity {
+
+ public static final String EXTRA_SERVICE_INTENT = "data";
+
+ private Uri mAppUri;
+
+ private AppSettingsAllowedKeysListFragment mAllowedKeysFragment;
+
+ Intent mServiceData;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Inflate a "Done" custom action bar
+ setFullScreenDialogDoneClose(R.string.api_settings_save,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ save();
+ }
+ },
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ cancel();
+ }
+ });
+
+ Intent intent = getIntent();
+ mServiceData = intent.getParcelableExtra(EXTRA_SERVICE_INTENT);
+ 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
+ protected void initLayout() {
+ setContentView(R.layout.api_remote_select_allowed_keys);
+ }
+
+ private void save() {
+ mAllowedKeysFragment.saveAllowedKeys();
+ setResult(Activity.RESULT_OK, mServiceData);
+ finish();
+ }
+
+ private void cancel() {
+ setResult(Activity.RESULT_CANCELED);
+ finish();
+ }
+
+ private void loadData(Bundle savedInstanceState, Uri appUri) {
+ Uri allowedKeysUri = appUri.buildUpon().appendPath(KeychainContract.PATH_ALLOWED_KEYS).build();
+ Log.d(Constants.TAG, "allowedKeysUri: " + allowedKeysUri);
+ startListFragments(savedInstanceState, allowedKeysUri);
+ }
+
+ private void startListFragments(Bundle savedInstanceState, Uri allowedKeysUri) {
+ // 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 fragments
+ mAllowedKeysFragment = AppSettingsAllowedKeysListFragment.newInstance(allowedKeysUri);
+ // Add the fragment to the 'fragment_container' FrameLayout
+ // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.api_allowed_keys_list_fragment, mAllowedKeysFragment)
+ .commitAllowingStateLoss();
+ // do it immediately!
+ getSupportFragmentManager().executePendingTransactions();
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java
index ff0bf65be..f338a53a6 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java
@@ -126,7 +126,6 @@ public class CreateKeyEmailFragment extends Fragment {
if (mAdditionalEmailModels == null) {
mAdditionalEmailModels = new ArrayList<>();
}
-
if (mEmailAdapter == null) {
mEmailAdapter = new EmailAdapter(mAdditionalEmailModels, new View.OnClickListener() {
@Override
@@ -139,6 +138,9 @@ public class CreateKeyEmailFragment extends Fragment {
mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails);
}
}
+ if (mAdditionalEmailModels.isEmpty() && mCreateKeyActivity.mAdditionalEmails != null) {
+ mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails);
+ }
mEmailsRecyclerView.setAdapter(mEmailAdapter);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java
index 32173edf7..3379e0a6d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java
@@ -21,7 +21,6 @@ import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
-import android.text.Editable;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.view.LayoutInflater;
@@ -37,9 +36,6 @@ import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
import org.sufficientlysecure.keychain.ui.widget.PassphraseEditText;
import org.sufficientlysecure.keychain.util.Passphrase;
-import java.util.ArrayList;
-import java.util.Arrays;
-
public class CreateKeyPassphraseFragment extends Fragment {
// view
@@ -111,8 +107,8 @@ public class CreateKeyPassphraseFragment extends Fragment {
// initial values
// TODO: using String here is unsafe...
if (mCreateKeyActivity.mPassphrase != null) {
- mPassphraseEdit.setText(Arrays.toString(mCreateKeyActivity.mPassphrase.getCharArray()));
- mPassphraseEditAgain.setText(Arrays.toString(mCreateKeyActivity.mPassphrase.getCharArray()));
+ mPassphraseEdit.setText(new String(mCreateKeyActivity.mPassphrase.getCharArray()));
+ mPassphraseEditAgain.setText(new String(mCreateKeyActivity.mPassphrase.getCharArray()));
}
mPassphraseEdit.requestFocus();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
index d641f02f9..9c51893ce 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
@@ -79,17 +79,18 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
- mResultLayout = (LinearLayout) view.findViewById(R.id.result_main_layout);
+ // NOTE: These views are inside the activity!
+ mResultLayout = (LinearLayout) getActivity().findViewById(R.id.result_main_layout);
mResultLayout.setVisibility(View.GONE);
- mEncryptionIcon = (ImageView) view.findViewById(R.id.result_encryption_icon);
- mEncryptionText = (TextView) view.findViewById(R.id.result_encryption_text);
- mSignatureIcon = (ImageView) view.findViewById(R.id.result_signature_icon);
- mSignatureText = (TextView) view.findViewById(R.id.result_signature_text);
- mSignatureLayout = view.findViewById(R.id.result_signature_layout);
- mSignatureName = (TextView) view.findViewById(R.id.result_signature_name);
- mSignatureEmail = (TextView) view.findViewById(R.id.result_signature_email);
- mSignatureAction = (TextView) view.findViewById(R.id.result_signature_action);
+ mEncryptionIcon = (ImageView) getActivity().findViewById(R.id.result_encryption_icon);
+ mEncryptionText = (TextView) getActivity().findViewById(R.id.result_encryption_text);
+ mSignatureIcon = (ImageView) getActivity().findViewById(R.id.result_signature_icon);
+ mSignatureText = (TextView) getActivity().findViewById(R.id.result_signature_text);
+ mSignatureLayout = getActivity().findViewById(R.id.result_signature_layout);
+ mSignatureName = (TextView) getActivity().findViewById(R.id.result_signature_name);
+ mSignatureEmail = (TextView) getActivity().findViewById(R.id.result_signature_email);
+ mSignatureAction = (TextView) getActivity().findViewById(R.id.result_signature_action);
}
@@ -230,6 +231,7 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
KeychainContract.KeyRings.IS_REVOKED,
KeychainContract.KeyRings.IS_EXPIRED,
KeychainContract.KeyRings.VERIFIED,
+ KeychainContract.KeyRings.HAS_ANY_SECRET,
};
@SuppressWarnings("unused")
@@ -238,6 +240,7 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
static final int INDEX_IS_REVOKED = 3;
static final int INDEX_IS_EXPIRED = 4;
static final int INDEX_VERIFIED = 5;
+ static final int INDEX_HAS_ANY_SECRET = 6;
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
@@ -282,6 +285,7 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
boolean isRevoked = data.getInt(INDEX_IS_REVOKED) != 0;
boolean isExpired = data.getInt(INDEX_IS_EXPIRED) != 0;
boolean isVerified = data.getInt(INDEX_VERIFIED) > 0;
+ boolean isYours = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
if (isRevoked) {
mSignatureText.setText(R.string.decrypt_result_signature_revoked_key);
@@ -301,6 +305,16 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
onVerifyLoaded(true);
+ } else if (isYours) {
+
+ mSignatureText.setText(R.string.decrypt_result_signature_secret);
+ KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.VERIFIED);
+
+ setSignatureLayoutVisibility(View.VISIBLE);
+ setShowAction(signatureKeyId);
+
+ onVerifyLoaded(true);
+
} else if (isVerified) {
mSignatureText.setText(R.string.decrypt_result_signature_certified);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.VERIFIED);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
index 1b9ae917f..6f576a112 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
@@ -97,9 +97,9 @@ public class DecryptTextFragment extends DecryptFragment {
/**
* Create Intent Chooser but exclude decrypt activites
*/
- private Intent sendWithChooserExcludingEncrypt(String text) {
+ private Intent sendWithChooserExcludingDecrypt(String text) {
Intent prototype = createSendIntent(text);
- String title = getString(R.string.title_share_file);
+ String title = getString(R.string.title_share_message);
// we don't want to decrypt the decrypted, no inception ;)
String[] blacklist = new String[]{
@@ -147,7 +147,7 @@ public class DecryptTextFragment extends DecryptFragment {
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.decrypt_share: {
- startActivity(sendWithChooserExcludingEncrypt(mText.getText().toString()));
+ startActivity(sendWithChooserExcludingDecrypt(mText.getText().toString()));
break;
}
case R.id.decrypt_copy: {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
index 96ce101b5..1355bd3e6 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
@@ -240,7 +240,7 @@ public class KeyListFragment extends LoaderFragment
}
case R.id.menu_key_list_multi_select_all: {
// select all
- for (int i = 0; i < mStickyList.getCount(); i++) {
+ for (int i = 0; i < mAdapter.getCount(); i++) {
mStickyList.setItemChecked(i, true);
}
break;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java
index 151382da3..f571ba1e6 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java
@@ -24,7 +24,7 @@ import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.AdapterView;
@@ -42,7 +42,7 @@ import org.sufficientlysecure.keychain.remote.ui.AppsListFragment;
import org.sufficientlysecure.keychain.util.FabContainer;
import org.sufficientlysecure.keychain.util.Preferences;
-public class MainActivity extends ActionBarActivity implements FabContainer {
+public class MainActivity extends AppCompatActivity implements FabContainer {
public Drawer.Result result;
@@ -64,7 +64,7 @@ public class MainActivity extends ActionBarActivity implements FabContainer {
transaction.replace(R.id.main_fragment_container, mainFragment);
transaction.commit();
- mToolbar = (Toolbar) findViewById(R.id.activity_main_toolbar);
+ mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.setTitle(R.string.app_name);
setSupportActionBar(mToolbar);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java
index 6f19fc6ed..eef44a94b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java
@@ -27,6 +27,7 @@ import android.database.Cursor;
import android.graphics.PorterDuff;
import android.support.v4.widget.CursorAdapter;
import android.text.format.DateFormat;
+import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -88,6 +89,7 @@ public class KeyAdapter extends CursorAdapter {
public Long mMasterKeyId;
public TextView mMainUserId;
public TextView mMainUserIdRest;
+ public TextView mCreationDate;
public ImageView mStatus;
public View mSlinger;
public ImageButton mSlingerButton;
@@ -98,6 +100,7 @@ public class KeyAdapter extends CursorAdapter {
mStatus = (ImageView) view.findViewById(R.id.key_list_item_status_icon);
mSlinger = view.findViewById(R.id.key_list_item_slinger_view);
mSlingerButton = (ImageButton) view.findViewById(R.id.key_list_item_slinger_button);
+ mCreationDate = (TextView) view.findViewById(R.id.key_list_item_creation);
}
public void setData(Context context, Cursor cursor, Highlighter highlighter) {
@@ -125,7 +128,7 @@ public class KeyAdapter extends CursorAdapter {
boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
boolean isExpired = cursor.getInt(INDEX_IS_EXPIRED) != 0;
boolean isVerified = cursor.getInt(INDEX_VERIFIED) > 0;
- // boolean hasDuplicate = cursor.getInt(INDEX_HAS_DUPLICATE_USER_ID) == 1;
+ boolean hasDuplicate = cursor.getInt(INDEX_HAS_DUPLICATE_USER_ID) != 0;
mMasterKeyId = masterKeyId;
@@ -165,6 +168,21 @@ public class KeyAdapter extends CursorAdapter {
mMainUserId.setTextColor(context.getResources().getColor(R.color.black));
mMainUserIdRest.setTextColor(context.getResources().getColor(R.color.black));
}
+
+ if (hasDuplicate) {
+ String dateTime = DateUtils.formatDateTime(context,
+ cursor.getLong(INDEX_CREATION) * 1000,
+ DateUtils.FORMAT_SHOW_DATE
+ | DateUtils.FORMAT_SHOW_YEAR
+ | DateUtils.FORMAT_ABBREV_MONTH);
+
+ mCreationDate.setText(context.getString(R.string.label_key_created,
+ dateTime));
+ mCreationDate.setVisibility(View.VISIBLE);
+ } else {
+ mCreationDate.setVisibility(View.GONE);
+ }
+
}
}
@@ -262,20 +280,6 @@ public class KeyAdapter extends CursorAdapter {
}
}
- public boolean hasDuplicate() {
- return mHasDuplicate;
- }
-
- public String getCreationDate(Context context) {
- Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- creationCal.setTime(mCreation);
- // convert from UTC to time zone of device
- creationCal.setTimeZone(TimeZone.getDefault());
-
- return context.getString(R.string.label_creation) + ": "
- + DateFormat.getDateFormat(context).format(creationCal.getTime());
- }
-
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java
index 963e77fe9..7b911da96 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java
@@ -21,7 +21,7 @@ import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v7.app.AppCompatActivity;
import java.util.ArrayList;
@@ -41,7 +41,7 @@ public class PagerTabStripAdapter extends FragmentPagerAdapter {
}
}
- public PagerTabStripAdapter(ActionBarActivity activity) {
+ public PagerTabStripAdapter(AppCompatActivity activity) {
super(activity.getSupportFragmentManager());
mActivity = activity;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
index 3308a4500..a6cb52977 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
@@ -20,7 +20,7 @@ package org.sufficientlysecure.keychain.ui.adapter;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
-import android.text.format.DateFormat;
+import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -36,10 +36,6 @@ import org.sufficientlysecure.keychain.ui.util.Highlighter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
-
/**
* Yes this class is abstract!
@@ -138,14 +134,13 @@ abstract public class SelectKeyCursorAdapter extends CursorAdapter {
boolean duplicate = cursor.getLong(mIndexDuplicateUserId) > 0;
if (duplicate) {
- Date creationDate = new Date(cursor.getLong(mIndexCreation) * 1000);
- Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- creationCal.setTime(creationDate);
- // convert from UTC to time zone of device
- creationCal.setTimeZone(TimeZone.getDefault());
-
- h.creation.setText(context.getString(R.string.label_creation) + ": "
- + DateFormat.getDateFormat(context).format(creationCal.getTime()));
+ String dateTime = DateUtils.formatDateTime(context,
+ cursor.getLong(mIndexCreation) * 1000,
+ DateUtils.FORMAT_SHOW_DATE
+ | DateUtils.FORMAT_SHOW_YEAR
+ | DateUtils.FORMAT_ABBREV_MONTH);
+
+ h.creation.setText(context.getString(R.string.label_key_created, dateTime));
h.creation.setVisibility(View.VISIBLE);
} else {
h.creation.setVisibility(View.GONE);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java
index 44afed351..a1f00599c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java
@@ -24,7 +24,7 @@ import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v7.app.AppCompatActivity;
import java.util.ArrayList;
@@ -45,7 +45,7 @@ public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar.
}
}
- public TabsAdapter(ActionBarActivity activity, ViewPager pager) {
+ public TabsAdapter(AppCompatActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getSupportActionBar();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java
index 07d2ef8c0..0e752881f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java
@@ -20,7 +20,7 @@ package org.sufficientlysecure.keychain.ui.base;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -33,7 +33,7 @@ import org.sufficientlysecure.keychain.R;
/**
* Setups Toolbar
*/
-public abstract class BaseActivity extends ActionBarActivity {
+public abstract class BaseActivity extends AppCompatActivity {
protected Toolbar mToolbar;
protected View mStatusBar;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java
index ae66b59d4..91a7d361a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java
@@ -475,7 +475,7 @@ public class KeyFormattingUtils {
statusIcon.setImageDrawable(
context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout_24dp));
if (color == KeyFormattingUtils.DEFAULT_COLOR) {
- color = R.color.android_orange_light;
+ color = R.color.android_red_light;
}
statusIcon.setColorFilter(context.getResources().getColor(color),
PorterDuff.Mode.SRC_IN);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java
index b8d4ea7d2..5f71abdab 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java
@@ -29,6 +29,7 @@ import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.KeychainApplication;
import org.sufficientlysecure.keychain.util.Log;
import java.util.Hashtable;
@@ -40,36 +41,45 @@ public class QrCodeUtils {
/**
* Generate Bitmap with QR Code based on input.
- *
- * @param input
- * @param size
* @return QR Code as Bitmap
*/
public static Bitmap getQRCodeBitmap(final String input, final int size) {
+
try {
- final Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
- hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
- final BitMatrix result = new QRCodeWriter().encode(input, BarcodeFormat.QR_CODE, size,
- size, hints);
-
- final int width = result.getWidth();
- final int height = result.getHeight();
- final int[] pixels = new int[width * height];
-
- for (int y = 0; y < height; y++) {
- final int offset = y * width;
- for (int x = 0; x < width; x++) {
- pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.TRANSPARENT;
+
+ // the qrCodeCache is handled in KeychainApplication so we can
+ // properly react to onTrimMemory calls
+ Bitmap bitmap = KeychainApplication.qrCodeCache.get(input);
+ if (bitmap == null) {
+
+ Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
+ hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
+ BitMatrix result = new QRCodeWriter().encode(input, BarcodeFormat.QR_CODE, size,
+ size, hints);
+
+ int width = result.getWidth();
+ int height = result.getHeight();
+ int[] pixels = new int[width * height];
+
+ for (int y = 0; y < height; y++) {
+ final int offset = y * width;
+ for (int x = 0; x < width; x++) {
+ pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.TRANSPARENT;
+ }
}
+
+ bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
+
+ KeychainApplication.qrCodeCache.put(input, bitmap);
}
- final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
- } catch (final WriterException e) {
+ } catch (WriterException e) {
Log.e(Constants.TAG, "QrCodeUtils", e);
return null;
}
+
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java
index e21c5d510..e55f6b1ad 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java
@@ -17,9 +17,8 @@
package org.sufficientlysecure.keychain.ui.widget;
-import android.annotation.TargetApi;
import android.content.Context;
-import android.os.Build;
+import android.support.v7.widget.AppCompatAutoCompleteTextView;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
@@ -27,14 +26,13 @@ import android.util.AttributeSet;
import android.util.Patterns;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
-import android.widget.AutoCompleteTextView;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.ContactHelper;
import java.util.regex.Matcher;
-public class EmailEditText extends AutoCompleteTextView {
+public class EmailEditText extends AppCompatAutoCompleteTextView {
public EmailEditText(Context context) {
super(context);
@@ -51,12 +49,6 @@ public class EmailEditText extends AutoCompleteTextView {
init();
}
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public EmailEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- init();
- }
-
private void init() {
setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
reenableKeyboardSuggestions();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java
index 3d2e8b9df..63a1aade9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java
@@ -101,7 +101,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView
/*if (completionText.startsWith("0x")) {
}*/
- return null;
+ return "";
}
@Override
@@ -110,7 +110,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView
if (getContext() instanceof FragmentActivity) {
mLoaderManager = ((FragmentActivity) getContext()).getSupportLoaderManager();
- mLoaderManager.initLoader(hashCode(), null, this);
+ mLoaderManager.initLoader(0, null, this);
} else {
Log.e(Constants.TAG, "EncryptKeyCompletionView must be attached to a FragmentActivity, this is " + getContext().getClass());
}
@@ -136,7 +136,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView
where += " AND " + KeyRings.USER_ID + " LIKE ?";
return new CursorLoader(getContext(), baseUri, KeyAdapter.PROJECTION, where,
- new String[] { "%" + query + "%" }, null);
+ new String[]{"%" + query + "%"}, null);
}
mAdapter.setSearchQuery(null);
@@ -155,6 +155,14 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView
}
@Override
+ public void showDropDown() {
+ if (mAdapter == null || mAdapter.getCursor() == null || mAdapter.getCursor().isClosed()) {
+ return;
+ }
+ super.showDropDown();
+ }
+
+ @Override
public void onFocusChanged(boolean hasFocus, int direction, Rect previous) {
super.onFocusChanged(hasFocus, direction, previous);
if (hasFocus) {
@@ -171,7 +179,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView
}
Bundle args = new Bundle();
args.putString(ARG_QUERY, text.subSequence(start, end).toString());
- mLoaderManager.restartLoader(hashCode(), args, this);
+ mLoaderManager.restartLoader(0, args, this);
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java
index 2c75c3a7d..aecc81604 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java
@@ -24,8 +24,9 @@ import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
-import android.support.v7.internal.widget.TintSpinner;
+import android.support.v7.widget.AppCompatSpinner;
import android.text.format.DateFormat;
+import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
@@ -46,10 +47,10 @@ import java.util.Date;
import java.util.TimeZone;
/**
- * Use TintSpinner from AppCompat lib instead of Spinner. Fixes white dropdown icon.
+ * Use AppCompatSpinner from AppCompat lib instead of Spinner. Fixes white dropdown icon.
* Related: http://stackoverflow.com/a/27713090
*/
-public abstract class KeySpinner extends TintSpinner implements LoaderManager.LoaderCallbacks<Cursor> {
+public abstract class KeySpinner extends AppCompatSpinner implements LoaderManager.LoaderCallbacks<Cursor> {
public interface OnKeyChangedListener {
public void onKeyChanged(long masterKeyId);
}
@@ -167,14 +168,13 @@ public abstract class KeySpinner extends TintSpinner implements LoaderManager.Lo
boolean duplicate = cursor.getLong(mIndexDuplicate) > 0;
if (duplicate) {
- Date creationDate = new Date(cursor.getLong(mIndexCreationDate) * 1000);
- Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- creationCal.setTime(creationDate);
- // convert from UTC to time zone of device
- creationCal.setTimeZone(TimeZone.getDefault());
-
- vDuplicate.setText(context.getString(R.string.label_creation) + ": "
- + DateFormat.getDateFormat(context).format(creationCal.getTime()));
+ String dateTime = DateUtils.formatDateTime(context,
+ cursor.getLong(mIndexCreationDate) * 1000,
+ DateUtils.FORMAT_SHOW_DATE
+ | DateUtils.FORMAT_SHOW_YEAR
+ | DateUtils.FORMAT_ABBREV_MONTH);
+
+ vDuplicate.setText(context.getString(R.string.label_key_created, dateTime));
vDuplicate.setVisibility(View.VISIBLE);
} else {
vDuplicate.setVisibility(View.GONE);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java
index 153bf2ff2..1a034537c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java
@@ -17,17 +17,15 @@
package org.sufficientlysecure.keychain.ui.widget;
-import android.annotation.TargetApi;
import android.content.Context;
-import android.os.Build;
+import android.support.v7.widget.AppCompatAutoCompleteTextView;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
-import android.widget.AutoCompleteTextView;
import org.sufficientlysecure.keychain.util.ContactHelper;
-public class NameEditText extends AutoCompleteTextView {
+public class NameEditText extends AppCompatAutoCompleteTextView {
public NameEditText(Context context) {
super(context);
init();
@@ -43,12 +41,6 @@ public class NameEditText extends AutoCompleteTextView {
init();
}
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public NameEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- init();
- }
-
private void init() {
reenableKeyboardSuggestions();
initAdapter();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PassphraseEditText.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PassphraseEditText.java
index 377f701d1..9364c5ee9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PassphraseEditText.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PassphraseEditText.java
@@ -19,15 +19,13 @@ package org.sufficientlysecure.keychain.ui.widget;
import android.content.Context;
import android.graphics.Canvas;
+import android.support.v7.widget.AppCompatEditText;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.TypedValue;
-import android.widget.EditText;
-import org.sufficientlysecure.keychain.ui.widget.passwordstrengthindicator.PasswordStrengthBarView;
-
-public class PassphraseEditText extends EditText {
+public class PassphraseEditText extends AppCompatEditText {
PasswordStrengthBarView mPasswordStrengthBarView;
int mPasswordBarWidth;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthBarView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthBarView.java
index 9e06c4cce..e5886345f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthBarView.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthBarView.java
@@ -22,13 +22,10 @@
* SOFTWARE.
*/
-package org.sufficientlysecure.keychain.ui.widget.passwordstrengthindicator;
+package org.sufficientlysecure.keychain.ui.widget;
import android.content.Context;
import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
/**
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthView.java
index bc5018497..1487c3053 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthView.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthView.java
@@ -22,7 +22,7 @@
* SOFTWARE.
*/
-package org.sufficientlysecure.keychain.ui.widget.passwordstrengthindicator;
+package org.sufficientlysecure.keychain.ui.widget;
import android.content.Context;
import android.content.res.TypedArray;
@@ -56,7 +56,6 @@ import org.sufficientlysecure.keychain.R;
*/
public class PasswordStrengthView extends View {
-
protected int mMinWidth;
protected int mMinHeight;
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_content_copy_black_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_content_copy_black_24dp.png
new file mode 100644
index 000000000..dc8c85cce
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_content_copy_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_share_black_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_share_black_24dp.png
new file mode 100644
index 000000000..2839b1352
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_share_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_content_copy_black_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_content_copy_black_24dp.png
new file mode 100644
index 000000000..4ad9e552d
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_content_copy_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_share_black_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_share_black_24dp.png
new file mode 100644
index 000000000..f0ff945b8
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_share_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_content_copy_black_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_content_copy_black_24dp.png
new file mode 100644
index 000000000..c6f0e6b85
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_content_copy_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_share_black_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_share_black_24dp.png
new file mode 100644
index 000000000..4b3675766
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_share_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_content_copy_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_content_copy_black_24dp.png
new file mode 100644
index 000000000..081fbec5b
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_content_copy_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_share_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_share_black_24dp.png
new file mode 100644
index 000000000..09d4df6af
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_share_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_content_copy_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_content_copy_black_24dp.png
new file mode 100644
index 000000000..04c07fb56
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_content_copy_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_share_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_share_black_24dp.png
new file mode 100644
index 000000000..0fe15fc05
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_share_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/layout/api_remote_select_allowed_keys.xml b/OpenKeychain/src/main/res/layout/api_remote_select_allowed_keys.xml
new file mode 100644
index 000000000..e052ff333
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/api_remote_select_allowed_keys.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
+
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
+ android:padding="16dp"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/api_select_keys_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dp"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/api_select_keys_text" />
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <FrameLayout
+ android:id="@+id/api_allowed_keys_list_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </ScrollView>
+
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/create_yubikey_wait_fragment.xml b/OpenKeychain/src/main/res/layout/create_yubikey_wait_fragment.xml
index c7f9821eb..4e4b53118 100644
--- a/OpenKeychain/src/main/res/layout/create_yubikey_wait_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/create_yubikey_wait_fragment.xml
@@ -22,8 +22,7 @@
android:layout_marginTop="16dp"
android:layout_marginLeft="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="Hold Yubikey against device dawg"
- />
+ android:text="@string/yubikey_create" />
<ImageView
android:layout_width="match_parent"
diff --git a/OpenKeychain/src/main/res/layout/decrypt_file_fragment.xml b/OpenKeychain/src/main/res/layout/decrypt_file_fragment.xml
index 2ef411eaf..60673e475 100644
--- a/OpenKeychain/src/main/res/layout/decrypt_file_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/decrypt_file_fragment.xml
@@ -9,8 +9,6 @@
android:layout_height="wrap_content"
android:orientation="vertical">
- <include layout="@layout/decrypt_result_include" />
-
<View
android:id="@+id/status_divider"
android:layout_height="1dip"
diff --git a/OpenKeychain/src/main/res/layout/decrypt_result_include.xml b/OpenKeychain/src/main/res/layout/decrypt_result_include.xml
deleted file mode 100644
index f64d72987..000000000
--- a/OpenKeychain/src/main/res/layout/decrypt_result_include.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/result_main_layout"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/holo_gray_bright"
- tools:showIn="@layout/decrypt_text_fragment">
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:paddingTop="4dp"
- android:paddingBottom="4dp"
- android:animateLayoutChanges="true">
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <ImageView
- android:id="@+id/result_encryption_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/status_lock_open_24dp"
- android:layout_gravity="center_vertical" />
-
- <TextView
- android:id="@+id/result_encryption_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_marginLeft="8dp"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp"
- tools:text="Encryption status text"
- />
- </LinearLayout>
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <ImageView
- android:id="@+id/result_signature_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/status_signature_unverified_cutout_24dp"
- android:layout_gravity="center_vertical" />
-
- <TextView
- android:id="@+id/result_signature_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_marginLeft="8dp"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp"
- tools:text="Signature status text"
- />
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/result_signature_layout"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- android:paddingLeft="4dp"
- android:paddingRight="4dp"
- android:background="?android:selectableItemBackground"
- android:orientation="horizontal">
-
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:paddingRight="4dp"
- android:paddingLeft="4dp"
- android:gravity="center_vertical"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/result_signature_name"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- tools:text="Alice" />
-
- <TextView
- android:id="@+id/result_signature_email"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- tools:text="alice@example.com"
- />
-
- </LinearLayout>
-
- <View
- android:layout_width="1dip"
- android:layout_height="match_parent"
- android:gravity="right"
- android:layout_marginBottom="8dp"
- android:layout_marginTop="8dp"
- android:background="?android:attr/listDivider" />
-
- <TextView
- android:id="@+id/result_signature_action"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:text="Show"
- android:drawableRight="@drawable/ic_vpn_key_grey_24dp"
- android:drawablePadding="8dp"
- android:gravity="center_vertical"
- />
-
- </LinearLayout>
-
- </LinearLayout>
-
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider" />
-
-</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml b/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml
index a6099e25e..41d7c5c95 100644
--- a/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml
+++ b/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml
@@ -5,7 +5,7 @@
<include
android:id="@+id/toolbar_include"
- layout="@layout/toolbar_standalone_white" />
+ layout="@layout/toolbar_result_decrypt" />
<!--
fitsSystemWindows and layout_marginTop from
diff --git a/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml b/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml
index 635e61621..5b74905e7 100644
--- a/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml
@@ -4,8 +4,6 @@
android:layout_height="match_parent"
android:orientation="vertical">
- <include layout="@layout/decrypt_result_include" />
-
<LinearLayout
android:visibility="gone"
android:id="@+id/decrypt_text_valid"
diff --git a/OpenKeychain/src/main/res/layout/key_list_item.xml b/OpenKeychain/src/main/res/layout/key_list_item.xml
index fbe5f1326..6078b898f 100644
--- a/OpenKeychain/src/main/res/layout/key_list_item.xml
+++ b/OpenKeychain/src/main/res/layout/key_list_item.xml
@@ -26,7 +26,7 @@
android:id="@+id/key_list_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/label_main_user_id"
+ tools:text="@string/label_main_user_id"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
@@ -35,8 +35,20 @@
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end"
- android:text="user@example.com"
+ tools:text="user@example.com"
android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <TextView
+ android:id="@+id/key_list_item_creation"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:visibility="gone"
+ tools:visibility="visible"
+ tools:text="Created on 10/10/2010 10:00"
+ />
+
</LinearLayout>
<LinearLayout
diff --git a/OpenKeychain/src/main/res/layout/main_activity.xml b/OpenKeychain/src/main/res/layout/main_activity.xml
index 4a07053ea..45df0df71 100644
--- a/OpenKeychain/src/main/res/layout/main_activity.xml
+++ b/OpenKeychain/src/main/res/layout/main_activity.xml
@@ -1,19 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="match_parent"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
- android:id="@+id/activity_main_toolbar"
+ android:id="@+id/toolbar"
android:layout_width="match_parent"
- android:layout_height="?attr/actionBarSize"
+ android:layout_height="wrap_content"
android:elevation="4dp"
- android:background="?attr/colorPrimary"/>
+ android:background="?attr/colorPrimary"
+ android:minHeight="?attr/actionBarSize"
+ app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
+ app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
+ tools:ignore="UnusedAttribute" />
<FrameLayout
android:id="@+id/main_fragment_container"
android:layout_gravity="center"
android:layout_height="match_parent"
- android:layout_width="match_parent"/>
+ android:layout_width="match_parent" />
</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/passphrase_repeat_dialog.xml b/OpenKeychain/src/main/res/layout/passphrase_repeat_dialog.xml
index 5f323716c..ffc5266b5 100644
--- a/OpenKeychain/src/main/res/layout/passphrase_repeat_dialog.xml
+++ b/OpenKeychain/src/main/res/layout/passphrase_repeat_dialog.xml
@@ -33,7 +33,7 @@
android:ems="10"
android:layout_gravity="center_horizontal" />
- <org.sufficientlysecure.keychain.ui.widget.passwordstrengthindicator.PasswordStrengthBarView
+ <org.sufficientlysecure.keychain.ui.widget.PasswordStrengthBarView
android:id="@+id/passphrase_repeat_passphrase_strength"
android:layout_width="48dp"
android:layout_height="8dp"
diff --git a/OpenKeychain/src/main/res/layout/toolbar_result_decrypt.xml b/OpenKeychain/src/main/res/layout/toolbar_result_decrypt.xml
new file mode 100644
index 000000000..fe421449a
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/toolbar_result_decrypt.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/toolbar_include"
+ android:elevation="4dp"
+ android:background="@color/white"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <include
+ android:id="@+id/toolbar_inner_layout"
+ layout="@layout/toolbar_inner_layout_white" />
+
+ <LinearLayout
+ android:layout_below="@id/toolbar"
+ android:id="@+id/result_main_layout"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ tools:showIn="@layout/decrypt_text_fragment">
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
+ android:animateLayoutChanges="true">
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:id="@+id/result_encryption_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/status_lock_open_24dp"
+ android:layout_gravity="center_vertical" />
+
+ <TextView
+ android:id="@+id/result_encryption_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_marginLeft="8dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginBottom="8dp"
+ tools:text="Encryption status text" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:id="@+id/result_signature_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/status_signature_unverified_cutout_24dp"
+ android:layout_gravity="center_vertical" />
+
+ <TextView
+ android:id="@+id/result_signature_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_marginLeft="8dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginBottom="8dp"
+ tools:text="Signature status text" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/result_signature_layout"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ android:paddingLeft="4dp"
+ android:paddingRight="4dp"
+ android:background="?android:selectableItemBackground"
+ android:orientation="horizontal">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:paddingRight="4dp"
+ android:paddingLeft="4dp"
+ android:gravity="center_vertical"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/result_signature_name"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ tools:text="Alice" />
+
+ <TextView
+ android:id="@+id/result_signature_email"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ tools:text="alice@example.com" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="1dip"
+ android:layout_height="match_parent"
+ android:gravity="right"
+ android:layout_marginBottom="8dp"
+ android:layout_marginTop="8dp"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ android:id="@+id/result_signature_action"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:text="Show"
+ android:drawableRight="@drawable/ic_vpn_key_grey_24dp"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ </LinearLayout>
+
+</RelativeLayout>
diff --git a/OpenKeychain/src/main/res/menu/decrypt_menu.xml b/OpenKeychain/src/main/res/menu/decrypt_menu.xml
index c0d7a519f..9e90fc9c7 100644
--- a/OpenKeychain/src/main/res/menu/decrypt_menu.xml
+++ b/OpenKeychain/src/main/res/menu/decrypt_menu.xml
@@ -5,13 +5,13 @@
<item
android:id="@+id/decrypt_copy"
android:title="@string/btn_copy_decrypted_text"
- android:icon="@drawable/ic_action_encrypt_copy_24dp"
+ android:icon="@drawable/ic_content_copy_black_24dp"
app:showAsAction="ifRoom" />
<item
android:id="@+id/decrypt_share"
android:title="@string/btn_share_decrypted_text"
- android:icon="@drawable/ic_action_encrypt_share_24dp"
+ android:icon="@drawable/ic_share_black_24dp"
app:showAsAction="ifRoom" />
</menu> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml
index 4d92dac20..61ef859c3 100644
--- a/OpenKeychain/src/main/res/values/strings.xml
+++ b/OpenKeychain/src/main/res/values/strings.xml
@@ -41,7 +41,7 @@
<!-- section -->
<string name="section_user_ids">"Identities"</string>
- <string name="section_yubikey">"Yubikey"</string>
+ <string name="section_yubikey">"YubiKey"</string>
<string name="section_linked_system_contact">"Linked System Contact"</string>
<string name="section_should_you_trust">"Should you trust this key?"</string>
<string name="section_proof_details">Proof verification</string>
@@ -137,6 +137,7 @@
<string name="label_file_compression">"File compression"</string>
<string name="label_keyservers">"Keyservers"</string>
<string name="label_key_id">"Key ID"</string>
+ <string name="label_key_created">"Key created %s"</string>
<string name="label_creation">"Creation"</string>
<string name="label_expiry">"Expiry"</string>
<string name="label_usage">"Usage"</string>
@@ -287,6 +288,7 @@
<string name="decrypt_result_no_signature">"Not Signed"</string>
<string name="decrypt_result_invalid_signature">"Invalid signature!"</string>
<string name="decrypt_result_signature_uncertified">"Signed by <b>unconfirmed</b> key"</string>
+ <string name="decrypt_result_signature_secret">"Signed by your key"</string>
<string name="decrypt_result_signature_certified">"Signed by confirmed key"</string>
<string name="decrypt_result_signature_expired_key">"Signed by <b>expired</b> key!"</string>
<string name="decrypt_result_signature_revoked_key">"Signed by <b>revoked</b> key!"</string>
@@ -502,7 +504,7 @@
<string name="api_settings_delete_account">"Delete account"</string>
<string name="api_settings_package_name">"Package Name"</string>
<string name="api_settings_package_signature">"SHA-256 of Package Signature"</string>
- <string name="api_settings_accounts">"Accounts (deprecated API)"</string>
+ <string name="api_settings_accounts">"Accounts (old API)"</string>
<string name="api_settings_advanced">"Extended Information"</string>
<string name="api_settings_allowed_keys">"Allowed Keys"</string>
<string name="api_settings_settings">"Settings"</string>
@@ -520,6 +522,7 @@
<string name="api_select_pub_keys_text_no_user_ids">"Please select the recipients!"</string>
<string name="api_error_wrong_signature">"Signature check failed! Have you installed this app from a different source? If you are sure that this is not an attack, revoke this app's registration in OpenKeychain and then register the app again."</string>
<string name="api_select_sign_key_text">"Please select one of your existing keys or create a new one."</string>
+ <string name="api_select_keys_text">"None of the allowed keys is able to decrypt the content. Please select the allowed keys."</string>
<!-- Share -->
<string name="share_qr_code_dialog_title">"Share with QR Code"</string>
@@ -1277,11 +1280,12 @@
<string name="yubikey_serno">"Serial No: %s"</string>
<string name="yubikey_key_holder">"Key holder: "</string>
<string name="yubikey_key_holder_unset">"Key holder: &lt;unset&gt;"</string>
- <string name="yubikey_status_bound">"Yubikey matches and is bound to key"</string>
- <string name="yubikey_status_unbound">"Yubikey matches, can be bound to key"</string>
- <string name="yubikey_status_partly">"Yubikey matches, partly bound to key"</string>
+ <string name="yubikey_status_bound">"YubiKey matches and is bound to key"</string>
+ <string name="yubikey_status_unbound">"YubiKey matches, can be bound to key"</string>
+ <string name="yubikey_status_partly">"YubiKey matches, partly bound to key"</string>
+ <string name="yubikey_create">"Hold YubiKey against the back of your device."</string>
<string name="btn_import">"Import"</string>
- <string name="snack_yubi_other">Different key stored on Yubikey!</string>
+ <string name="snack_yubi_other">Different key stored on YubiKey!</string>
<string name="error_nfc">"NFC Error: %s"</string>
<string name="error_pin_nodefault">Default PIN was rejected!</string>
diff --git a/OpenKeychain/src/main/res/values/themes.xml b/OpenKeychain/src/main/res/values/themes.xml
index a1644707e..6ac09c5d7 100644
--- a/OpenKeychain/src/main/res/values/themes.xml
+++ b/OpenKeychain/src/main/res/values/themes.xml
@@ -8,17 +8,12 @@
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="colorAccent">@color/accent</item>
- <item name="android:windowNoTitle">true</item>
- <!-- remove actionbar, we use toolbar! -->
+ <!-- remove actionbar and title, we use toolbar! -->
+ <item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<!-- multi selection should overlay Toolbar! http://stackoverflow.com/a/26450875 -->
<item name="windowActionModeOverlay">true</item>
<item name="searchViewStyle">@style/MySearchViewStyle</item>
-
- <!-- dark action bar... -->
- <item name="theme">@style/ThemeOverlay.AppCompat.Dark</item>
- <!-- ...but light popup menu (white background) -->
- <item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
</style>
<!-- http://android-developers.blogspot.de/2014/10/appcompat-v21-material-design-for-pre.html -->