aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2013-09-22 19:58:33 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2013-09-22 19:58:33 +0200
commit917c86b52454d2984ac116ace8e56c75f1e244fb (patch)
tree408697945836ce5adc36201f95feaaafa63412fe
parent7b2de96d152ab1de922a3303409e85afbbc00778 (diff)
downloadopen-keychain-917c86b52454d2984ac116ace8e56c75f1e244fb.tar.gz
open-keychain-917c86b52454d2984ac116ace8e56c75f1e244fb.tar.bz2
open-keychain-917c86b52454d2984ac116ace8e56c75f1e244fb.zip
Import keys with adapter, loader, and new design
-rw-r--r--OpenPGP-Keychain/AndroidManifest.xml2
-rw-r--r--OpenPGP-Keychain/res/layout/import_keys_keyserver_fragment.xml53
-rw-r--r--OpenPGP-Keychain/res/layout/import_keys_list_entry.xml108
-rw-r--r--OpenPGP-Keychain/res/layout/import_keys_list_entry_user_id.xml26
-rw-r--r--OpenPGP-Keychain/res/layout/select_key_item.xml66
-rw-r--r--OpenPGP-Keychain/res/values/strings.xml6
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/pgp/PgpImportExport.java46
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java16
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainIntentService.java14
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java45
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/DecryptActivity.java2
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java56
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java6
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java108
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java19
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java2
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java2
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerQueryActivity.java4
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java2
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java2
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java151
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java105
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java (renamed from OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/ImportKeysListLoader.java)42
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java2
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java4
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/KeyListAdapter.java273
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/SelectKeyCursorAdapter.java140
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/AlgorithmNames.java92
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/HkpKeyServer.java10
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/KeyValueSpinnerAdapter.java101
30 files changed, 705 insertions, 800 deletions
diff --git a/OpenPGP-Keychain/AndroidManifest.xml b/OpenPGP-Keychain/AndroidManifest.xml
index 003f02607..214ffeb0e 100644
--- a/OpenPGP-Keychain/AndroidManifest.xml
+++ b/OpenPGP-Keychain/AndroidManifest.xml
@@ -267,9 +267,7 @@
android:label="@string/title_signKey" />
<activity
android:name=".ui.ImportKeysActivity"
- android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_importKeys"
- android:uiOptions="splitActionBarWhenNarrow"
android:windowSoftInputMode="stateHidden" >
<!-- Keychain's own Actions -->
diff --git a/OpenPGP-Keychain/res/layout/import_keys_keyserver_fragment.xml b/OpenPGP-Keychain/res/layout/import_keys_keyserver_fragment.xml
index 2b0abf9b6..9e4771e65 100644
--- a/OpenPGP-Keychain/res/layout/import_keys_keyserver_fragment.xml
+++ b/OpenPGP-Keychain/res/layout/import_keys_keyserver_fragment.xml
@@ -3,28 +3,37 @@
android:layout_height="match_parent"
android:orientation="vertical" >
- <Spinner
- android:id="@+id/import_keys_server_key_server"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <LinearLayout
- android:layout_width="fill_parent"
+ <Button
+ android:id="@+id/import_keyserver_button"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal" >
-
- <EditText
- android:id="@+id/import_keys_server_query"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:inputType="textPersonName|textEmailAddress" />
-
- <Button
- android:id="@+id/import_keys_server_search"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/btn_search" />
- </LinearLayout>
+ android:text="@string/menu_keyServer" />
+
+ <!-- <Spinner -->
+ <!-- android:id="@+id/import_keys_server_key_server" -->
+ <!-- android:layout_width="fill_parent" -->
+ <!-- android:layout_height="wrap_content" /> -->
+
+
+ <!-- <LinearLayout -->
+ <!-- android:layout_width="fill_parent" -->
+ <!-- android:layout_height="wrap_content" -->
+ <!-- android:orientation="horizontal" > -->
+
+
+ <!-- <EditText -->
+ <!-- android:id="@+id/import_keys_server_query" -->
+ <!-- android:layout_width="0dip" -->
+ <!-- android:layout_height="wrap_content" -->
+ <!-- android:layout_weight="1" -->
+ <!-- android:inputType="textPersonName|textEmailAddress" /> -->
+
+
+ <!-- <Button -->
+ <!-- android:id="@+id/import_keys_server_search" -->
+ <!-- android:layout_width="wrap_content" -->
+ <!-- android:layout_height="wrap_content" -->
+ <!-- android:text="@string/btn_search" /> -->
+ <!-- </LinearLayout> -->
</LinearLayout> \ No newline at end of file
diff --git a/OpenPGP-Keychain/res/layout/import_keys_list_entry.xml b/OpenPGP-Keychain/res/layout/import_keys_list_entry.xml
new file mode 100644
index 000000000..aa8f56b83
--- /dev/null
+++ b/OpenPGP-Keychain/res/layout/import_keys_list_entry.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingLeft="3dip"
+ android:paddingRight="?android:attr/scrollbarSize"
+ android:singleLine="true" >
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" >
+
+ <CheckBox
+ android:id="@+id/selected"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clickable="false"
+ android:focusable="false"
+ android:focusableInTouchMode="false" />
+ <!-- focusable and clickable MUST be false to handle click and longClick in ListView Activity -->
+
+ <LinearLayout
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip" >
+
+ <TextView
+ android:id="@+id/mainUserId"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Main User ID"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/fingerprint"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="fingerprint"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <TextView
+ android:id="@+id/mainUserIdRest"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="&lt;user@somewhere.com>"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="right"
+ android:minWidth="90dip"
+ android:orientation="vertical"
+ android:paddingLeft="3dip" >
+
+ <TextView
+ android:id="@+id/keyId"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ android:text="BBBBBBBB"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:typeface="monospace" />
+
+ <TextView
+ android:id="@+id/algorithm"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <TextView
+ android:id="@+id/status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="#e00" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="30dip"
+ android:orientation="vertical" >
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenPGP-Keychain/res/layout/import_keys_list_entry_user_id.xml b/OpenPGP-Keychain/res/layout/import_keys_list_entry_user_id.xml
new file mode 100644
index 000000000..9d3a4a1ab
--- /dev/null
+++ b/OpenPGP-Keychain/res/layout/import_keys_list_entry_user_id.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_marginRight="?android:attr/scrollbarSize"
+ android:singleLine="true"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:paddingRight="3dip">
+
+</TextView>
diff --git a/OpenPGP-Keychain/res/layout/select_key_item.xml b/OpenPGP-Keychain/res/layout/select_key_item.xml
index 5eed7c268..d5b1655ed 100644
--- a/OpenPGP-Keychain/res/layout/select_key_item.xml
+++ b/OpenPGP-Keychain/res/layout/select_key_item.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+<!--
+ Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,69 +15,66 @@
limitations under the License.
-->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:singleLine="true"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingLeft="3dip"
android:paddingRight="?android:attr/scrollbarSize"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:layout_width="fill_parent">
+ android:singleLine="true" >
<CheckBox
android:id="@+id/selected"
- android:focusable="false"
- android:focusableInTouchMode="false"
- android:clickable="false"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
+ android:layout_height="wrap_content"
+ android:clickable="false"
+ android:focusable="false"
+ android:focusableInTouchMode="false" />
<LinearLayout
- android:orientation="vertical"
- android:paddingLeft="5dip"
android:layout_width="0dip"
android:layout_height="wrap_content"
- android:layout_weight="1">
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:paddingLeft="5dip" >
<TextView
android:id="@+id/mainUserId"
- android:text="Main User ID"
- android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
+ android:layout_height="wrap_content"
+ android:text="Main User ID"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/mainUserIdRest"
- android:text="&lt;user@example.com&gt;"
- android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
-
+ android:layout_height="wrap_content"
+ android:text="&lt;user@example.com>"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<LinearLayout
- android:orientation="vertical"
- android:minWidth="90dip"
- android:paddingLeft="3dip"
- android:gravity="right"
android:layout_width="wrap_content"
- android:layout_height="wrap_content">
+ android:layout_height="wrap_content"
+ android:gravity="right"
+ android:minWidth="90dip"
+ android:orientation="vertical"
+ android:paddingLeft="3dip" >
<TextView
android:id="@+id/keyId"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
android:text="BBBBBBBB"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:typeface="monospace"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"/>
+ android:typeface="monospace" />
<TextView
android:id="@+id/status"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:text="expired"
- android:textStyle="italic"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
-
+ android:layout_height="wrap_content"
+ android:text="expired"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textStyle="italic" />
</LinearLayout>
-</LinearLayout>
+</LinearLayout> \ No newline at end of file
diff --git a/OpenPGP-Keychain/res/values/strings.xml b/OpenPGP-Keychain/res/values/strings.xml
index 5975665e9..544910330 100644
--- a/OpenPGP-Keychain/res/values/strings.xml
+++ b/OpenPGP-Keychain/res/values/strings.xml
@@ -157,7 +157,7 @@
<string name="notValid">not valid</string>
<string name="nKeyServers">%s key server(s)</string>
<string name="fingerprint">Fingerprint:</string>
- <string name="secretKeyring">Secret Keyring:</string>
+ <string name="secretKey">Secret Key:</string>
<!-- choice_lowerCase: capitalized first word, no punctuation -->
<string name="choice_none">None</string>
@@ -347,8 +347,8 @@
<string name="help_about_version">Version:</string>
<!-- Import -->
- <string name="import_import">Import key(s) (only locally)</string>
- <string name="import_sign_and_upload">Import, Sign, and upload key(s)</string>
+ <string name="import_import">Import selected keys</string>
+ <string name="import_sign_and_upload">Import, Sign, and upload selected keys</string>
<string name="import_finish">Finish</string>
<!-- Intent labels -->
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
index d7ab5d8fe..eff8de224 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
@@ -24,10 +24,11 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
import org.spongycastle.bcpg.ArmoredOutputStream;
-import org.spongycastle.openpgp.operator.KeyFingerPrintCalculator;
-import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPObjectFactory;
@@ -36,6 +37,7 @@ import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPUtil;
+import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
@@ -100,17 +102,23 @@ public class PgpImportExport {
}
}
- public Bundle importKeyRings(InputData data) throws PgpGeneralException, FileNotFoundException,
- PGPException, IOException {
+ /**
+ * Imports keys from given data. If keyIds is given only those are imported
+ *
+ * @param data
+ * @param keyIds
+ * @return
+ * @throws PgpGeneralException
+ * @throws FileNotFoundException
+ * @throws PGPException
+ * @throws IOException
+ */
+ public Bundle importKeyRings(InputData data, ArrayList<Long> keyIds)
+ throws PgpGeneralException, FileNotFoundException, PGPException, IOException {
Bundle returnData = new Bundle();
updateProgress(R.string.progress_importingSecretKeys, 0, 100);
- if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- throw new PgpGeneralException(
- mContext.getString(R.string.error_externalStorageNotReady));
- }
-
PositionAwareInputStream progressIn = new PositionAwareInputStream(data.getInputStream());
// need to have access to the bufferedInput, so we can reuse it for the possible
@@ -137,7 +145,16 @@ public class PgpImportExport {
int status = Integer.MIN_VALUE; // out of bounds value
- status = storeKeyRingInCache(keyring);
+ if (keyIds != null) {
+ if (keyIds.contains(keyring.getPublicKey().getKeyID())) {
+ status = storeKeyRingInCache(keyring);
+ } else {
+ Log.d(Constants.TAG, "not selected! key id: "
+ + keyring.getPublicKey().getKeyID());
+ }
+ } else {
+ status = storeKeyRingInCache(keyring);
+ }
if (status == Id.return_value.error) {
throw new PgpGeneralException(
@@ -264,11 +281,14 @@ public class PgpImportExport {
if (save) {
ProviderHelper.saveKeyRing(mContext, secretKeyRing);
- // TODO: preserve certifications (http://osdir.com/ml/encryption.bouncy-castle.devel/2007-01/msg00054.html ?)
+ // TODO: preserve certifications
+ // (http://osdir.com/ml/encryption.bouncy-castle.devel/2007-01/msg00054.html ?)
PGPPublicKeyRing newPubRing = null;
- for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(secretKeyRing.getPublicKeys())) {
+ for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(
+ secretKeyRing.getPublicKeys())) {
if (newPubRing == null) {
- newPubRing = new PGPPublicKeyRing(key.getEncoded(), new JcaKeyFingerprintCalculator());
+ newPubRing = new PGPPublicKeyRing(key.getEncoded(),
+ new JcaKeyFingerprintCalculator());
}
newPubRing = PGPPublicKeyRing.insertPublicKey(newPubRing, key);
}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java
index e5cf91f39..37a3cb8e2 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java
@@ -137,7 +137,7 @@ public class PgpKeyHelper {
PGPPublicKey masterKey = null;
for (int i = 0; i < encryptKeys.size(); ++i) {
PGPPublicKey key = encryptKeys.get(i);
- if (!isExpired(key) && !key.isRevoked()) {
+ if (!isExpired(key) && !key.isRevoked()) {
if (key.isMasterKey()) {
masterKey = key;
} else {
@@ -488,7 +488,7 @@ public class PgpKeyHelper {
return isSecretKeyPrivateEmpty(secretKey);
}
- public static String getSmallFingerPrint(long keyId) {
+ public static String convertKeyIdToHex(long keyId) {
String fingerPrint = Long.toHexString(keyId & 0xffffffffL).toUpperCase(Locale.US);
while (fingerPrint.length() < 8) {
fingerPrint = "0" + fingerPrint;
@@ -496,11 +496,17 @@ public class PgpKeyHelper {
return fingerPrint;
}
- public static String keyToHex(long keyId) {
- return getSmallFingerPrint(keyId >> 32) + getSmallFingerPrint(keyId);
+ /**
+ * TODO: what is the difference to the other function?
+ *
+ * @param keyId
+ * @return
+ */
+ public static String convertKeyToHex(long keyId) {
+ return convertKeyIdToHex(keyId >> 32) + convertKeyIdToHex(keyId);
}
- public static long keyFromHex(String data) {
+ public static long convertHexToKeyId(String data) {
int len = data.length();
String s2 = data.substring(len - 8);
String s1 = data.substring(0, len - 8);
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainIntentService.java
index 749b46405..8f8f1bdca 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -27,7 +27,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.List;
+import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
@@ -45,6 +47,7 @@ import org.sufficientlysecure.keychain.pgp.PgpOperation;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
import org.sufficientlysecure.keychain.util.HkpKeyServer;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.KeyServer.KeyInfo;
@@ -142,7 +145,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
public static final String IMPORT_INPUT_STREAM = "import_input_stream";
public static final String IMPORT_FILENAME = "import_filename";
public static final String IMPORT_BYTES = "import_bytes";
- // public static final String IMPORT_KEY_TYPE = "importKeyType";
+ public static final String IMPORT_KEY_LIST = "import_key_list";
// export key
public static final String EXPORT_OUTPUT_STREAM = "export_output_stream";
@@ -630,11 +633,6 @@ public class KeychainIntentService extends IntentService implements ProgressDial
/* Input */
int target = data.getInt(TARGET);
- // int keyType = Id.type.public_key;
- // if (data.containsKey(IMPORT_KEY_TYPE)) {
- // keyType = data.getInt(IMPORT_KEY_TYPE);
- // }
-
/* Operation */
InputStream inStream = null;
long inLength = -1;
@@ -666,8 +664,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial
Bundle resultData = new Bundle();
+ ArrayList<Long> keyIds = (ArrayList<Long>) data.getSerializable(IMPORT_KEY_LIST);
+
PgpImportExport pgpImportExport = new PgpImportExport(this, this);
- resultData = pgpImportExport.importKeyRings(inputData);
+ resultData = pgpImportExport.importKeyRings(inputData, keyIds);
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
} catch (Exception e) {
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java
index 0f919fc67..30804ee90 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java
@@ -17,10 +17,6 @@
package org.sufficientlysecure.keychain.service.remote;
-import java.util.HashMap;
-
-import org.spongycastle.bcpg.HashAlgorithmTags;
-import org.spongycastle.openpgp.PGPEncryptedData;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.sufficientlysecure.keychain.Constants;
@@ -29,7 +25,8 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.ui.SelectSecretKeyActivity;
-import org.sufficientlysecure.keychain.util.KeyValueSpinnerAdapter;
+import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter;
+import org.sufficientlysecure.keychain.util.AlgorithmNames;
import org.sufficientlysecure.keychain.util.Log;
import android.app.Activity;
@@ -114,18 +111,10 @@ public class AppSettingsFragment extends Fragment {
mHashAlgorithm = (Spinner) view.findViewById(R.id.api_app_settings_hash_algorithm);
mCompression = (Spinner) view.findViewById(R.id.api_app_settings_compression);
- HashMap<Integer, String> encryptionMap = new HashMap<Integer, String>();
- encryptionMap.put(PGPEncryptedData.AES_128, "AES-128");
- encryptionMap.put(PGPEncryptedData.AES_192, "AES-192");
- encryptionMap.put(PGPEncryptedData.AES_256, "AES-256");
- encryptionMap.put(PGPEncryptedData.BLOWFISH, "Blowfish");
- encryptionMap.put(PGPEncryptedData.TWOFISH, "Twofish");
- encryptionMap.put(PGPEncryptedData.CAST5, "CAST5");
- encryptionMap.put(PGPEncryptedData.DES, "DES");
- encryptionMap.put(PGPEncryptedData.TRIPLE_DES, "Triple DES");
- encryptionMap.put(PGPEncryptedData.IDEA, "IDEA");
-
- encryptionAdapter = new KeyValueSpinnerAdapter(getActivity(), encryptionMap);
+ AlgorithmNames algorithmNames = new AlgorithmNames(getActivity());
+
+ encryptionAdapter = new KeyValueSpinnerAdapter(getActivity(),
+ algorithmNames.getEncryptionNames());
mEncryptionAlgorithm.setAdapter(encryptionAdapter);
mEncryptionAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() {
@@ -139,16 +128,7 @@ public class AppSettingsFragment extends Fragment {
}
});
- HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
- hashMap.put(HashAlgorithmTags.MD5, "MD5");
- hashMap.put(HashAlgorithmTags.RIPEMD160, "RIPEMD-160");
- hashMap.put(HashAlgorithmTags.SHA1, "SHA-1");
- hashMap.put(HashAlgorithmTags.SHA224, "SHA-224");
- hashMap.put(HashAlgorithmTags.SHA256, "SHA-256");
- hashMap.put(HashAlgorithmTags.SHA384, "SHA-384");
- hashMap.put(HashAlgorithmTags.SHA512, "SHA-512");
-
- hashAdapter = new KeyValueSpinnerAdapter(getActivity(), hashMap);
+ hashAdapter = new KeyValueSpinnerAdapter(getActivity(), algorithmNames.getHashNames());
mHashAlgorithm.setAdapter(hashAdapter);
mHashAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() {
@@ -162,15 +142,8 @@ public class AppSettingsFragment extends Fragment {
}
});
- HashMap<Integer, String> compressionMap = new HashMap<Integer, String>();
- compressionMap.put(Id.choice.compression.none, getString(R.string.choice_none) + " ("
- + getString(R.string.fast) + ")");
- compressionMap.put(Id.choice.compression.zip, "ZIP (" + getString(R.string.fast) + ")");
- compressionMap.put(Id.choice.compression.zlib, "ZLIB (" + getString(R.string.fast) + ")");
- compressionMap.put(Id.choice.compression.bzip2, "BZIP2 (" + getString(R.string.very_slow)
- + ")");
-
- compressionAdapter = new KeyValueSpinnerAdapter(getActivity(), compressionMap);
+ compressionAdapter = new KeyValueSpinnerAdapter(getActivity(),
+ algorithmNames.getCompressionNames());
mCompression.setAdapter(compressionAdapter);
mCompression.setOnItemSelectedListener(new OnItemSelectedListener() {
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/DecryptActivity.java
index 136a53000..2aab7ac22 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/DecryptActivity.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/DecryptActivity.java
@@ -773,7 +773,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
mSignatureKeyId = returnData
.getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
mUserIdRest.setText("id: "
- + PgpKeyHelper.getSmallFingerPrint(mSignatureKeyId));
+ + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId));
if (userId == null) {
userId = getResources().getString(R.string.unknownUserId);
}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
index 48655655a..ecccd64d0 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
@@ -17,12 +17,15 @@
package org.sufficientlysecure.keychain.ui;
+import java.util.ArrayList;
+import java.util.List;
+
import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
@@ -44,7 +47,6 @@ import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
import com.actionbarsherlock.app.SherlockFragmentActivity;
-import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
public class ImportKeysActivity extends SherlockFragmentActivity implements OnNavigationListener {
@@ -152,27 +154,6 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa
mListFragment.load(importData, importFilename);
}
- /**
- * ActionBar menu is created based on class variables to change it at runtime
- *
- */
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- menu.add(1, Id.menu.option.key_server, 0, R.string.menu_keyServer).setShowAsAction(
- MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
- menu.add(1, Id.menu.option.import_from_file, 1, R.string.menu_importFromFile)
- .setShowAsAction(
- MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
- menu.add(1, Id.menu.option.import_from_qr_code, 2, R.string.menu_importFromQrCode)
- .setShowAsAction(
- MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
- menu.add(1, Id.menu.option.import_from_nfc, 3, R.string.menu_importFromNfc)
- .setShowAsAction(
- MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-
- return true;
- }
-
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -184,23 +165,6 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa
startActivity(intent);
return true;
- case Id.menu.option.key_server:
- startActivityForResult(new Intent(this, KeyServerQueryActivity.class), 0);
-
- return true;
-
- // case Id.menu.option.import_from_file:
- // showImportFromFileDialog();
- // return true;
-
- // case Id.menu.option.import_from_qr_code:
- // importFromQrCode();
- // return true;
- //
- // case Id.menu.option.import_from_nfc:
- // importFromNfc();
- // return true;
-
default:
return super.onOptionsItemSelected(item);
@@ -329,8 +293,16 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa
// fill values for this action
Bundle data = new Bundle();
- // TODO: check for key type?
- // data.putInt(KeychainIntentService.IMPORT_KEY_TYPE, Id.type.secret_key);
+ // get selected key ids
+ List<ImportKeysListEntry> listEntries = mListFragment.getData();
+ ArrayList<Long> selectedKeyIds = new ArrayList<Long>();
+ for (ImportKeysListEntry entry : listEntries) {
+ if (entry.isSelected()) {
+ selectedKeyIds.add(entry.keyId);
+ }
+ }
+
+ data.putSerializable(KeychainIntentService.IMPORT_KEY_LIST, selectedKeyIds);
if (mListFragment.getKeyBytes() != null) {
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES);
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java
index 026939cd6..7d77a7b09 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java
@@ -68,8 +68,8 @@ public class ImportKeysFileFragment extends Fragment {
// open .asc or .gpg files
// setting it to text/plain prevents Cynaogenmod's file manager from selecting asc
// or gpg types!
- FileHelper.openFile(ImportKeysFileFragment.this, mFilename.getText().toString(), "*/*",
- Id.request.filename);
+ FileHelper.openFile(ImportKeysFileFragment.this, mFilename.getText().toString(),
+ "*/*", Id.request.filename);
}
});
@@ -84,7 +84,7 @@ public class ImportKeysFileFragment extends Fragment {
// set default path
String path = Constants.path.APP_DIR + "/";
- if (getArguments() != null) {
+ if (getArguments() != null && getArguments().containsKey(ARG_PATH)) {
path = getArguments().getString(ARG_PATH);
}
mFilename.setText(path);
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
index 1b12adb91..1925a5509 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
@@ -17,37 +17,32 @@
package org.sufficientlysecure.keychain.ui;
-import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.ui.widget.ImportKeysListLoader;
-import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.R;
-
-import com.actionbarsherlock.app.SherlockListFragment;
+import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter;
+import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
+import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListLoader;
+import org.sufficientlysecure.keychain.util.Log;
import android.app.Activity;
import android.os.Bundle;
-import android.support.v4.content.Loader;
import android.support.v4.app.LoaderManager;
+import android.support.v4.content.Loader;
import android.view.View;
import android.widget.ListView;
-import android.widget.SimpleAdapter;
+
+import com.actionbarsherlock.app.SherlockListFragment;
public class ImportKeysListFragment extends SherlockListFragment implements
- LoaderManager.LoaderCallbacks<List<Map<String, String>>> {
- // public static final String ARG_IMPORT_DATA = "bytes";
- // public static final String ARG_IMPORT_FILENAME = "filename";
+ LoaderManager.LoaderCallbacks<List<ImportKeysListEntry>> {
private Activity mActivity;
- private SimpleAdapter mAdapter;
+ private ImportKeysAdapter mAdapter;
private byte[] mKeyBytes;
private String mImportFilename;
-
-
public byte[] getKeyBytes() {
return mKeyBytes;
@@ -57,38 +52,19 @@ public class ImportKeysListFragment extends SherlockListFragment implements
return mImportFilename;
}
+ public List<ImportKeysListEntry> getData() {
+ return mAdapter.getData();
+ }
+
/**
* Creates new instance of this fragment
*/
public static ImportKeysListFragment newInstance() {
ImportKeysListFragment frag = new ImportKeysListFragment();
- Bundle args = new Bundle();
-
- frag.setArguments(args);
return frag;
}
- @Override
- public void onListItemClick(ListView listView, View view, int position, long id) {
- // Map<String, String> item = (Map<String, String>) listView.getItemAtPosition(position);
- // String userId = item.get(ImportKeysListLoader.MAP_ATTR_USER_ID);
- }
-
- /**
- * Resume is called after rotating
- */
- @Override
- public void onResume() {
- super.onResume();
-
- // Start out with a progress indicator.
- setListShown(false);
-
- // reload list
- getLoaderManager().restartLoader(0, null, this);
- }
-
/**
* Define Adapter and Loader on create of Activity
*/
@@ -96,10 +72,7 @@ public class ImportKeysListFragment extends SherlockListFragment implements
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- mActivity = this.getActivity();
-
- // mKeyBytes = getArguments().getByteArray(ARG_IMPORT_DATA);
- // mImportFilename = getArguments().getString(ARG_IMPORT_FILENAME);
+ mActivity = getActivity();
// register long press context menu
registerForContextMenu(getListView());
@@ -109,11 +82,7 @@ public class ImportKeysListFragment extends SherlockListFragment implements
setEmptyText(mActivity.getString(R.string.error_nothingImport));
// Create an empty adapter we will use to display the loaded data.
- String[] from = new String[] {};
- int[] to = new int[] {};
- List<Map<String, String>> data = new ArrayList<Map<String, String>>();
- mAdapter = new SimpleAdapter(getActivity(), data, android.R.layout.two_line_list_item,
- from, to);
+ mAdapter = new ImportKeysAdapter(getActivity());
setListAdapter(mAdapter);
// Start out with a progress indicator.
@@ -124,39 +93,37 @@ public class ImportKeysListFragment extends SherlockListFragment implements
getLoaderManager().initLoader(0, null, this);
}
- public void load(byte[] importData, String importFilename) {
- mKeyBytes = importData;
- mImportFilename = importFilename;
+ @Override
+ public void onListItemClick(ListView l, View v, int position, long id) {
+ super.onListItemClick(l, v, position, id);
+
+ // Select checkbox!
+ // Update underlying data and notify adapter of change. The adapter will
+ // update the view automatically.
+ ImportKeysListEntry entry = mAdapter.getItem(position);
+ entry.setSelected(!entry.isSelected());
+ mAdapter.notifyDataSetChanged();
+ }
- getLoaderManager().initLoader(0, null, this);
+ public void load(byte[] importData, String importFilename) {
+ this.mKeyBytes = importData;
+ this.mImportFilename = importFilename;
}
@Override
- public Loader<List<Map<String, String>>> onCreateLoader(int id, Bundle args) {
+ public Loader<List<ImportKeysListEntry>> onCreateLoader(int id, Bundle args) {
return new ImportKeysListLoader(mActivity, mKeyBytes, mImportFilename);
}
@Override
- public void onLoadFinished(Loader<List<Map<String, String>>> loader,
- List<Map<String, String>> data) {
- // Set the new data in the adapter.
- // for (String item : data) {
- // mAdapter.add(item);
- // }
+ public void onLoadFinished(Loader<List<ImportKeysListEntry>> loader,
+ List<ImportKeysListEntry> data) {
Log.d(Constants.TAG, "data: " + data);
- // TODO: real swapping the data to the already defined adapter doesn't work
- // Workaround: recreate adapter!
- // http://stackoverflow.com/questions/2356091/android-add-function-of-arrayadapter-not-working
- // mAdapter = new ArrayAdapter<String>(mActivity, android.R.layout.two_line_list_item,
- // data);
-
- String[] from = new String[] { ImportKeysListLoader.MAP_ATTR_USER_ID,
- ImportKeysListLoader.MAP_ATTR_FINGERPINT };
- int[] to = new int[] { android.R.id.text1, android.R.id.text2 };
- mAdapter = new SimpleAdapter(getActivity(), data, android.R.layout.two_line_list_item,
- from, to);
+ // swap in the real data!
+ mAdapter.setData(data);
mAdapter.notifyDataSetChanged();
+
setListAdapter(mAdapter);
// The list should now be shown.
@@ -168,10 +135,9 @@ public class ImportKeysListFragment extends SherlockListFragment implements
}
@Override
- public void onLoaderReset(Loader<List<Map<String, String>>> loader) {
+ public void onLoaderReset(Loader<List<ImportKeysListEntry>> loader) {
// Clear the data in the adapter.
- // Not available in SimpleAdapter!
- // mAdapter.clear();
+ mAdapter.clear();
}
}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java
index 334f56c7c..106c8ebef 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java
@@ -19,13 +19,17 @@ package org.sufficientlysecure.keychain.ui;
import org.sufficientlysecure.keychain.R;
+import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
public class ImportKeysServerFragment extends Fragment {
+ private Button mButton;
/**
* Creates new instance of this fragment
@@ -44,8 +48,19 @@ public class ImportKeysServerFragment extends Fragment {
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- return inflater.inflate(R.layout.import_keys_keyserver_fragment, container, false);
- }
+ View view = inflater.inflate(R.layout.import_keys_keyserver_fragment, container, false);
+
+ mButton = (Button) view.findViewById(R.id.import_keyserver_button);
+ mButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // TODO: use fragment instead of activity, handle onresult here!
+ startActivityForResult(new Intent(getActivity(), KeyServerQueryActivity.class), 0);
+ }
+ });
+
+ return view;
+ }
}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
index 2e2c3cfcd..f6f8e24ef 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
@@ -23,7 +23,7 @@ import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
-import org.sufficientlysecure.keychain.ui.widget.KeyListAdapter;
+import org.sufficientlysecure.keychain.ui.adapter.KeyListAdapter;
import org.sufficientlysecure.keychain.R;
import android.content.Intent;
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java
index f8d02b7b3..7f44429f2 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java
@@ -22,7 +22,7 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.ui.widget.KeyListAdapter;
+import org.sufficientlysecure.keychain.ui.adapter.KeyListAdapter;
import android.database.Cursor;
import android.net.Uri;
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerQueryActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerQueryActivity.java
index 22f4b65fe..9f540a232 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerQueryActivity.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyServerQueryActivity.java
@@ -140,7 +140,7 @@ public class KeyServerQueryActivity extends SherlockFragmentActivity {
if (ACTION_LOOK_UP_KEY_ID.equals(action) || ACTION_LOOK_UP_KEY_ID_AND_RETURN.equals(action)) {
long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0);
if (keyId != 0) {
- String query = "0x" + PgpKeyHelper.keyToHex(keyId);
+ String query = "0x" + PgpKeyHelper.convertKeyToHex(keyId);
mQuery.setText(query);
search(query);
}
@@ -308,7 +308,7 @@ public class KeyServerQueryActivity extends SherlockFragmentActivity {
mainUserId.setText(userId);
}
- keyId.setText(PgpKeyHelper.getSmallFingerPrint(keyInfo.keyId));
+ keyId.setText(PgpKeyHelper.convertKeyIdToHex(keyInfo.keyId));
if (mainUserIdRest.getText().length() == 0) {
mainUserIdRest.setVisibility(View.GONE);
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
index fe7199cc0..65bcc0fab 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
@@ -28,7 +28,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
-import org.sufficientlysecure.keychain.ui.widget.SelectKeyCursorAdapter;
+import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter;
import android.app.Activity;
import android.database.Cursor;
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java
index 17539fe72..00f85bdd0 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java
@@ -26,7 +26,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
-import org.sufficientlysecure.keychain.ui.widget.SelectKeyCursorAdapter;
+import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter;
import android.database.Cursor;
import android.net.Uri;
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
new file mode 100644
index 000000000..26416057c
--- /dev/null
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui.adapter;
+
+import java.util.List;
+
+import org.sufficientlysecure.keychain.R;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Color;
+import android.os.Build;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
+import android.widget.TextView;
+
+public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
+ protected LayoutInflater mInflater;
+ protected Activity mActivity;
+
+ protected List<ImportKeysListEntry> data;
+
+ public ImportKeysAdapter(Activity activity) {
+ super(activity, -1);
+ mActivity = activity;
+ mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ @SuppressLint("NewApi")
+ public void setData(List<ImportKeysListEntry> data) {
+ clear();
+ if (data != null) {
+ if (Build.VERSION.SDK_INT >= 11) {
+ addAll(data);
+ } else {
+ for (ImportKeysListEntry entry : data) {
+ add(entry);
+ }
+ }
+ this.data = data;
+ }
+ }
+
+ public List<ImportKeysListEntry> getData() {
+ return data;
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ImportKeysListEntry entry = data.get(position);
+
+ View view = mInflater.inflate(R.layout.import_keys_list_entry, null);
+
+ TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId);
+ mainUserId.setText(R.string.unknownUserId);
+ TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
+ mainUserIdRest.setText("");
+ TextView keyId = (TextView) view.findViewById(R.id.keyId);
+ keyId.setText(R.string.noKey);
+ TextView fingerprint = (TextView) view.findViewById(R.id.fingerprint);
+ TextView algorithm = (TextView) view.findViewById(R.id.algorithm);
+ algorithm.setText("");
+ TextView status = (TextView) view.findViewById(R.id.status);
+ status.setText("");
+
+ String userId = entry.userIds.get(0);
+ if (userId != null) {
+ String chunks[] = userId.split(" <", 2);
+ userId = chunks[0];
+ if (chunks.length > 1) {
+ mainUserIdRest.setText("<" + chunks[1]);
+ }
+ if (entry.secretKey) {
+ userId = mActivity.getString(R.string.secretKey) + " " + userId;
+ mainUserId.setTextColor(Color.RED);
+ }
+ mainUserId.setText(userId);
+ }
+
+ keyId.setText(entry.hexKeyId);
+ fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint);
+
+ if (mainUserIdRest.getText().length() == 0) {
+ mainUserIdRest.setVisibility(View.GONE);
+ }
+
+ algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm);
+
+ if (entry.revoked) {
+ status.setText("revoked");
+ } else {
+ status.setVisibility(View.GONE);
+ }
+
+ LinearLayout ll = (LinearLayout) view.findViewById(R.id.list);
+ if (entry.userIds.size() == 1) {
+ ll.setVisibility(View.GONE);
+ } else {
+ boolean first = true;
+ boolean second = true;
+ for (String uid : entry.userIds) {
+ if (first) {
+ first = false;
+ continue;
+ }
+ if (!second) {
+ View sep = new View(mActivity);
+ sep.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 1));
+ sep.setBackgroundResource(android.R.drawable.divider_horizontal_dark);
+ ll.addView(sep);
+ }
+ TextView uidView = (TextView) mInflater.inflate(
+ R.layout.import_keys_list_entry_user_id, null);
+ uidView.setText(uid);
+ ll.addView(uidView);
+ second = false;
+ }
+ }
+
+ CheckBox cBox = (CheckBox) view.findViewById(R.id.selected);
+ cBox.setChecked(entry.isSelected());
+
+ return view;
+ }
+
+}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
new file mode 100644
index 000000000..1a100a585
--- /dev/null
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui.adapter;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import org.spongycastle.openpgp.PGPKeyRing;
+import org.spongycastle.openpgp.PGPPublicKey;
+import org.spongycastle.openpgp.PGPSecretKeyRing;
+import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
+import org.sufficientlysecure.keychain.util.AlgorithmNames;
+import org.sufficientlysecure.keychain.util.IterableIterator;
+
+public class ImportKeysListEntry implements Serializable {
+ private static final long serialVersionUID = -7797972103284992662L;
+ public ArrayList<String> userIds;
+ public long keyId;
+
+ public boolean revoked;
+ // public Date date;
+ public String fingerPrint;
+ public String hexKeyId;
+ public int bitStrength;
+ public String algorithm;
+ public boolean secretKey;
+ AlgorithmNames algorithmNames;
+
+ private boolean selected;
+
+ /**
+ * Constructor for later querying from keyserver
+ */
+ public ImportKeysListEntry() {
+ secretKey = false;
+ userIds = new ArrayList<String>();
+ }
+
+ public boolean isSelected() {
+ return selected;
+ }
+
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ /**
+ * Constructor based on key object, used for import from NFC, QR Codes, files
+ *
+ * @param pgpKey
+ */
+ @SuppressWarnings("unchecked")
+ public ImportKeysListEntry(PGPKeyRing pgpKeyRing) {
+ // selected is default
+ this.selected = true;
+
+ if (pgpKeyRing instanceof PGPSecretKeyRing) {
+ secretKey = true;
+ } else {
+ secretKey = false;
+ }
+
+ userIds = new ArrayList<String>();
+ for (String userId : new IterableIterator<String>(pgpKeyRing.getPublicKey().getUserIDs())) {
+ userIds.add(userId);
+ }
+ this.keyId = pgpKeyRing.getPublicKey().getKeyID();
+
+ this.revoked = pgpKeyRing.getPublicKey().isRevoked();
+ this.fingerPrint = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey()
+ .getFingerprint());
+ this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId);
+ this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength();
+ int algorithm = pgpKeyRing.getPublicKey().getAlgorithm();
+ if (algorithm == PGPPublicKey.RSA_ENCRYPT || algorithm == PGPPublicKey.RSA_GENERAL
+ || algorithm == PGPPublicKey.RSA_SIGN) {
+ this.algorithm = "RSA";
+ } else if (algorithm == PGPPublicKey.DSA) {
+ this.algorithm = "DSA";
+ } else if (algorithm == PGPPublicKey.ELGAMAL_ENCRYPT
+ || algorithm == PGPPublicKey.ELGAMAL_GENERAL) {
+ this.algorithm = "ElGamal";
+ } else if (algorithm == PGPPublicKey.EC || algorithm == PGPPublicKey.ECDSA) {
+ this.algorithm = "ECC";
+ } else {
+ // TODO: with resources
+ this.algorithm = "unknown";
+ }
+ }
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/ImportKeysListLoader.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
index b10e5fd26..2e5239a93 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/ImportKeysListLoader.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package org.sufficientlysecure.keychain.ui.widget;
+package org.sufficientlysecure.keychain.ui.adapter;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
@@ -23,32 +23,23 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPObjectFactory;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPUtil;
import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
-import org.sufficientlysecure.keychain.R;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
-public class ImportKeysListLoader extends AsyncTaskLoader<List<Map<String, String>>> {
- public static final String MAP_ATTR_USER_ID = "user_id";
- public static final String MAP_ATTR_FINGERPINT = "fingerprint";
-
- ArrayList<Map<String, String>> data = new ArrayList<Map<String, String>>();
-
+public class ImportKeysListLoader extends AsyncTaskLoader<List<ImportKeysListEntry>> {
Context mContext;
- List<String> mItems;
+
+ ArrayList<ImportKeysListEntry> data = new ArrayList<ImportKeysListEntry>();
byte[] mKeyringBytes;
String mImportFilename;
@@ -61,7 +52,7 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<Map<String, Strin
}
@Override
- public List<Map<String, String>> loadInBackground() {
+ public List<ImportKeysListEntry> loadInBackground() {
InputData inputData = null;
if (mKeyringBytes != null) {
inputData = new InputData(new ByteArrayInputStream(mKeyringBytes), mKeyringBytes.length);
@@ -76,7 +67,8 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<Map<String, Strin
return data;
}
- generateListOfKeyrings(inputData);
+ if (inputData != null)
+ generateListOfKeyrings(inputData);
return data;
}
@@ -100,12 +92,12 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<Map<String, Strin
}
@Override
- public void deliverResult(List<Map<String, String>> data) {
+ public void deliverResult(List<ImportKeysListEntry> data) {
super.deliverResult(data);
}
/**
- * Similar to PGPMain.importKeyRings
+ * Reads all PGPKeyRing objects from input
*
* @param keyringBytes
* @return
@@ -144,20 +136,8 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<Map<String, Strin
}
private void addToData(PGPKeyRing keyring) {
- String userId = PgpKeyHelper.getMainUserId(keyring.getPublicKey());
-
- if (keyring instanceof PGPSecretKeyRing) {
- userId = mContext.getString(R.string.secretKeyring) + " " + userId;
- }
-
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(keyring.getPublicKey()
- .getFingerprint());
-
- Map<String, String> attrs = new HashMap<String, String>();
- attrs.put(MAP_ATTR_USER_ID, userId);
- attrs.put(MAP_ATTR_FINGERPINT, mContext.getString(R.string.fingerprint) + "\n"
- + fingerprint);
- data.add(attrs);
+ ImportKeysListEntry item = new ImportKeysListEntry(keyring);
+ data.add(item);
}
}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java
index b50ec5f0d..802453f63 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java
@@ -79,7 +79,7 @@ public class LookupUnknownKeyDialogFragment extends DialogFragment {
alert.setIcon(android.R.drawable.ic_dialog_alert);
alert.setTitle(R.string.title_unknownSignatureKey);
alert.setMessage(getString(R.string.lookupUnknownKey,
- PgpKeyHelper.getSmallFingerPrint(unknownKeyId)));
+ PgpKeyHelper.convertKeyIdToHex(unknownKeyId)));
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
index 27e5a7cc6..53a1bc38f 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
@@ -152,8 +152,8 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
}
mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(key));
- String keyId1Str = PgpKeyHelper.getSmallFingerPrint(key.getKeyID());
- String keyId2Str = PgpKeyHelper.getSmallFingerPrint(key.getKeyID() >> 32);
+ String keyId1Str = PgpKeyHelper.convertKeyIdToHex(key.getKeyID());
+ String keyId2Str = PgpKeyHelper.convertKeyIdToHex(key.getKeyID() >> 32);
mKeyId.setText(keyId1Str + " " + keyId2Str);
Vector<Choice> choices = new Vector<Choice>();
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/KeyListAdapter.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/KeyListAdapter.java
deleted file mode 100644
index 780520cb1..000000000
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/KeyListAdapter.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.helper.OtherHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.R;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.MergeCursor;
-import android.net.Uri;
-import android.provider.BaseColumns;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CursorTreeAdapter;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-public class KeyListAdapter extends CursorTreeAdapter {
- private Context mContext;
- private LayoutInflater mInflater;
-
- protected int mKeyType;
-
- private static final int CHILD_KEY = 0;
- private static final int CHILD_USER_ID = 1;
- private static final int CHILD_FINGERPRINT = 2;
-
- public KeyListAdapter(Context context, Cursor groupCursor, int keyType) {
- super(groupCursor, context);
- mContext = context;
- mInflater = LayoutInflater.from(context);
- mKeyType = keyType;
- }
-
- /**
- * Inflate new view for group items
- */
- @Override
- public View newGroupView(Context context, Cursor cursor, boolean isExpanded, ViewGroup parent) {
- return mInflater.inflate(R.layout.key_list_group_item, null);
- }
-
- /**
- * Binds TextViews from group view to results from database group cursor.
- */
- @Override
- protected void bindGroupView(View view, Context context, Cursor cursor, boolean isExpanded) {
- int userIdIndex = cursor.getColumnIndex(UserIds.USER_ID);
-
- TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId);
- mainUserId.setText(R.string.unknownUserId);
- TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
- mainUserIdRest.setText("");
-
- String userId = cursor.getString(userIdIndex);
- if (userId != null) {
- String[] userIdSplit = OtherHelper.splitUserId(userId);
-
- if (userIdSplit[1] != null) {
- mainUserIdRest.setText(userIdSplit[1]);
- }
- mainUserId.setText(userIdSplit[0]);
- }
-
- if (mainUserId.getText().length() == 0) {
- mainUserId.setText(R.string.unknownUserId);
- }
-
- if (mainUserIdRest.getText().length() == 0) {
- mainUserIdRest.setVisibility(View.GONE);
- } else {
- mainUserIdRest.setVisibility(View.VISIBLE);
- }
- }
-
- /**
- * Inflate new view for child items
- */
- @Override
- public View newChildView(Context context, Cursor cursor, boolean isLastChild, ViewGroup parent) {
- return mInflater.inflate(R.layout.key_list_child_item, null);
- }
-
- /**
- * Bind TextViews from view of childs based on query results
- */
- @Override
- protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) {
- LinearLayout keyLayout = (LinearLayout) view.findViewById(R.id.keyLayout);
- LinearLayout userIdLayout = (LinearLayout) view.findViewById(R.id.userIdLayout);
-
- // first entry is fingerprint
- if (cursor.getPosition() == 0) {
- // show only userId layout
- keyLayout.setVisibility(View.GONE);
- userIdLayout.setVisibility(View.VISIBLE);
-
- String fingerprint = PgpKeyHelper.getFingerPrint(context,
- cursor.getLong(cursor.getColumnIndex(Keys.KEY_ID)));
- fingerprint = fingerprint.replace(" ", "\n");
-
- TextView userId = (TextView) view.findViewById(R.id.userId);
- if (userId == null) {
- Log.d(Constants.TAG, "userId is null!");
- }
- userId.setText(context.getString(R.string.fingerprint) + "\n" + fingerprint);
- } else {
- // differentiate between keys and userIds in MergeCursor
- if (cursor.getColumnIndex(Keys.KEY_ID) != -1) {
- keyLayout.setVisibility(View.VISIBLE);
- userIdLayout.setVisibility(View.GONE);
-
- String keyIdStr = PgpKeyHelper.getSmallFingerPrint(cursor.getLong(cursor
- .getColumnIndex(Keys.KEY_ID)));
- String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
- cursor.getInt(cursor.getColumnIndex(Keys.ALGORITHM)),
- cursor.getInt(cursor.getColumnIndex(Keys.KEY_SIZE)));
-
- TextView keyId = (TextView) view.findViewById(R.id.keyId);
- keyId.setText(keyIdStr);
-
- TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails);
- keyDetails.setText("(" + algorithmStr + ")");
-
- ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey);
- if (cursor.getInt(cursor.getColumnIndex(Keys.IS_MASTER_KEY)) != 1) {
- masterKeyIcon.setVisibility(View.INVISIBLE);
- } else {
- masterKeyIcon.setVisibility(View.VISIBLE);
- }
-
- ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey);
- if (cursor.getInt(cursor.getColumnIndex(Keys.CAN_CERTIFY)) != 1) {
- certifyIcon.setVisibility(View.GONE);
- } else {
- certifyIcon.setVisibility(View.VISIBLE);
- }
-
- ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
- if (cursor.getInt(cursor.getColumnIndex(Keys.CAN_ENCRYPT)) != 1) {
- encryptIcon.setVisibility(View.GONE);
- } else {
- encryptIcon.setVisibility(View.VISIBLE);
- }
-
- ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey);
- if (cursor.getInt(cursor.getColumnIndex(Keys.CAN_SIGN)) != 1) {
- signIcon.setVisibility(View.GONE);
- } else {
- signIcon.setVisibility(View.VISIBLE);
- }
- } else {
- keyLayout.setVisibility(View.GONE);
- userIdLayout.setVisibility(View.VISIBLE);
-
- String userIdStr = cursor.getString(cursor.getColumnIndex(UserIds.USER_ID));
-
- TextView userId = (TextView) view.findViewById(R.id.userId);
- userId.setText(userIdStr);
- }
- }
- }
-
- /**
- * Given the group cursor, we start cursors for a fingerprint, keys, and userIds, which are
- * merged together and build the child cursor
- */
- @Override
- protected Cursor getChildrenCursor(Cursor groupCursor) {
- final long keyRingRowId = groupCursor.getLong(groupCursor.getColumnIndex(BaseColumns._ID));
-
- Cursor fingerprintCursor = getChildCursor(keyRingRowId, CHILD_FINGERPRINT);
- Cursor keyCursor = getChildCursor(keyRingRowId, CHILD_KEY);
- Cursor userIdCursor = getChildCursor(keyRingRowId, CHILD_USER_ID);
-
- MergeCursor mergeCursor = new MergeCursor(new Cursor[] { fingerprintCursor, keyCursor,
- userIdCursor });
- Log.d(Constants.TAG, "mergeCursor:" + DatabaseUtils.dumpCursorToString(mergeCursor));
-
- return mergeCursor;
- }
-
- /**
- * This builds a cursor for a specific type of children
- *
- * @param keyRingRowId
- * foreign row id of the keyRing
- * @param type
- * @return
- */
- private Cursor getChildCursor(long keyRingRowId, int type) {
- Uri uri = null;
- String[] projection = null;
- String sortOrder = null;
- String selection = null;
-
- switch (type) {
- case CHILD_FINGERPRINT:
- projection = new String[] { Keys._ID, Keys.KEY_ID, Keys.IS_MASTER_KEY, Keys.ALGORITHM,
- Keys.KEY_SIZE, Keys.CAN_CERTIFY, Keys.CAN_SIGN, Keys.CAN_ENCRYPT, };
- sortOrder = Keys.RANK + " ASC";
-
- // use only master key for fingerprint
- selection = Keys.IS_MASTER_KEY + " = 1 ";
-
- if (mKeyType == Id.type.public_key) {
- uri = Keys.buildPublicKeysUri(String.valueOf(keyRingRowId));
- } else {
- uri = Keys.buildSecretKeysUri(String.valueOf(keyRingRowId));
- }
- break;
-
- case CHILD_KEY:
- projection = new String[] { Keys._ID, Keys.KEY_ID, Keys.IS_MASTER_KEY, Keys.ALGORITHM,
- Keys.KEY_SIZE, Keys.CAN_CERTIFY, Keys.CAN_SIGN, Keys.CAN_ENCRYPT, };
- sortOrder = Keys.RANK + " ASC";
-
- if (mKeyType == Id.type.public_key) {
- uri = Keys.buildPublicKeysUri(String.valueOf(keyRingRowId));
- } else {
- uri = Keys.buildSecretKeysUri(String.valueOf(keyRingRowId));
- }
-
- break;
-
- case CHILD_USER_ID:
- projection = new String[] { UserIds._ID, UserIds.USER_ID, UserIds.RANK, };
- sortOrder = UserIds.RANK + " ASC";
-
- // not the main user id
- selection = UserIds.RANK + " > 0 ";
-
- if (mKeyType == Id.type.public_key) {
- uri = UserIds.buildPublicUserIdsUri(String.valueOf(keyRingRowId));
- } else {
- uri = UserIds.buildSecretUserIdsUri(String.valueOf(keyRingRowId));
- }
-
- break;
-
- default:
- return null;
-
- }
-
- return mContext.getContentResolver().query(uri, projection, selection, null, sortOrder);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/SelectKeyCursorAdapter.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/SelectKeyCursorAdapter.java
deleted file mode 100644
index 0b2b612a5..000000000
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/SelectKeyCursorAdapter.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.helper.OtherHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
-import org.sufficientlysecure.keychain.R;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.support.v4.widget.CursorAdapter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.ListView;
-import android.widget.TextView;
-
-public class SelectKeyCursorAdapter extends CursorAdapter {
-
- protected int mKeyType;
-
- private LayoutInflater mInflater;
- private ListView mListView;
-
- public final static String PROJECTION_ROW_AVAILABLE = "available";
- public final static String PROJECTION_ROW_VALID = "valid";
-
- public SelectKeyCursorAdapter(Context context, Cursor c, int flags, ListView listView,
- int keyType) {
- super(context, c, flags);
-
- mInflater = LayoutInflater.from(context);
- mListView = listView;
- mKeyType = keyType;
- }
-
- public String getUserId(int position) {
- mCursor.moveToPosition(position);
- return mCursor.getString(mCursor.getColumnIndex(UserIds.USER_ID));
- }
-
- public long getMasterKeyId(int position) {
- mCursor.moveToPosition(position);
- return mCursor.getLong(mCursor.getColumnIndex(KeyRings.MASTER_KEY_ID));
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- boolean valid = cursor.getInt(cursor.getColumnIndex(PROJECTION_ROW_VALID)) > 0;
-
- TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId);
- mainUserId.setText(R.string.unknownUserId);
- TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
- mainUserIdRest.setText("");
- TextView keyId = (TextView) view.findViewById(R.id.keyId);
- keyId.setText(R.string.noKey);
- TextView status = (TextView) view.findViewById(R.id.status);
- status.setText(R.string.unknownStatus);
-
- String userId = cursor.getString(cursor.getColumnIndex(UserIds.USER_ID));
- if (userId != null) {
- String[] userIdSplit = OtherHelper.splitUserId(userId);
-
- if (userIdSplit[1] != null) {
- mainUserIdRest.setText(userIdSplit[1]);
- }
- mainUserId.setText(userIdSplit[0]);
- }
-
- long masterKeyId = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID));
- keyId.setText(PgpKeyHelper.getSmallFingerPrint(masterKeyId));
-
- if (mainUserIdRest.getText().length() == 0) {
- mainUserIdRest.setVisibility(View.GONE);
- }
-
- if (valid) {
- if (mKeyType == Id.type.public_key) {
- status.setText(R.string.canEncrypt);
- } else {
- status.setText(R.string.canSign);
- }
- } else {
- if (cursor.getInt(cursor.getColumnIndex(PROJECTION_ROW_AVAILABLE)) > 0) {
- // has some CAN_ENCRYPT keys, but col(ROW_VALID) = 0, so must be revoked or
- // expired
- status.setText(R.string.expired);
- } else {
- status.setText(R.string.noKey);
- }
- }
-
- CheckBox selected = (CheckBox) view.findViewById(R.id.selected);
- if (mKeyType == Id.type.public_key) {
- selected.setVisibility(View.VISIBLE);
-
- if (!valid) {
- mListView.setItemChecked(cursor.getPosition(), false);
- }
-
- selected.setChecked(mListView.isItemChecked(cursor.getPosition()));
- selected.setEnabled(valid);
- } else {
- selected.setVisibility(View.GONE);
- }
-
- status.setText(status.getText() + " ");
-
- view.setEnabled(valid);
- mainUserId.setEnabled(valid);
- mainUserIdRest.setEnabled(valid);
- keyId.setEnabled(valid);
- status.setEnabled(valid);
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.select_key_item, null);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/AlgorithmNames.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/AlgorithmNames.java
new file mode 100644
index 000000000..8ccc63ae7
--- /dev/null
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/AlgorithmNames.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.util;
+
+import java.util.HashMap;
+import org.spongycastle.bcpg.HashAlgorithmTags;
+import org.spongycastle.openpgp.PGPEncryptedData;
+import org.sufficientlysecure.keychain.Id;
+import org.sufficientlysecure.keychain.R;
+import android.annotation.SuppressLint;
+import android.app.Activity;
+
+@SuppressLint("UseSparseArrays")
+public class AlgorithmNames {
+ Activity mActivity;
+
+ HashMap<Integer, String> mEncryptionNames = new HashMap<Integer, String>();
+ HashMap<Integer, String> mHashNames = new HashMap<Integer, String>();
+ HashMap<Integer, String> mCompressionNames = new HashMap<Integer, String>();
+
+ public AlgorithmNames(Activity context) {
+ super();
+ this.mActivity = context;
+
+ mEncryptionNames.put(PGPEncryptedData.AES_128, "AES-128");
+ mEncryptionNames.put(PGPEncryptedData.AES_192, "AES-192");
+ mEncryptionNames.put(PGPEncryptedData.AES_256, "AES-256");
+ mEncryptionNames.put(PGPEncryptedData.BLOWFISH, "Blowfish");
+ mEncryptionNames.put(PGPEncryptedData.TWOFISH, "Twofish");
+ mEncryptionNames.put(PGPEncryptedData.CAST5, "CAST5");
+ mEncryptionNames.put(PGPEncryptedData.DES, "DES");
+ mEncryptionNames.put(PGPEncryptedData.TRIPLE_DES, "Triple DES");
+ mEncryptionNames.put(PGPEncryptedData.IDEA, "IDEA");
+
+ mHashNames.put(HashAlgorithmTags.MD5, "MD5");
+ mHashNames.put(HashAlgorithmTags.RIPEMD160, "RIPEMD-160");
+ mHashNames.put(HashAlgorithmTags.SHA1, "SHA-1");
+ mHashNames.put(HashAlgorithmTags.SHA224, "SHA-224");
+ mHashNames.put(HashAlgorithmTags.SHA256, "SHA-256");
+ mHashNames.put(HashAlgorithmTags.SHA384, "SHA-384");
+ mHashNames.put(HashAlgorithmTags.SHA512, "SHA-512");
+
+ mCompressionNames.put(Id.choice.compression.none, mActivity.getString(R.string.choice_none)
+ + " (" + mActivity.getString(R.string.fast) + ")");
+ mCompressionNames.put(Id.choice.compression.zip,
+ "ZIP (" + mActivity.getString(R.string.fast) + ")");
+ mCompressionNames.put(Id.choice.compression.zlib,
+ "ZLIB (" + mActivity.getString(R.string.fast) + ")");
+ mCompressionNames.put(Id.choice.compression.bzip2,
+ "BZIP2 (" + mActivity.getString(R.string.very_slow) + ")");
+ }
+
+ public HashMap<Integer, String> getEncryptionNames() {
+ return mEncryptionNames;
+ }
+
+ public void setEncryptionNames(HashMap<Integer, String> encryptionNames) {
+ this.mEncryptionNames = encryptionNames;
+ }
+
+ public HashMap<Integer, String> getHashNames() {
+ return mHashNames;
+ }
+
+ public void setHashNames(HashMap<Integer, String> hashNames) {
+ this.mHashNames = hashNames;
+ }
+
+ public HashMap<Integer, String> getCompressionNames() {
+ return mCompressionNames;
+ }
+
+ public void setCompressionNames(HashMap<Integer, String> compressionNames) {
+ this.mCompressionNames = compressionNames;
+ }
+
+}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/HkpKeyServer.java
index ff69aa264..8b5e94858 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/HkpKeyServer.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/HkpKeyServer.java
@@ -179,8 +179,8 @@ public class HkpKeyServer extends KeyServer {
KeyInfo info = new KeyInfo();
info.size = Integer.parseInt(matcher.group(1));
info.algorithm = matcher.group(2);
- info.keyId = PgpKeyHelper.keyFromHex(matcher.group(3));
- info.fingerPrint = PgpKeyHelper.getSmallFingerPrint(info.keyId);
+ info.keyId = PgpKeyHelper.convertHexToKeyId(matcher.group(3));
+ info.fingerPrint = PgpKeyHelper.convertKeyIdToHex(info.keyId);
String chunks[] = matcher.group(4).split("-");
info.date = new GregorianCalendar(Integer.parseInt(chunks[0]),
Integer.parseInt(chunks[1]), Integer.parseInt(chunks[2])).getTime();
@@ -211,7 +211,7 @@ public class HkpKeyServer extends KeyServer {
HttpClient client = new DefaultHttpClient();
try {
HttpGet get = new HttpGet("http://" + mHost + ":" + mPort
- + "/pks/lookup?op=get&search=0x" + PgpKeyHelper.keyToHex(keyId));
+ + "/pks/lookup?op=get&search=0x" + PgpKeyHelper.convertKeyToHex(keyId));
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
@@ -235,13 +235,13 @@ public class HkpKeyServer extends KeyServer {
}
@Override
- public void add(String armouredText) throws AddKeyException {
+ public void add(String armoredText) throws AddKeyException {
HttpClient client = new DefaultHttpClient();
try {
HttpPost post = new HttpPost("http://" + mHost + ":" + mPort + "/pks/add");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
- nameValuePairs.add(new BasicNameValuePair("keytext", armouredText));
+ nameValuePairs.add(new BasicNameValuePair("keytext", armoredText));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/KeyValueSpinnerAdapter.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/KeyValueSpinnerAdapter.java
deleted file mode 100644
index e8905062c..000000000
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/KeyValueSpinnerAdapter.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import android.content.Context;
-import android.widget.ArrayAdapter;
-
-public class KeyValueSpinnerAdapter extends ArrayAdapter<String> {
- private final HashMap<Integer, String> mData;
- private final int[] mKeys;
- private final String[] mValues;
-
- static <K, V extends Comparable<? super V>> SortedSet<Map.Entry<K, V>> entriesSortedByValues(
- Map<K, V> map) {
- SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<Map.Entry<K, V>>(
- new Comparator<Map.Entry<K, V>>() {
- @Override
- public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) {
- return e1.getValue().compareTo(e2.getValue());
- }
- });
- sortedEntries.addAll(map.entrySet());
- return sortedEntries;
- }
-
- public KeyValueSpinnerAdapter(Context context, HashMap<Integer, String> objects) {
- // To make the drop down a simple text box
- super(context, android.R.layout.simple_spinner_item);
- mData = objects;
-
- // To make the drop down view a radio button list
- setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-
- SortedSet<Map.Entry<Integer, String>> sorted = entriesSortedByValues(objects);
-
- // Assign hash keys with a position so that we can present and retrieve them
- int i = 0;
- mKeys = new int[mData.size()];
- mValues = new String[mData.size()];
- for (Map.Entry<Integer, String> entry : sorted) {
- mKeys[i] = entry.getKey();
- mValues[i] = entry.getValue();
- i++;
- }
- }
-
- public int getCount() {
- return mData.size();
- }
-
- /**
- * Returns the value
- */
- @Override
- public String getItem(int position) {
- // return the value based on the position. This is displayed in the list.
- return mValues[position];
- }
-
- /**
- * Returns item key
- */
- public long getItemId(int position) {
- // Return an id to represent the item.
-
- return mKeys[position];
- }
-
- /**
- * Find position from key
- */
- public int getPosition(long itemId) {
- for (int i = 0; i < mKeys.length; i++) {
- if ((int) itemId == mKeys[i]) {
- return i;
- }
- }
- return -1;
- }
-} \ No newline at end of file