Merge branch 'development' into linked-identities

Conflicts:
	OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
	OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java
This commit is contained in:
Vincent Breitmoser 2015-03-05 12:10:51 +01:00
commit 7b3bc4ca98
598 changed files with 1240 additions and 1508 deletions

4
.gitmodules vendored
View File

@ -19,9 +19,11 @@
[submodule "extern/minidns"]
path = extern/minidns
url = https://github.com/open-keychain/minidns.git
ignore = dirty
[submodule "extern/TokenAutoComplete"]
path = extern/TokenAutoComplete
url = https://github.com/open-keychain/TokenAutoComplete
[submodule "extern/safeslinger-exchange"]
path = extern/safeslinger-exchange
url = https://github.com/open-keychain/exchange-android
url = https://github.com/open-keychain/exchange-android
ignore = dirty

View File

@ -17,14 +17,9 @@ file_filter = OpenKeychain/src/main/res/raw-<lang>/help_changelog.html
source_file = OpenKeychain/src/main/res/raw/help_changelog.html
source_lang = en
[open-keychain.help-wot]
file_filter = OpenKeychain/src/main/res/raw-<lang>/help_wot.html
source_file = OpenKeychain/src/main/res/raw/help_wot.html
source_lang = en
[open-keychain.help-nfc-beam]
file_filter = OpenKeychain/src/main/res/raw-<lang>/help_nfc_beam.html
source_file = OpenKeychain/src/main/res/raw/help_nfc_beam.html
[open-keychain.help-certification]
file_filter = OpenKeychain/src/main/res/raw-<lang>/help_certification.html
source_file = OpenKeychain/src/main/res/raw/help_certification.html
source_lang = en
[open-keychain.help-start]
@ -32,7 +27,3 @@ file_filter = OpenKeychain/src/main/res/raw-<lang>/help_start.html
source_file = OpenKeychain/src/main/res/raw/help_start.html
source_lang = en
[open-keychain.nfc-beam-share]
file_filter = OpenKeychain/src/main/res/raw-<lang>/nfc_beam_share.html
source_file = OpenKeychain/src/main/res/raw/nfc_beam_share.html
source_lang = en

View File

