aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain')
-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
27 files changed, 337 insertions, 139 deletions
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;