@ -73,6 +73,9 @@ Mapping vars:
Options file
============
*In this project, if you need to fetch new icons, rename options.templ.json to options.json. And then run script get-material-icons.sh*
Named `options.json` in same dir. Sample:
```json
{

View File

@ -1,5 +1,5 @@
{
"basePath": "~/Documents",
"basePath": "../../",
"filenameMap": {
"classic": "ic_action_{name}{bgSuffix}.png",
"fa": "ic_action_fa_{name}{bgSuffix}.png",

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 651 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 938 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 908 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 938 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 908 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,8 @@
<!-- drawable/key-plus.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M6.5,3C8.46,3 10.13,4.25 10.74,6H22V9H18V12H15V9H10.74C10.13,10.75 8.46,12 6.5,12C4,12 2,10 2,7.5C2,5 4,3 6.5,3M6.5,6A1.5,1.5 0 0,0 5,7.5A1.5,1.5 0 0,0 6.5,9A1.5,1.5 0 0,0 8,7.5A1.5,1.5 0 0,0 6.5,6M8,17H11V14H13V17H16V19H13V22H11V19H8V17Z" />
</vector>

View File

@ -0,0 +1,5 @@
Thanks for visiting MaterialDesignIcons.com
Check back often for new icons and follow @MaterialIcons for updates.
Icon: key-plus
By: Austin Andrews

View File

@ -10,6 +10,31 @@ python copy OpenKeychain navigation white refresh 24
python copy OpenKeychain av white repeat 24
python copy OpenKeychain av grey repeat 24
python copy OpenKeychain editor white mode_edit 24
python copy OpenKeychain content white save 24
python copy OpenKeychain action grey delete 24
python copy OpenKeychain action grey done 24
python copy OpenKeychain action grey search 24
python copy OpenKeychain action grey settings 24
python copy OpenKeychain action grey view_list 24
python copy OpenKeychain action grey lock 24
python copy OpenKeychain action grey lock_open 24
python copy OpenKeychain alert grey warning 24
python copy OpenKeychain av grey play_arrow 24
python copy OpenKeychain communication grey import_export 24
python copy OpenKeychain content grey content_copy 24
python copy OpenKeychain content grey content_paste 24
python copy OpenKeychain content grey save 24
python copy OpenKeychain content grey select_all 24
python copy OpenKeychain editor grey mode_edit 24
python copy OpenKeychain file grey cloud 24
python copy OpenKeychain file grey folder 24
python copy OpenKeychain file grey file_download 24
python copy OpenKeychain file grey file_upload 24
python copy OpenKeychain navigation grey close 24
python copy OpenKeychain social grey person 24
python copy OpenKeychain social grey person_add 24
python copy OpenKeychain social grey share 24
# navigation drawer sections
python copy OpenKeychain communication black vpn_key 24
@ -25,4 +50,4 @@ python copy OpenKeychain av white play_arrow 24
python copy OpenKeychain file white folder 24
# multi select
python copy OpenKeychain action white lock 24
python copy OpenKeychain action white lock 24

View File

@ -10,17 +10,6 @@ XXXDPI_DIR=$APP_DIR/res/drawable-xxxhdpi
PLAY_DIR=./drawables/
SRC_DIR=./drawables/
# Launcher Icon:
# -----------------------
# mdpi: 48x48
# hdpi: 72x72
# xhdpi: 96x96
# xxhdpi: 144x144.
# xxxhdpi 192x192.
# google play: 512x512
# Adobe Illustrator (.ai) exports by Tha Phlash are way better than the Inkscape exports (.svg)
#NAME="ic_launcher"
@ -32,38 +21,24 @@ SRC_DIR=./drawables/
#inkscape -w 192 -h 192 -e "$XXXDPI_DIR/$NAME.png" $NAME.svg
#inkscape -w 512 -h 512 -e "$PLAY_DIR/$NAME.png" $NAME.svg
# Actionbar Icons
# -----------------------
# mdpi: 32x32
# hdpi: 48x48
# xhdpi: 64x64
# xxhdpi: 96x96
for NAME in "ic_action_search_cloud" "ic_cloud_search_24px" "ic_action_encrypt_file" "ic_action_encrypt_text" "ic_action_verified_cutout"
for NAME in "ic_cloud_search" "ic_action_encrypt_file" "ic_action_encrypt_text" "ic_action_verified_cutout" "status_lock_closed" "status_lock_error" "status_lock_open" "status_signature_expired_cutout" "status_signature_invalid_cutout" "status_signature_revoked_cutout" "status_signature_unknown_cutout" "status_signature_unverified_cutout" "status_signature_verified_cutout" "key_flag_authenticate" "key_flag_certify" "key_flag_encrypt" "key_flag_sign"
do
echo $NAME
inkscape -w 32 -h 32 -e "$MDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
inkscape -w 48 -h 48 -e "$HDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
inkscape -w 64 -h 64 -e "$XDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
inkscape -w 96 -h 96 -e "$XXDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
done
for NAME in "status_lock_closed" "status_lock_error" "status_lock_open" "status_signature_expired_cutout" "status_signature_invalid_cutout" "status_signature_revoked_cutout" "status_signature_unknown_cutout" "status_signature_unverified_cutout" "status_signature_verified_cutout" "key_flag_authenticate" "key_flag_certify" "key_flag_encrypt" "key_flag_sign"
do
echo $NAME
inkscape -w 24 -h 24 -e "$MDPI_DIR/${NAME}_24px.png" "$SRC_DIR/$NAME.svg"
inkscape -w 32 -h 32 -e "$HDPI_DIR/${NAME}_24px.png" "$SRC_DIR/$NAME.svg"
inkscape -w 48 -h 48 -e "$XDPI_DIR/${NAME}_24px.png" "$SRC_DIR/$NAME.svg"
inkscape -w 64 -h 64 -e "$XXDPI_DIR/${NAME}_24px.png" "$SRC_DIR/$NAME.svg"
inkscape -w 24 -h 24 -e "$MDPI_DIR/${NAME}_24dp.png" "$SRC_DIR/$NAME.svg"
inkscape -w 36 -h 36 -e "$HDPI_DIR/${NAME}_24dp.png" "$SRC_DIR/$NAME.svg"
inkscape -w 48 -h 48 -e "$XDPI_DIR/${NAME}_24dp.png" "$SRC_DIR/$NAME.svg"
inkscape -w 72 -h 72 -e "$XXDPI_DIR/${NAME}_24dp.png" "$SRC_DIR/$NAME.svg"
inkscape -w 96 -h 96 -e "$XXXDPI_DIR/${NAME}_24dp.png" "$SRC_DIR/$NAME.svg"
done
for NAME in "status_signature_expired_cutout" "status_signature_invalid_cutout" "status_signature_revoked_cutout" "status_signature_unknown_cutout" "status_signature_unverified_cutout" "status_signature_verified_cutout"
do
echo $NAME
inkscape -w 96 -h 96 -e "$MDPI_DIR/${NAME}_96px.png" "$SRC_DIR/$NAME.svg"
inkscape -w 128 -h 128 -e "$HDPI_DIR/${NAME}_96px.png" "$SRC_DIR/$NAME.svg"
inkscape -w 192 -h 192 -e "$XDPI_DIR/${NAME}_96px.png" "$SRC_DIR/$NAME.svg"
inkscape -w 256 -h 256 -e "$XXDPI_DIR/${NAME}_96px.png" "$SRC_DIR/$NAME.svg"
inkscape -w 96 -h 96 -e "$MDPI_DIR/${NAME}_96dp.png" "$SRC_DIR/$NAME.svg"
inkscape -w 128 -h 128 -e "$HDPI_DIR/${NAME}_96dp.png" "$SRC_DIR/$NAME.svg"
inkscape -w 192 -h 192 -e "$XDPI_DIR/${NAME}_96dp.png" "$SRC_DIR/$NAME.svg"
inkscape -w 256 -h 256 -e "$XXDPI_DIR/${NAME}_96dp.png" "$SRC_DIR/$NAME.svg"
done
for NAME in "create_key_robot"

View File

@ -3,11 +3,25 @@ apply plugin: 'witness'
dependencies {
// NOTE: Always use fixed version codes not dynamic ones, e.g. 0.7.3 instead of 0.7.+, see README for more information
// NOTE: libraries are pinned to a specific build, see below
// from local Android SDK
compile 'com.android.support:support-v4:21.0.3'
compile 'com.android.support:appcompat-v7:21.0.3'
compile 'com.android.support:recyclerview-v7:21.0.3'
compile 'com.android.support:cardview-v7:21.0.3'
// JCenter etc.
compile 'com.eftimoff:android-patternview:1.0.1@aar'
compile 'com.journeyapps:zxing-android-embedded:2.0.1@aar'
compile 'com.journeyapps:zxing-android-integration:2.0.1@aar'
compile 'com.google.zxing:core:3.0.1'
compile 'com.jpardogo.materialtabstrip:library:1.0.9'
compile 'it.neokree:MaterialNavigationDrawer:1.3.1'
compile 'com.nispok:snackbar:2.9.1'
compile 'com.getbase:floatingactionbutton:1.8.0'
// libs as submodules
compile project(':extern:openpgp-api-lib')
compile project(':extern:openkeychain-api-lib')
compile project(':extern:html-textview')
@ -20,16 +34,6 @@ dependencies {
compile project(':extern:KeybaseLib:Lib')
compile project(':extern:TokenAutoComplete:library')
compile project(':extern:safeslinger-exchange')
// NOTE: libraries are pinned to a specific build, see below
compile 'com.eftimoff:android-patternview:1.0.0@aar'
compile 'com.journeyapps:zxing-android-embedded:2.0.1@aar'
compile 'com.journeyapps:zxing-android-integration:2.0.1@aar'
compile 'com.google.zxing:core:3.0.1'
compile 'com.jpardogo.materialtabstrip:library:1.0.9'
compile 'it.neokree:MaterialNavigationDrawer:1.3.1'
compile 'com.nispok:snackbar:2.9.1'
compile 'com.getbase:floatingactionbutton:1.8.0'
}
// Output of ./gradlew -q calculateChecksums
@ -40,6 +44,16 @@ dependencyVerification {
'com.android.support:appcompat-v7:5dbeb5316d0a6027d646ae552804c3baa5e3bd53f7f33db50904d51505c8a0e5',
'com.android.support:recyclerview-v7:e525ad3f33c84bb12b73d2dc975b55364a53f0f2d0697e043efba59ba73e22d2',
'com.android.support:cardview-v7:45c48c2ab056bc7a8573970b10f8902742c5d443f180dae43c56557397ac39af',
'com.eftimoff:android-patternview:cec80e7265b8d8278b3c55b5fcdf551e4600ac2c8bf60d8dd76adca538af0b1e',
'com.journeyapps:zxing-android-embedded:5d6ba3931bd0b999695e363b571e95bd6bc9956340c1e6ce740cd0bff3d89a50',
'com.journeyapps:zxing-android-integration:6f50bb07c057ac94319777ddfbb66f5d4f6190393418b2fc861e0e60d06f3c0d',
'com.google.zxing:core:38c49045765281e4c170062fa3f48e4e988629bf985cab850c7497be5eaa72a1',
'com.jpardogo.materialtabstrip:library:c6ef812fba4f74be7dc4a905faa4c2908cba261a94c13d4f96d5e67e4aad4aaa',
'it.neokree:MaterialNavigationDrawer:1174d751a54689fccf53c1fbcdf439745926ae19024f4f1017afb6b29643c57d',
'com.nispok:snackbar:59dc092a44c877e9ce5f9040c632d99e62d8932b0a4d67ba0ec9e35467d9047c',
'com.getbase:floatingactionbutton:e63966148212e9685afad2370780ea239b6dbd2a06f6a3f919b98882318e6a32',
'com.android.support:support-annotations:fdee2354787ef66b268e75958de3f7f6c4f8f325510a6dac9f49c929f83a63de',
'com.balysv:material-ripple:587f19c1e27f16c7dc67ff9ac73838aa1451086ef05a15cee38bee3e4e1454ae',
//'OpenKeychain.extern:openpgp-api-lib:b17bb282321351e4b00b4cd6422a57aadc13decae264019a88707bcb556439ea',
//'OpenKeychain.extern:openkeychain-api-lib:5f95f01c066069d4bde68992fd8da5faac21510d009b1fdae7a2e28e43e82cf4',
//'OpenKeychain.extern:html-textview:b58e343cf4c145e91f888806d06a2a7770a9e9331a72f08cfcf1128db30dcff3',
@ -52,16 +66,6 @@ dependencyVerification {
//'OpenKeychain.extern.KeybaseLib:Lib:af9bff087148e0859430d0b99ece096c41b315c5dc1ed500a68580b9b0e5ab11',
//'OpenKeychain.extern.TokenAutoComplete:library:40d4212a95e947efdb02f2ca66c95a27d49fba848471a6317eca2b9cc18e8780',
//'OpenKeychain.extern:safeslinger-exchange:94a1ce68217af7499579a042758283b1530912c53241bdfa06d1a079a5ae3faf',
'com.eftimoff:android-patternview:a031eaed3b5cef8ea06c2d4a6e27693937f89ae483598d61b7027eeee0bed408',
'com.journeyapps:zxing-android-embedded:5d6ba3931bd0b999695e363b571e95bd6bc9956340c1e6ce740cd0bff3d89a50',
'com.journeyapps:zxing-android-integration:6f50bb07c057ac94319777ddfbb66f5d4f6190393418b2fc861e0e60d06f3c0d',
'com.google.zxing:core:38c49045765281e4c170062fa3f48e4e988629bf985cab850c7497be5eaa72a1',
'com.jpardogo.materialtabstrip:library:c6ef812fba4f74be7dc4a905faa4c2908cba261a94c13d4f96d5e67e4aad4aaa',
'it.neokree:MaterialNavigationDrawer:1174d751a54689fccf53c1fbcdf439745926ae19024f4f1017afb6b29643c57d',
'com.nispok:snackbar:59dc092a44c877e9ce5f9040c632d99e62d8932b0a4d67ba0ec9e35467d9047c',
'com.getbase:floatingactionbutton:e63966148212e9685afad2370780ea239b6dbd2a06f6a3f919b98882318e6a32',
'com.android.support:support-annotations:fdee2354787ef66b268e75958de3f7f6c4f8f325510a6dac9f49c929f83a63de',
'com.balysv:material-ripple:587f19c1e27f16c7dc67ff9ac73838aa1451086ef05a15cee38bee3e4e1454ae',
]
}

View File

@ -67,10 +67,8 @@
<uses-permission android:name="android.permission.READ_PROFILE" />
<!-- android:allowBackup="false": Don't allow backup over adb backup or other apps! -->
<!-- tools:replace="android:allowBackup" is a workaround for https://github.com/geftimov/android-patternview/pull/2 -->
<application
android:name=".KeychainApplication"
tools:replace="android:allowBackup"
android:allowBackup="false"
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher"

View File

@ -33,6 +33,7 @@ public final class Constants {
public static final String ACCOUNT_NAME = "OpenKeychain";
public static final String ACCOUNT_TYPE = PACKAGE_NAME + ".account";
public static final String CUSTOM_CONTACT_DATA_MIME_TYPE = "vnd.android.cursor.item/vnd.org.sufficientlysecure.keychain.key";
// as defined in http://tools.ietf.org/html/rfc3156, section 7
public static final String NFC_MIME = "application/pgp-keys";
@ -49,8 +50,6 @@ public final class Constants {
public static final String INTENT_PREFIX = PACKAGE_NAME + ".action.";
public static final String EXTRA_PREFIX = PACKAGE_NAME + ".";
public static final String CUSTOM_CONTACT_DATA_MIME_TYPE = "vnd.android.cursor.item/vnd.org.sufficientlysecure.keychain.key";
public static final int TEMPFILE_TTL = 24 * 60 * 60 * 1000; // 1 day
public static final String SAFESLINGER_SERVER = "safeslinger-openpgp.appspot.com";

View File

@ -140,20 +140,22 @@ public class KeychainApplication extends Application {
}
static void brandGlowEffect(Context context, int brandColor) {
try {
// terrible hack to brand the edge overscroll glow effect
// https://gist.github.com/menny/7878762#file-brandgloweffect_full-java
// no hack on Android 5
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
try {
// terrible hack to brand the edge overscroll glow effect
// https://gist.github.com/menny/7878762#file-brandgloweffect_full-java
//glow
int glowDrawableId = context.getResources().getIdentifier("overscroll_glow", "drawable", "android");
Drawable androidGlow = context.getResources().getDrawable(glowDrawableId);
androidGlow.setColorFilter(brandColor, PorterDuff.Mode.SRC_IN);
//edge
int edgeDrawableId = context.getResources().getIdentifier("overscroll_edge", "drawable", "android");
Drawable androidEdge = context.getResources().getDrawable(edgeDrawableId);
androidEdge.setColorFilter(brandColor, PorterDuff.Mode.SRC_IN);
} catch (Resources.NotFoundException e) {
// no hack on Android 5
//glow
int glowDrawableId = context.getResources().getIdentifier("overscroll_glow", "drawable", "android");
Drawable androidGlow = context.getResources().getDrawable(glowDrawableId);
androidGlow.setColorFilter(brandColor, PorterDuff.Mode.SRC_IN);
//edge
int edgeDrawableId = context.getResources().getIdentifier("overscroll_edge", "drawable", "android");
Drawable androidEdge = context.getResources().getDrawable(edgeDrawableId);
androidEdge.setColorFilter(brandColor, PorterDuff.Mode.SRC_IN);
} catch (Resources.NotFoundException e) {
}
}
}
}

View File

@ -38,6 +38,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/** Represent the result of an operation.
*
@ -51,6 +53,56 @@ import java.util.List;
public abstract class OperationResult implements Parcelable {
public static final String EXTRA_RESULT = "operation_result";
public static final UUID NULL_UUID = new UUID(0,0);
/**
* A HashMap of UUID:OperationLog which contains logs that we don't need
* to care about. This is used such that when we become parceled, we are
* well below the 1Mbit boundary that is specified.
*/
private static ConcurrentHashMap<UUID, OperationLog> dehydratedLogs;
static {
// Static initializer for ConcurrentHashMap
dehydratedLogs = new ConcurrentHashMap<UUID,OperationLog>();
}
/**
* Dehydrate a log (such that it is available after deparcelization)
*
* Returns the NULL uuid (0) if you hand it null.
* @param log An OperationLog to dehydrate
* @return a UUID, the ticket for your dehydrated log
*
*/
private static UUID dehydrateLog(OperationLog log) {
if(log == null) {
return NULL_UUID;
}
else {
UUID ticket = UUID.randomUUID();
dehydratedLogs.put(ticket, log);
return ticket;
}
}
/***
* Rehydrate a log after going through parcelization, invalidating its place in the
* dehydration pool.
* This is used such that when parcelized, the parcel is no larger than 1mbit.
* @param ticket A UUID ticket that identifies the log in question.
* @return An OperationLog.
*/
private static OperationLog rehydrateLog(UUID ticket) {
// UUID.equals isn't well documented; we use compareTo instead.
if( NULL_UUID.compareTo(ticket) == 0 ) {
return null;
}
else {
OperationLog log = dehydratedLogs.get(ticket);
dehydratedLogs.remove(ticket);
return log;
}
}
/** Holds the overall result, the number specifying varying degrees of success:
* - The first bit is 0 on overall success, 1 on overall failure
@ -65,7 +117,7 @@ public abstract class OperationResult implements Parcelable {
public static final int RESULT_WARNINGS = 4;
/// A list of log entries tied to the operation result.
final OperationLog mLog;
protected OperationLog mLog;
public OperationResult(int result, OperationLog log) {
mResult = result;
@ -74,8 +126,11 @@ public abstract class OperationResult implements Parcelable {
public OperationResult(Parcel source) {
mResult = source.readInt();
mLog = new OperationLog();
mLog.addAll(source.createTypedArrayList(LogEntryParcel.CREATOR));
long mostSig = source.readLong();
long leastSig = source.readLong();
UUID mTicket = new UUID(mostSig, leastSig);
// fetch the dehydrated log out of storage (this removes it from the dehydration pool)
mLog = rehydrateLog(mTicket);
}
public int getResult() {
@ -723,6 +778,12 @@ public abstract class OperationResult implements Parcelable {
MSG_LV_FETCH_ERROR_URL (LogLevel.ERROR, R.string.msg_lv_fetch_error_url),
MSG_LV_FETCH_ERROR_IO (LogLevel.ERROR, R.string.msg_lv_fetch_error_io),
//export log
MSG_EXPORT_LOG(LogLevel.START,R.string.msg_export_log_start),
MSG_EXPORT_LOG_EXPORT_ERROR_NO_FILE(LogLevel.ERROR,R.string.msg_export_log_error_no_file),
MSG_EXPORT_LOG_EXPORT_ERROR_FOPEN(LogLevel.ERROR,R.string.msg_export_log_error_fopen),
MSG_EXPORT_LOG_EXPORT_ERROR_WRITING(LogLevel.ERROR,R.string.msg_export_log_error_writing),
MSG_EXPORT_LOG_EXPORT_SUCCESS (LogLevel.OK, R.string.msg_export_log_success),
;
public final int mMsgId;
@ -755,9 +816,11 @@ public abstract class OperationResult implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mResult);
if (mLog != null) {
dest.writeTypedList(mLog.toList());
}
// Get a ticket for our log.
UUID mTicket = dehydrateLog(mLog);
// And write out the UUID most and least significant bits.
dest.writeLong(mTicket.getMostSignificantBits());
dest.writeLong(mTicket.getLeastSignificantBits());
}
public static class OperationLog implements Iterable<LogEntryParcel> {

View File

@ -100,8 +100,8 @@ public class PgpKeyOperation {
private static final int[] PREFERRED_HASH_ALGORITHMS = new int[]{
HashAlgorithmTags.SHA512,
HashAlgorithmTags.SHA384,
HashAlgorithmTags.SHA224,
HashAlgorithmTags.SHA256,
HashAlgorithmTags.SHA224,
HashAlgorithmTags.RIPEMD160
};
private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[]{
@ -131,6 +131,7 @@ public class PgpKeyOperation {
private static final int SECRET_KEY_ENCRYPTOR_S2K_COUNT = 0x90;
private static final int SECRET_KEY_ENCRYPTOR_HASH_ALGO = HashAlgorithmTags.SHA256;
private static final int SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO = SymmetricKeyAlgorithmTags.AES_256;
private static final int SECRET_KEY_SIGNATURE_HASH_ALGO = HashAlgorithmTags.SHA256;
public PgpKeyOperation(Progressable progress) {
super();
@ -1025,7 +1026,7 @@ public class PgpKeyOperation {
// add packet with EMPTY notation data (updates old one, but will be stripped later)
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
{ // set subpackets
@ -1051,7 +1052,7 @@ public class PgpKeyOperation {
// add packet with "pin" notation data
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
{ // set subpackets
@ -1236,7 +1237,7 @@ public class PgpKeyOperation {
int flags, long expiry)
throws IOException, PGPException, SignatureException {
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
@ -1279,7 +1280,7 @@ public class PgpKeyOperation {
PGPUserAttributeSubpacketVector vector)
throws IOException, PGPException, SignatureException {
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
@ -1298,7 +1299,7 @@ public class PgpKeyOperation {
PGPPrivateKey masterPrivateKey, PGPPublicKey pKey, String userId)
throws IOException, PGPException, SignatureException {
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator();
@ -1312,7 +1313,7 @@ public class PgpKeyOperation {
PGPPublicKey masterPublicKey, PGPPrivateKey masterPrivateKey, PGPPublicKey pKey)
throws IOException, PGPException, SignatureException {
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA512)
masterPublicKey.getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator();
@ -1356,7 +1357,7 @@ public class PgpKeyOperation {
PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator();
subHashedPacketsGen.setSignatureCreationTime(false, creationTime);
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
pKey.getAlgorithm(), HashAlgorithmTags.SHA512)
pKey.getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
sGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey);
@ -1377,7 +1378,7 @@ public class PgpKeyOperation {
}
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA512)
masterPublicKey.getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
sGen.init(PGPSignature.SUBKEY_BINDING, masterPrivateKey);

View File

@ -28,9 +28,11 @@ public class CreateKeyActivity extends BaseActivity {
public static final String EXTRA_NAME = "name";
public static final String EXTRA_EMAIL = "email";
public static final int FRAG_ACTION_START = 0;
public static final int FRAG_ACTION_TO_RIGHT = 1;
public static final int FRAG_ACTION_TO_LEFT = 2;
public static enum FragAction {
START,
TO_RIGHT,
TO_LEFT
}
@Override
public void onCreate(Bundle savedInstanceState) {
@ -42,7 +44,7 @@ public class CreateKeyActivity extends BaseActivity {
getIntent().getStringExtra(EXTRA_NAME),
getIntent().getStringExtra(EXTRA_EMAIL)
);
loadFragment(null, frag, FRAG_ACTION_START);
loadFragment(null, frag, FragAction.START);
}
@Override
@ -50,7 +52,7 @@ public class CreateKeyActivity extends BaseActivity {
setContentView(R.layout.create_key_activity);
}
public void loadFragment(Bundle savedInstanceState, Fragment fragment, int action) {
public void loadFragment(Bundle savedInstanceState, Fragment fragment, FragAction action) {
// 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.
@ -63,15 +65,15 @@ public class CreateKeyActivity extends BaseActivity {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
switch (action) {
case FRAG_ACTION_START:
case START:
transaction.setCustomAnimations(0, 0);
transaction.replace(R.id.create_key_fragment_container, fragment)
.commitAllowingStateLoss();
break;
case FRAG_ACTION_TO_LEFT:
case TO_LEFT:
getSupportFragmentManager().popBackStackImmediate();
break;
case FRAG_ACTION_TO_RIGHT:
case TO_RIGHT:
transaction.setCustomAnimations(R.anim.frag_slide_in_from_right, R.anim.frag_slide_out_to_left,
R.anim.frag_slide_in_from_left, R.anim.frag_slide_out_to_right);
transaction.addToBackStack(null);

View File

@ -43,6 +43,7 @@ import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences;
@ -117,7 +118,7 @@ public class CreateKeyFinalFragment extends Fragment {
mBackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCreateKeyActivity.loadFragment(null, null, CreateKeyActivity.FRAG_ACTION_TO_LEFT);
mCreateKeyActivity.loadFragment(null, null, FragAction.TO_LEFT);
}
});

View File

@ -32,6 +32,7 @@ import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
import org.sufficientlysecure.keychain.util.ContactHelper;
import java.util.regex.Matcher;
@ -161,7 +162,7 @@ public class CreateKeyInputFragment extends Fragment {
);
hideKeyboard();
mCreateKeyActivity.loadFragment(null, frag, CreateKeyActivity.FRAG_ACTION_TO_RIGHT);
mCreateKeyActivity.loadFragment(null, frag, FragAction.TO_RIGHT);
}
}

View File

@ -31,6 +31,7 @@ import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
public abstract class DecryptFragment extends Fragment {
private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
@ -141,16 +142,16 @@ public abstract class DecryptFragment extends Fragment {
if (signatureResult.isSignatureOnly()) {
mEncryptionText.setText(R.string.decrypt_result_not_encrypted);
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, KeyFormattingUtils.STATE_NOT_ENCRYPTED);
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.NOT_ENCRYPTED);
} else {
mEncryptionText.setText(R.string.decrypt_result_encrypted);
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, KeyFormattingUtils.STATE_ENCRYPTED);
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED);
}
switch (signatureResult.getStatus()) {
case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: {
mSignatureText.setText(R.string.decrypt_result_signature_certified);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_VERIFIED);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.VERIFIED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId);
@ -161,7 +162,7 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: {
mSignatureText.setText(R.string.decrypt_result_signature_uncertified);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_UNVERIFIED);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNVERIFIED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId);
@ -172,11 +173,11 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_KEY_MISSING: {
mSignatureText.setText(R.string.decrypt_result_signature_missing_key);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_UNKNOWN_KEY);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNKNOWN_KEY);
setSignatureLayoutVisibility(View.VISIBLE);
mSignatureAction.setText(R.string.decrypt_result_action_Lookup);
mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_action_download, 0);
mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_file_download_grey_24dp, 0);
mSignatureLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -190,7 +191,7 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED: {
mSignatureText.setText(R.string.decrypt_result_signature_expired_key);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_EXPIRED);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.EXPIRED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId);
@ -201,7 +202,7 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED: {
mSignatureText.setText(R.string.decrypt_result_signature_revoked_key);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_REVOKED);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.REVOKED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId);
@ -212,7 +213,7 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_ERROR: {
mSignatureText.setText(R.string.decrypt_result_invalid_signature);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_INVALID);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.INVALID);
setSignatureLayoutVisibility(View.GONE);
@ -224,9 +225,9 @@ public abstract class DecryptFragment extends Fragment {
setSignatureLayoutVisibility(View.GONE);
mSignatureText.setText(R.string.decrypt_result_no_signature);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_NOT_SIGNED);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.NOT_SIGNED);
mEncryptionText.setText(R.string.decrypt_result_encrypted);
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, KeyFormattingUtils.STATE_ENCRYPTED);
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED);
valid = true;
}

View File

@ -32,10 +32,9 @@ public class HelpActivity extends BaseActivity {
public static final int TAB_START = 0;
public static final int TAB_FAQ = 1;
public static final int TAB_WOT = 2;
public static final int TAB_NFC = 3;
public static final int TAB_CHANGELOG = 4;
public static final int TAB_ABOUT = 5;
public static final int TAB_TRUST = 2;
public static final int TAB_CHANGELOG = 3;
public static final int TAB_ABOUT = 4;
ViewPager mViewPager;
private PagerTabStripAdapter mTabsAdapter;
@ -69,21 +68,11 @@ public class HelpActivity extends BaseActivity {
mTabsAdapter.addTab(HelpHtmlFragment.class, startBundle,
getString(R.string.help_tab_start));
Bundle faqBundle = new Bundle();
faqBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_faq);
mTabsAdapter.addTab(HelpHtmlFragment.class, faqBundle,
getString(R.string.help_tab_faq));
Bundle wotBundle = new Bundle();
wotBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_wot);
wotBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_certification);
mTabsAdapter.addTab(HelpHtmlFragment.class, wotBundle,
getString(R.string.help_tab_wot));
Bundle nfcBundle = new Bundle();
nfcBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_nfc_beam);
mTabsAdapter.addTab(HelpHtmlFragment.class, nfcBundle,
getString(R.string.help_tab_nfc_beam));
Bundle changelogBundle = new Bundle();
changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog);
mTabsAdapter.addTab(HelpHtmlFragment.class, changelogBundle,

View File

@ -70,6 +70,7 @@ import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import org.sufficientlysecure.keychain.ui.util.Highlighter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.ExportHelper;
import org.sufficientlysecure.keychain.util.FabContainer;
@ -77,7 +78,6 @@ import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
@ -268,7 +268,7 @@ public class KeyListFragment extends LoaderFragment
KeyRings.MASTER_KEY_ID,
KeyRings.USER_ID,
KeyRings.IS_REVOKED,
KeyRings.EXPIRY,
KeyRings.IS_EXPIRED,
KeyRings.VERIFIED,
KeyRings.HAS_ANY_SECRET
};
@ -276,7 +276,7 @@ public class KeyListFragment extends LoaderFragment
static final int INDEX_MASTER_KEY_ID = 1;
static final int INDEX_USER_ID = 2;
static final int INDEX_IS_REVOKED = 3;
static final int INDEX_EXPIRY = 4;
static final int INDEX_IS_EXPIRED = 4;
static final int INDEX_VERIFIED = 5;
static final int INDEX_HAS_ANY_SECRET = 6;
@ -708,21 +708,20 @@ public class KeyListFragment extends LoaderFragment
long masterKeyId = cursor.getLong(INDEX_MASTER_KEY_ID);
boolean isSecret = cursor.getInt(INDEX_HAS_ANY_SECRET) != 0;
boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
boolean isExpired = !cursor.isNull(INDEX_EXPIRY)
&& new Date(cursor.getLong(INDEX_EXPIRY) * 1000).before(new Date());
boolean isExpired = cursor.getInt(INDEX_IS_EXPIRED) != 0;
boolean isVerified = cursor.getInt(INDEX_VERIFIED) > 0;
h.mMasterKeyId = masterKeyId;
// Note: order is important!
if (isRevoked) {
KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, null, State.REVOKED, R.color.bg_gray);
h.mStatus.setVisibility(View.VISIBLE);
h.mSlinger.setVisibility(View.GONE);
h.mMainUserId.setTextColor(context.getResources().getColor(R.color.bg_gray));
h.mMainUserIdRest.setTextColor(context.getResources().getColor(R.color.bg_gray));
} else if (isExpired) {
KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, null, State.EXPIRED, R.color.bg_gray);
h.mStatus.setVisibility(View.VISIBLE);
h.mSlinger.setVisibility(View.GONE);
h.mMainUserId.setTextColor(context.getResources().getColor(R.color.bg_gray));
@ -735,10 +734,10 @@ public class KeyListFragment extends LoaderFragment
} else {
// this is a public key - show if it's verified
if (isVerified) {
KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, KeyFormattingUtils.STATE_VERIFIED);
KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, State.VERIFIED);
h.mStatus.setVisibility(View.VISIBLE);
} else {
KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, KeyFormattingUtils.STATE_UNVERIFIED);
KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, State.UNVERIFIED);
h.mStatus.setVisibility(View.VISIBLE);
}
h.mSlinger.setVisibility(View.GONE);

View File

@ -22,9 +22,13 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Parcel;
import android.support.v4.app.ListFragment;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
@ -33,11 +37,19 @@ import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogLevel;
import org.sufficientlysecure.keychain.operations.results.OperationResult.SubLogEntryParcel;
import org.sufficientlysecure.keychain.util.FileHelper;
import org.sufficientlysecure.keychain.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Iterator;
public class LogDisplayFragment extends ListFragment implements OnItemClickListener {
@ -46,6 +58,12 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
OperationResult mResult;
public static final String EXTRA_RESULT = "log";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
@ -70,6 +88,183 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
getListView().setFastScrollEnabled(true);
getListView().setDividerHeight(0);
}
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.log_display, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_log_display_export_log:
exportLog();
break;
}
return super.onOptionsItemSelected(item);
}
private void exportLog() {
showExportLogDialog(new File(Constants.Path.APP_DIR, "export.log"));
}
private void writeToLogFile(final OperationResult.OperationLog operationLog, final File f) {
OperationResult.OperationLog currLog = new OperationResult.OperationLog();
currLog.add(OperationResult.LogType.MSG_EXPORT_LOG, 0);
boolean error = false;
PrintWriter pw = null;
try {
pw = new PrintWriter(f);
pw.print(getPrintableOperationLog(operationLog, ""));
if (pw.checkError()) {//IOException
Log.e(Constants.TAG, "Log Export I/O Exception " + f.getAbsolutePath());
currLog.add(OperationResult.LogType.MSG_EXPORT_LOG_EXPORT_ERROR_WRITING, 1);
error = true;
}
} catch (FileNotFoundException e) {
Log.e(Constants.TAG, "File not found for exporting log " + f.getAbsolutePath());
currLog.add(OperationResult.LogType.MSG_EXPORT_LOG_EXPORT_ERROR_FOPEN, 1);
error = true;
}
if (pw != null) {
pw.close();
if (!error && pw.checkError()) {//check if it is only pw.close() which generated error
currLog.add(OperationResult.LogType.MSG_EXPORT_LOG_EXPORT_ERROR_WRITING, 1);
error = true;
}
}
if (!error) currLog.add(OperationResult.LogType.MSG_EXPORT_LOG_EXPORT_SUCCESS, 1);
int opResultCode = error ? OperationResult.RESULT_ERROR : OperationResult.RESULT_OK;
OperationResult opResult = new LogExportResult(opResultCode, currLog);
opResult.createNotify(getActivity()).show();
}
/**
* returns an indented String of an entire OperationLog
*
* @param opLog log to be converted to indented, printable format
* @param basePadding padding to add at the start of all log entries, made for use with SubLogs
* @return printable, indented version of passed operationLog
*/
private String getPrintableOperationLog(OperationResult.OperationLog opLog, String basePadding) {
String log = "";
for (Iterator<LogEntryParcel> logIterator = opLog.iterator(); logIterator.hasNext(); ) {
log += getPrintableLogEntry(logIterator.next(), basePadding) + "\n";
}
log = log.substring(0, log.length() - 1);//gets rid of extra new line
return log;
}
/**
* returns an indented String of a LogEntryParcel including any sub-logs it may contain
*
* @param entryParcel log entryParcel whose String representation is to be obtained
* @return indented version of passed log entryParcel in a readable format
*/
private String getPrintableLogEntry(OperationResult.LogEntryParcel entryParcel,
String basePadding) {
final String indent = " ";//4 spaces = 1 Indent level
String padding = basePadding;
for (int i = 0; i < entryParcel.mIndent; i++) {
padding += indent;
}
String logText = padding;
switch (entryParcel.mType.mLevel) {
case DEBUG:
logText += "[DEBUG]";
break;
case INFO:
logText += "[INFO]";
break;
case WARN:
logText += "[WARN]";
break;
case ERROR:
logText += "[ERROR]";
break;
case START:
logText += "[START]";
break;
case OK:
logText += "[OK]";
break;
case CANCELLED:
logText += "[CANCELLED]";
break;
}
// special case: first parameter may be a quantity
if (entryParcel.mParameters != null && entryParcel.mParameters.length > 0
&& entryParcel.mParameters[0] instanceof Integer) {
logText += getResources().getQuantityString(entryParcel.mType.getMsgId(),
(Integer) entryParcel.mParameters[0],
entryParcel.mParameters);
} else {
logText += getResources().getString(entryParcel.mType.getMsgId(),
entryParcel.mParameters);
}
if (entryParcel instanceof SubLogEntryParcel) {
OperationResult subResult = ((SubLogEntryParcel) entryParcel).getSubResult();
LogEntryParcel subEntry = subResult.getLog().getLast();
if (subEntry != null) {
//the first line of log of subResult is same as entryParcel, so replace logText
logText = getPrintableOperationLog(subResult.getLog(), padding);
}
}
return logText;
}
private void showExportLogDialog(final File exportFile) {
String title = this.getString(R.string.title_export_log);
String message = this.getString(R.string.specify_file_to_export_log_to);
FileHelper.saveFile(new FileHelper.FileDialogCallback() {
@Override
public void onFileSelected(File file, boolean checked) {
writeToLogFile(mResult.getLog(), file);
}
}, this.getActivity().getSupportFragmentManager(), title, message, exportFile, null);
}
private static class LogExportResult extends OperationResult {
public static Creator<LogExportResult> CREATOR = new Creator<LogExportResult>() {
public LogExportResult createFromParcel(final Parcel source) {
return new LogExportResult(source);
}
public LogExportResult[] newArray(final int size) {
return new LogExportResult[size];
}
};
public LogExportResult(int result, OperationLog log) {
super(result, log);
}
/**
* trivial but necessary to implement the Parcelable protocol.
*/
public LogExportResult(Parcel source) {
super(source);
}
}
@Override
@ -109,7 +304,7 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
mSecondImg = secondImg;
}
}
// Check if convertView.setPadding is redundant
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LogEntryParcel entry = getItem(position);
@ -132,7 +327,6 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
if (entry instanceof SubLogEntryParcel) {
ih.mSub.setVisibility(View.VISIBLE);
convertView.setClickable(false);
convertView.setPadding((entry.mIndent) * dipFactor, 0, 0, 0);
OperationResult result = ((SubLogEntryParcel) entry).getSubResult();

View File

@ -46,6 +46,7 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
@ -149,6 +150,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
public static class PassphraseDialogFragment extends DialogFragment implements TextView.OnEditorActionListener {
private EditText mPassphraseEditText;
private TextView mPassphraseText;
private View mInput, mProgress;
private CanonicalizedSecretKeyRing mSecretRing = null;
@ -167,7 +169,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
// if the dialog is displayed from the application class, design is missing
// hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay
ContextThemeWrapper theme = new ContextThemeWrapper(activity,
R.style.Theme_AppCompat_Light);
R.style.Theme_AppCompat_Light_Dialog);
mSubKeyId = getArguments().getLong(EXTRA_SUBKEY_ID);
mServiceIntent = getArguments().getParcelable(EXTRA_DATA);
@ -176,13 +178,30 @@ public class PassphraseDialogActivity extends FragmentActivity {
alert.setTitle(R.string.title_unlock);
LayoutInflater inflater = LayoutInflater.from(theme);
View view = inflater.inflate(R.layout.passphrase_dialog, null);
alert.setView(view);
mPassphraseText = (TextView) view.findViewById(R.id.passphrase_text);
mPassphraseEditText = (EditText) view.findViewById(R.id.passphrase_passphrase);
mInput = view.findViewById(R.id.input);
mProgress = view.findViewById(R.id.progress);
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
String userId;
CanonicalizedSecretKey.SecretKeyType keyType = CanonicalizedSecretKey.SecretKeyType.PASSPHRASE;
String message;
if (mSubKeyId == Constants.key.symmetric || mSubKeyId == Constants.key.none) {
alert.setMessage(R.string.passphrase_for_symmetric_encryption);
message = getString(R.string.passphrase_for_symmetric_encryption);
} else {
String message;
try {
ProviderHelper helper = new ProviderHelper(activity);
mSecretRing = helper.getCanonicalizedSecretKeyRing(
@ -191,7 +210,13 @@ public class PassphraseDialogActivity extends FragmentActivity {
// above can't be statically verified to have been set in all cases because
// the catch clause doesn't return.
try {
userId = mSecretRing.getPrimaryUserIdWithFallback();
String mainUserId = mSecretRing.getPrimaryUserIdWithFallback();
String[] mainUserIdSplit = KeyRing.splitUserId(mainUserId);
if (mainUserIdSplit[0] != null) {
userId = mainUserIdSplit[0];
} else {
userId = getString(R.string.user_id_no_name);
}
} catch (PgpKeyNotFoundException e) {
userId = null;
}
@ -231,33 +256,16 @@ public class PassphraseDialogActivity extends FragmentActivity {
alert.setCancelable(false);
return alert.create();
}
alert.setMessage(message);
}
LayoutInflater inflater = LayoutInflater.from(theme);
View view = inflater.inflate(R.layout.passphrase_dialog, null);
alert.setView(view);
mPassphraseEditText = (EditText) view.findViewById(R.id.passphrase_passphrase);
mInput = view.findViewById(R.id.input);
mProgress = view.findViewById(R.id.progress);
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
mPassphraseText.setText(message);
if (keyType == CanonicalizedSecretKey.SecretKeyType.PATTERN) {
// start pattern dialog and show progress circle here...
// Intent patternActivity = new Intent(getActivity(), LockPatternActivity.class);
// patternActivity.putExtra(LockPatternActivity.EXTRA_PATTERN, "123");
// startActivityForResult(patternActivity, REQUEST_CODE_ENTER_PATTERN);
mInput.setVisibility(View.GONE);
mInput.setVisibility(View.INVISIBLE);
mProgress.setVisibility(View.VISIBLE);
} else {
// Hack to open keyboard.
@ -325,7 +333,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
return;
}
mInput.setVisibility(View.GONE);
mInput.setVisibility(View.INVISIBLE);
mProgress.setVisibility(View.VISIBLE);
positive.setEnabled(false);
@ -367,7 +375,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
mPassphraseEditText.setText("");
mPassphraseEditText.setError(getString(R.string.wrong_passphrase));
mInput.setVisibility(View.VISIBLE);
mProgress.setVisibility(View.GONE);
mProgress.setVisibility(View.INVISIBLE);
positive.setEnabled(true);
return;
}

View File

@ -46,6 +46,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import java.util.Vector;
@ -136,7 +137,7 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T
mSearchView.setId(SEARCH_ID);
mSearchView.setHint(R.string.menu_search);
mSearchView.setCompoundDrawablesWithIntrinsicBounds(
getResources().getDrawable(R.drawable.ic_action_search), null, null, null);
getResources().getDrawable(R.drawable.ic_search_grey_24dp), null, null, null);
linearLayout.addView(mSearchView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
@ -376,15 +377,15 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T
// Check if key is viable for our purposes
if (cursor.getInt(mIndexHasEncrypt) == 0) {
h.statusIcon.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, KeyFormattingUtils.STATE_UNAVAILABLE);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, State.UNAVAILABLE);
enabled = false;
} else if (cursor.getInt(mIndexIsVerified) != 0) {
h.statusIcon.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, KeyFormattingUtils.STATE_VERIFIED);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, State.VERIFIED);
enabled = true;
} else {
h.statusIcon.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, KeyFormattingUtils.STATE_UNVERIFIED);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, State.UNVERIFIED);
enabled = true;
}
}

View File

@ -75,16 +75,15 @@ import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.ui.linked.LinkedIdWizard;
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.util.QrCodeUtils;
import org.sufficientlysecure.keychain.ui.widget.AspectRatioImageView;
import org.sufficientlysecure.keychain.util.ContactHelper;
import org.sufficientlysecure.keychain.util.ExportHelper;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
public class ViewKeyActivity extends BaseActivity implements
@ -106,7 +105,7 @@ public class ViewKeyActivity extends BaseActivity implements
private ImageButton mActionEncryptText;
private ImageButton mActionNfc;
private FloatingActionButton mFab;
private AspectRatioImageView mPhoto;
private ImageView mPhoto;
private ImageView mQrCode;
private CardView mQrCodeLayout;
@ -122,6 +121,9 @@ public class ViewKeyActivity extends BaseActivity implements
private boolean mIsSecret = false;
private boolean mHasEncrypt = false;
private boolean mIsVerified = false;
private boolean mIsRevoked = false;
private boolean mIsExpired = false;
private MenuItem mRefreshItem;
private boolean mIsRefreshing;
private Animation mRotate, mRotateSpin;
@ -148,7 +150,7 @@ public class ViewKeyActivity extends BaseActivity implements
mActionEncryptText = (ImageButton) findViewById(R.id.view_key_action_encrypt_text);
mActionNfc = (ImageButton) findViewById(R.id.view_key_action_nfc);
mFab = (FloatingActionButton) findViewById(R.id.fab);
mPhoto = (AspectRatioImageView) findViewById(R.id.view_key_photo);
mPhoto = (ImageView) findViewById(R.id.view_key_photo);
mQrCode = (ImageView) findViewById(R.id.view_key_qr_code);
mQrCodeLayout = (CardView) findViewById(R.id.view_key_qr_code_layout);
@ -174,7 +176,7 @@ public class ViewKeyActivity extends BaseActivity implements
}
});
mRotate = AnimationUtils.loadAnimation(this, R.anim.rotate);
mRotate = AnimationUtils.loadAnimation(this, R.anim.rotate);
mRotate.setRepeatCount(Animation.INFINITE);
mRotate.setAnimationListener(new Animation.AnimationListener() {
@Override
@ -358,7 +360,7 @@ public class ViewKeyActivity extends BaseActivity implements
addLinked.setVisible(mIsSecret);
MenuItem certifyFingerprint = menu.findItem(R.id.menu_key_view_certify_fingerprint);
certifyFingerprint.setVisible(!mIsSecret && !mIsVerified);
certifyFingerprint.setVisible(!mIsSecret && !mIsVerified && !mIsExpired && !mIsRevoked);
return true;
}
@ -409,12 +411,12 @@ public class ViewKeyActivity extends BaseActivity implements
private void certifyImmediate() {
Intent intent = new Intent(this, CertifyKeyActivity.class);
intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{ mMasterKeyId });
intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{mMasterKeyId});
startCertifyIntent(intent);
}
private void startCertifyIntent (Intent intent) {
private void startCertifyIntent(Intent intent) {
// Message is received after signing is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this) {
public void handleMessage(Message message) {
@ -761,7 +763,7 @@ public class ViewKeyActivity extends BaseActivity implements
KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.KeyRings.USER_ID,
KeychainContract.KeyRings.IS_REVOKED,
KeychainContract.KeyRings.EXPIRY,
KeychainContract.KeyRings.IS_EXPIRED,
KeychainContract.KeyRings.VERIFIED,
KeychainContract.KeyRings.HAS_ANY_SECRET,
KeychainContract.KeyRings.FINGERPRINT,
@ -771,7 +773,7 @@ public class ViewKeyActivity extends BaseActivity implements
static final int INDEX_MASTER_KEY_ID = 1;
static final int INDEX_USER_ID = 2;
static final int INDEX_IS_REVOKED = 3;
static final int INDEX_EXPIRY = 4;
static final int INDEX_IS_EXPIRED = 4;
static final int INDEX_VERIFIED = 5;
static final int INDEX_HAS_ANY_SECRET = 6;
static final int INDEX_FINGERPRINT = 7;
@ -820,9 +822,8 @@ public class ViewKeyActivity extends BaseActivity implements
mIsSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
mHasEncrypt = data.getInt(INDEX_HAS_ENCRYPT) != 0;
boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
boolean isExpired = !data.isNull(INDEX_EXPIRY)
&& new Date(data.getLong(INDEX_EXPIRY) * 1000).before(new Date());
mIsRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
mIsExpired = data.getInt(INDEX_IS_EXPIRED) != 0;
mIsVerified = data.getInt(INDEX_VERIFIED) > 0;
// if the refresh animation isn't playing
@ -832,10 +833,10 @@ public class ViewKeyActivity extends BaseActivity implements
// this is done at the end of the animation otherwise
}
AsyncTask<String, Void, Bitmap> photoTask =
new AsyncTask<String, Void, Bitmap>() {
protected Bitmap doInBackground(String... fingerprint) {
return ContactHelper.photoFromFingerprint(getContentResolver(), fingerprint[0]);
AsyncTask<Long, Void, Bitmap> photoTask =
new AsyncTask<Long, Void, Bitmap>() {
protected Bitmap doInBackground(Long... mMasterKeyId) {
return ContactHelper.loadPhotoByMasterKeyId(getContentResolver(), mMasterKeyId[0], true);
}
protected void onPostExecute(Bitmap photo) {
@ -846,11 +847,11 @@ public class ViewKeyActivity extends BaseActivity implements
// Note: order is important
int color;
if (isRevoked) {
if (mIsRevoked) {
mStatusText.setText(R.string.view_key_revoked);
mStatusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
KeyFormattingUtils.STATE_REVOKED, R.color.icons, true);
State.REVOKED, R.color.icons, true);
color = getResources().getColor(R.color.android_red_light);
mActionEncryptFile.setVisibility(View.GONE);
@ -858,7 +859,7 @@ public class ViewKeyActivity extends BaseActivity implements
mActionNfc.setVisibility(View.GONE);
mFab.setVisibility(View.GONE);
mQrCodeLayout.setVisibility(View.GONE);
} else if (isExpired) {
} else if (mIsExpired) {
if (mIsSecret) {
mStatusText.setText(R.string.view_key_expired_secret);
} else {
@ -866,7 +867,7 @@ public class ViewKeyActivity extends BaseActivity implements
}
mStatusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
KeyFormattingUtils.STATE_EXPIRED, R.color.icons, true);
State.EXPIRED, R.color.icons, true);
color = getResources().getColor(R.color.android_red_light);
mActionEncryptFile.setVisibility(View.GONE);
@ -879,10 +880,10 @@ public class ViewKeyActivity extends BaseActivity implements
mStatusImage.setVisibility(View.GONE);
color = getResources().getColor(R.color.primary);
// reload qr code only if the fingerprint changed
if ( !mFingerprint.equals(oldFingerprint)) {
if (!mFingerprint.equals(oldFingerprint)) {
loadQrCode(mFingerprint);
}
photoTask.execute(mFingerprint);
photoTask.execute(mMasterKeyId);
mQrCodeLayout.setVisibility(View.VISIBLE);
// and place leftOf qr code
@ -926,16 +927,16 @@ public class ViewKeyActivity extends BaseActivity implements
mStatusText.setText(R.string.view_key_verified);
mStatusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
KeyFormattingUtils.STATE_VERIFIED, R.color.icons, true);
State.VERIFIED, R.color.icons, true);
color = getResources().getColor(R.color.primary);
photoTask.execute(mFingerprint);
photoTask.execute(mMasterKeyId);
mFab.setVisibility(View.GONE);
} else {
mStatusText.setText(R.string.view_key_unverified);
mStatusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
KeyFormattingUtils.STATE_UNVERIFIED, R.color.icons, true);
State.UNVERIFIED, R.color.icons, true);
color = getResources().getColor(R.color.android_orange_light);
mFab.setVisibility(View.VISIBLE);
@ -943,27 +944,21 @@ public class ViewKeyActivity extends BaseActivity implements
}
if (mPreviousColor == 0 || mPreviousColor == color) {
mToolbar.setBackgroundColor(color);
mStatusBar.setBackgroundColor(color);
mBigToolbar.setBackgroundColor(color);
mPreviousColor = color;
} else {
ObjectAnimator colorFade1 =
ObjectAnimator.ofObject(mToolbar, "backgroundColor",
new ArgbEvaluator(), mPreviousColor, color);
ObjectAnimator colorFade2 =
ObjectAnimator.ofObject(mStatusBar, "backgroundColor",
new ArgbEvaluator(), mPreviousColor, color);
ObjectAnimator colorFade3 =
ObjectAnimator colorFade2 =
ObjectAnimator.ofObject(mBigToolbar, "backgroundColor",
new ArgbEvaluator(), mPreviousColor, color);
colorFade1.setDuration(1200);
colorFade2.setDuration(1200);
colorFade3.setDuration(1200);
colorFade1.start();
colorFade2.start();
colorFade3.start();
mPreviousColor = color;
}

View File

@ -43,8 +43,6 @@ import org.sufficientlysecure.keychain.util.ContactHelper;
import org.sufficientlysecure.keychain.util.ExportHelper;
import org.sufficientlysecure.keychain.util.Log;
import java.util.Date;
public class ViewKeyAdvActivity extends BaseActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
@ -159,7 +157,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.KeyRings.USER_ID,
KeychainContract.KeyRings.IS_REVOKED,
KeychainContract.KeyRings.EXPIRY,
KeychainContract.KeyRings.IS_EXPIRED,
KeychainContract.KeyRings.VERIFIED,
KeychainContract.KeyRings.HAS_ANY_SECRET
};
@ -167,7 +165,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
static final int INDEX_MASTER_KEY_ID = 1;
static final int INDEX_USER_ID = 2;
static final int INDEX_IS_REVOKED = 3;
static final int INDEX_EXPIRY = 4;
static final int INDEX_IS_EXPIRED = 4;
static final int INDEX_VERIFIED = 5;
static final int INDEX_HAS_ANY_SECRET = 6;
@ -212,8 +210,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
boolean isSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
boolean isExpired = !data.isNull(INDEX_EXPIRY)
&& new Date(data.getLong(INDEX_EXPIRY) * 1000).before(new Date());
boolean isExpired = data.getInt(INDEX_IS_EXPIRED) != 0;
boolean isVerified = data.getInt(INDEX_VERIFIED) > 0;
// Note: order is important

View File

@ -260,7 +260,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
static final String[] UNIFIED_PROJECTION = new String[]{
KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET,
KeyRings.USER_ID, KeyRings.FINGERPRINT,
KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.EXPIRY,
KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.IS_EXPIRED,
};
static final int INDEX_UNIFIED_MASTER_KEY_ID = 1;
@ -270,7 +270,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
static final int INDEX_UNIFIED_ALGORITHM = 5;
static final int INDEX_UNIFIED_KEY_SIZE = 6;
static final int INDEX_UNIFIED_CREATION = 7;
static final int INDEX_UNIFIED_EXPIRY = 8;
static final int INDEX_UNIFIED_ID_EXPIRED = 8;
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
setContentShown(false);

View File

@ -114,12 +114,12 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
static final String[] UNIFIED_PROJECTION = new String[]{
KeyRings._ID, KeyRings.MASTER_KEY_ID,
KeyRings.HAS_ANY_SECRET, KeyRings.IS_REVOKED, KeyRings.EXPIRY, KeyRings.HAS_ENCRYPT
KeyRings.HAS_ANY_SECRET, KeyRings.IS_REVOKED, KeyRings.IS_EXPIRED, KeyRings.HAS_ENCRYPT
};
static final int INDEX_UNIFIED_MASTER_KEY_ID = 1;
static final int INDEX_UNIFIED_HAS_ANY_SECRET = 2;
static final int INDEX_UNIFIED_IS_REVOKED = 3;
static final int INDEX_UNIFIED_EXPIRY = 4;
static final int INDEX_UNIFIED_IS_EXPIRED = 4;
static final int INDEX_UNIFIED_HAS_ENCRYPT = 5;
public Loader<Cursor> onCreateLoader(int id, Bundle args) {

View File

@ -115,12 +115,12 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
}
static final String[] TRUST_PROJECTION = new String[]{
KeyRings._ID, KeyRings.FINGERPRINT, KeyRings.IS_REVOKED, KeyRings.EXPIRY,
KeyRings._ID, KeyRings.FINGERPRINT, KeyRings.IS_REVOKED, KeyRings.IS_EXPIRED,
KeyRings.HAS_ANY_SECRET, KeyRings.VERIFIED
};
static final int INDEX_TRUST_FINGERPRINT = 1;
static final int INDEX_TRUST_IS_REVOKED = 2;
static final int INDEX_TRUST_EXPIRY = 3;
static final int INDEX_TRUST_IS_EXPIRED = 3;
static final int INDEX_UNIFIED_HAS_ANY_SECRET = 4;
static final int INDEX_VERIFIED = 5;
@ -169,8 +169,7 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
nothingSpecial = false;
} else {
Date expiryDate = new Date(data.getLong(INDEX_TRUST_EXPIRY) * 1000);
if (!data.isNull(INDEX_TRUST_EXPIRY) && expiryDate.before(new Date())) {
if (data.getInt(INDEX_TRUST_IS_EXPIRED) != 0) {
// if expired, dont trust it!
message.append(getString(R.string.key_trust_expired)).

View File

@ -37,6 +37,7 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
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.ArrayList;
import java.util.HashMap;
@ -175,9 +176,9 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
}
if (entry.isRevoked()) {
KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, State.REVOKED, R.color.bg_gray);
} else if (entry.isExpired()) {
KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, State.EXPIRED, R.color.bg_gray);
}
if (entry.isRevoked() || entry.isExpired()) {

View File

@ -39,9 +39,9 @@ import org.sufficientlysecure.keychain.pgp.linked.RawLinkedIdentity;
import org.sufficientlysecure.keychain.pgp.linked.resources.DnsResource;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.ui.ViewKeyFragment;
import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import java.io.IOException;
import java.util.WeakHashMap;
@ -66,15 +66,15 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {
switch (isVerified) {
case Certs.VERIFIED_SECRET:
KeyFormattingUtils.setStatusImage(mContext, holder.vVerified,
null, KeyFormattingUtils.STATE_VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break;
case Certs.VERIFIED_SELF:
KeyFormattingUtils.setStatusImage(mContext, holder.vVerified,
null, KeyFormattingUtils.STATE_UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break;
default:
KeyFormattingUtils.setStatusImage(mContext, holder.vVerified,
null, KeyFormattingUtils.STATE_INVALID, KeyFormattingUtils.DEFAULT_COLOR);
null, State.INVALID, KeyFormattingUtils.DEFAULT_COLOR);
break;
}

View File

@ -33,6 +33,7 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.ui.util.Highlighter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
/**
@ -133,11 +134,11 @@ abstract public class SelectKeyCursorAdapter extends CursorAdapter {
boolean enabled;
if (cursor.getInt(mIndexIsRevoked) != 0) {
h.statusIcon.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, null, State.REVOKED, R.color.bg_gray);
enabled = false;
} else if (cursor.getInt(mIndexIsExpiry) != 0) {
h.statusIcon.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, null, State.EXPIRED, R.color.bg_gray);
enabled = false;
} else {
h.statusIcon.setVisibility(View.GONE);

View File

@ -272,12 +272,12 @@ public class SubkeysAdapter extends CursorAdapter {
PorterDuff.Mode.SRC_IN);
if (isRevoked) {
vStatus.setImageResource(R.drawable.status_signature_revoked_cutout_24px);
vStatus.setImageResource(R.drawable.status_signature_revoked_cutout_24dp);
vStatus.setColorFilter(
mContext.getResources().getColor(R.color.bg_gray),
PorterDuff.Mode.SRC_IN);
} else if (isExpired) {
vStatus.setImageResource(R.drawable.status_signature_expired_cutout_24px);
vStatus.setImageResource(R.drawable.status_signature_expired_cutout_24dp);
vStatus.setColorFilter(
mContext.getResources().getColor(R.color.bg_gray),
PorterDuff.Mode.SRC_IN);

View File

@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
public class UserIdsAdapter extends UserAttributesAdapter {
protected LayoutInflater mInflater;
@ -127,7 +128,7 @@ public class UserIdsAdapter extends UserAttributesAdapter {
if (isRevoked) {
// set revocation icon (can this even be primary?)
KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
KeyFormattingUtils.setStatusImage(mContext, vVerified, null, State.REVOKED, R.color.bg_gray);
// disable revoked user ids
vName.setEnabled(false);
@ -149,13 +150,13 @@ public class UserIdsAdapter extends UserAttributesAdapter {
int isVerified = cursor.getInt(INDEX_VERIFIED);
switch (isVerified) {
case Certs.VERIFIED_SECRET:
KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
KeyFormattingUtils.setStatusImage(mContext, vVerified, null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break;
case Certs.VERIFIED_SELF:
KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
KeyFormattingUtils.setStatusImage(mContext, vVerified, null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break;
default:
KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_INVALID, KeyFormattingUtils.DEFAULT_COLOR);
KeyFormattingUtils.setStatusImage(mContext, vVerified, null, State.INVALID, KeyFormattingUtils.DEFAULT_COLOR);
break;
}
}

View File

@ -24,7 +24,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
@ -73,10 +72,8 @@ public class UserIdsAddedAdapter extends ArrayAdapter<String> {
holder.vDelete.setVisibility(View.VISIBLE); // always visible
// not used:
CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.user_id_item_check_box);
View certifiedLayout = convertView.findViewById(R.id.user_id_item_certified_layout);
ImageView editImage = (ImageView) convertView.findViewById(R.id.user_id_item_edit_image);
checkBox.setVisibility(View.GONE);
certifiedLayout.setVisibility(View.GONE);
editImage.setVisibility(View.GONE);

View File

@ -137,12 +137,10 @@ public class AddSubkeyDialogFragment extends DialogFragment {
}
});
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
// date picker works based on default time zone
Calendar minDateCal = Calendar.getInstance(TimeZone.getDefault());
minDateCal.add(Calendar.DAY_OF_YEAR, 1); // at least one day after creation (today)
mExpiryDatePicker.setMinDate(minDateCal.getTime().getTime());
}
// date picker works based on default time zone
Calendar minDateCal = Calendar.getInstance(TimeZone.getDefault());
minDateCal.add(Calendar.DAY_OF_YEAR, 1); // at least one day after creation (today)
mExpiryDatePicker.setMinDate(minDateCal.getTime().getTime());
{
ArrayList<Choice<Algorithm>> choices = new ArrayList<>();
@ -283,7 +281,7 @@ public class AddSubkeyDialogFragment extends DialogFragment {
// For EC keys, add a curve
if (algorithm == Algorithm.ECDH || algorithm == Algorithm.ECDSA) {
curve = ((Choice<Curve>) mCurveSpinner.getSelectedItem()).getId();
// Otherwise, get a keysize
// Otherwise, get a keysize
} else {
keySize = getProperKeyLength(algorithm, getSelectedKeyLength());
}

View File

@ -1,3 +1,20 @@
/*
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui.dialog;
import android.app.AlertDialog;

View File

@ -62,12 +62,9 @@ public class DeleteFileDialogFragment extends DialogFragment {
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity);
alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
alert.setTitle(R.string.warning);
alert.setMessage(this.getString(R.string.file_delete_confirmation, deleteFilename));
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
alert.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {

View File

@ -83,8 +83,6 @@ public class DeleteKeyDialogFragment extends DialogFragment {
mMainMessage = (TextView) mInflateView.findViewById(R.id.mainMessage);
builder.setTitle(R.string.warning);
final boolean hasSecret;
// If only a single key has been selected
@ -110,12 +108,14 @@ public class DeleteKeyDialogFragment extends DialogFragment {
}
hasSecret = ((Long) data.get(KeyRings.HAS_ANY_SECRET)) == 1;
// Set message depending on which key it is.
mMainMessage.setText(getString(
hasSecret ? R.string.secret_key_deletion_confirmation
: R.string.public_key_deletetion_confirmation,
name
));
if (hasSecret) {
// show title only for secret key deletions,
// see http://www.google.com/design/spec/components/dialogs.html#dialogs-behavior
builder.setTitle(getString(R.string.title_delete_secret_key, name));
mMainMessage.setText(getString(R.string.secret_key_deletion_confirmation, name));
} else {
mMainMessage.setText(getString(R.string.public_key_deletetion_confirmation, name));
}
} catch (ProviderHelper.NotFoundException e) {
dismiss();
return null;
@ -125,7 +125,6 @@ public class DeleteKeyDialogFragment extends DialogFragment {
hasSecret = false;
}
builder.setIcon(R.drawable.ic_dialog_alert_holo_light);
builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

View File

@ -25,11 +25,14 @@ import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.DatePicker;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
@ -97,62 +100,63 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment {
final CheckBox noExpiry = (CheckBox) view.findViewById(R.id.edit_subkey_expiry_no_expiry);
final DatePicker datePicker = (DatePicker) view.findViewById(R.id.edit_subkey_expiry_date_picker);
final TextView currentExpiry = (TextView) view.findViewById(R.id.edit_subkey_expiry_current_expiry);
final LinearLayout expiryLayout = (LinearLayout) view.findViewById(R.id.edit_subkey_expiry_layout);
noExpiry.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
datePicker.setVisibility(View.GONE);
expiryLayout.setVisibility(View.GONE);
} else {
datePicker.setVisibility(View.VISIBLE);
expiryLayout.setVisibility(View.VISIBLE);
}
}
});
// init date picker with default selected date
if (expiry == 0L) {
noExpiry.setChecked(true);
datePicker.setVisibility(View.GONE);
expiryLayout.setVisibility(View.GONE);
Calendar todayCal = Calendar.getInstance(TimeZone.getDefault());
if (creationCal.after(todayCal)) {
// Note: This is just for the rare cases where creation is _after_ today
// set it to creation date +1 day (don't set it to creationCal, it would break crash
// datePicker.setMinDate() execution with IllegalArgumentException
Calendar creationCalPlusOne = (Calendar) creationCal.clone();
creationCalPlusOne.add(Calendar.DAY_OF_YEAR, 1);
datePicker.init(
creationCalPlusOne.get(Calendar.YEAR),
creationCalPlusOne.get(Calendar.MONTH),
creationCalPlusOne.get(Calendar.DAY_OF_MONTH),
null
);
} else {
// normally, just init with today
datePicker.init(
todayCal.get(Calendar.YEAR),
todayCal.get(Calendar.MONTH),
todayCal.get(Calendar.DAY_OF_MONTH),
null
);
}
currentExpiry.setText(R.string.btn_no_date);
} else {
noExpiry.setChecked(false);
datePicker.setVisibility(View.VISIBLE);
expiryLayout.setVisibility(View.VISIBLE);
// set date picker to current expiry
datePicker.init(
expiryCal.get(Calendar.YEAR),
expiryCal.get(Calendar.MONTH),
expiryCal.get(Calendar.DAY_OF_MONTH),
null
);
// convert from UTC to time zone of device
Calendar expiryCalTimeZone = (Calendar) expiryCal.clone();
expiryCalTimeZone.setTimeZone(TimeZone.getDefault());
currentExpiry.setText(DateFormat.getDateFormat(
getActivity()).format(expiryCalTimeZone.getTime()));
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
datePicker.setMinDate(creationCal.getTime().getTime());
// date picker works based on default time zone
Calendar todayCal = Calendar.getInstance(TimeZone.getDefault());
if (creationCal.after(todayCal)) {
// NOTE: This is just for the rare cases where creation is _after_ today
// Min Date: Creation date + 1 day
Calendar creationCalPlusOne = (Calendar) creationCal.clone();
creationCalPlusOne.add(Calendar.DAY_OF_YEAR, 1);
datePicker.setMinDate(creationCalPlusOne.getTime().getTime());
datePicker.init(
creationCalPlusOne.get(Calendar.YEAR),
creationCalPlusOne.get(Calendar.MONTH),
creationCalPlusOne.get(Calendar.DAY_OF_MONTH),
null
);
} else {
// Min Date: today + 1 day
// at least one day after creation (today)
todayCal.add(Calendar.DAY_OF_YEAR, 1);
datePicker.setMinDate(todayCal.getTime().getTime());
datePicker.init(
todayCal.get(Calendar.YEAR),
todayCal.get(Calendar.MONTH),
todayCal.get(Calendar.DAY_OF_MONTH),
null
);
}
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

Some files were not shown because too many files have changed in this diff Show More