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
598 changed files with 1240 additions and 1508 deletions

4
.gitmodules vendored
View File

@@ -19,9 +19,11 @@
[submodule "extern/minidns"] [submodule "extern/minidns"]
path = extern/minidns path = extern/minidns
url = https://github.com/open-keychain/minidns.git url = https://github.com/open-keychain/minidns.git
ignore = dirty
[submodule "extern/TokenAutoComplete"] [submodule "extern/TokenAutoComplete"]
path = extern/TokenAutoComplete path = extern/TokenAutoComplete
url = https://github.com/open-keychain/TokenAutoComplete url = https://github.com/open-keychain/TokenAutoComplete
[submodule "extern/safeslinger-exchange"] [submodule "extern/safeslinger-exchange"]
path = 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_file = OpenKeychain/src/main/res/raw/help_changelog.html
source_lang = en source_lang = en
[open-keychain.help-wot] [open-keychain.help-certification]
file_filter = OpenKeychain/src/main/res/raw-<lang>/help_wot.html file_filter = OpenKeychain/src/main/res/raw-<lang>/help_certification.html
source_file = OpenKeychain/src/main/res/raw/help_wot.html source_file = OpenKeychain/src/main/res/raw/help_certification.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
source_lang = en source_lang = en
[open-keychain.help-start] [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_file = OpenKeychain/src/main/res/raw/help_start.html
source_lang = en 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 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: Named `options.json` in same dir. Sample:
```json ```json
{ {

View File

@@ -1,5 +1,5 @@
{ {
"basePath": "~/Documents", "basePath": "../../",
"filenameMap": { "filenameMap": {
"classic": "ic_action_{name}{bgSuffix}.png", "classic": "ic_action_{name}{bgSuffix}.png",
"fa": "ic_action_fa_{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 white repeat 24
python copy OpenKeychain av grey repeat 24 python copy OpenKeychain av grey repeat 24
python copy OpenKeychain editor white mode_edit 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 # navigation drawer sections
python copy OpenKeychain communication black vpn_key 24 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 python copy OpenKeychain file white folder 24
# multi select # 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/ PLAY_DIR=./drawables/
SRC_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) # Adobe Illustrator (.ai) exports by Tha Phlash are way better than the Inkscape exports (.svg)
#NAME="ic_launcher" #NAME="ic_launcher"
@@ -32,38 +21,24 @@ SRC_DIR=./drawables/
#inkscape -w 192 -h 192 -e "$XXXDPI_DIR/$NAME.png" $NAME.svg #inkscape -w 192 -h 192 -e "$XXXDPI_DIR/$NAME.png" $NAME.svg
#inkscape -w 512 -h 512 -e "$PLAY_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 do
echo $NAME echo $NAME
inkscape -w 32 -h 32 -e "$MDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg" inkscape -w 24 -h 24 -e "$MDPI_DIR/${NAME}_24dp.png" "$SRC_DIR/$NAME.svg"
inkscape -w 48 -h 48 -e "$HDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg" inkscape -w 36 -h 36 -e "$HDPI_DIR/${NAME}_24dp.png" "$SRC_DIR/$NAME.svg"
inkscape -w 64 -h 64 -e "$XDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg" inkscape -w 48 -h 48 -e "$XDPI_DIR/${NAME}_24dp.png" "$SRC_DIR/$NAME.svg"
inkscape -w 96 -h 96 -e "$XXDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg" inkscape -w 72 -h 72 -e "$XXDPI_DIR/${NAME}_24dp.png" "$SRC_DIR/$NAME.svg"
done inkscape -w 96 -h 96 -e "$XXXDPI_DIR/${NAME}_24dp.png" "$SRC_DIR/$NAME.svg"
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"
done 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" 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 do
echo $NAME echo $NAME
inkscape -w 96 -h 96 -e "$MDPI_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}_96px.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}_96px.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}_96px.png" "$SRC_DIR/$NAME.svg" inkscape -w 256 -h 256 -e "$XXDPI_DIR/${NAME}_96dp.png" "$SRC_DIR/$NAME.svg"
done done
for NAME in "create_key_robot" for NAME in "create_key_robot"

View File

@@ -3,11 +3,25 @@ apply plugin: 'witness'
dependencies { 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: 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:support-v4:21.0.3'
compile 'com.android.support:appcompat-v7: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:recyclerview-v7:21.0.3'
compile 'com.android.support:cardview-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:openpgp-api-lib')
compile project(':extern:openkeychain-api-lib') compile project(':extern:openkeychain-api-lib')
compile project(':extern:html-textview') compile project(':extern:html-textview')
@@ -20,16 +34,6 @@ dependencies {
compile project(':extern:KeybaseLib:Lib') compile project(':extern:KeybaseLib:Lib')
compile project(':extern:TokenAutoComplete:library') compile project(':extern:TokenAutoComplete:library')
compile project(':extern:safeslinger-exchange') 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 // Output of ./gradlew -q calculateChecksums
@@ -40,6 +44,16 @@ dependencyVerification {
'com.android.support:appcompat-v7:5dbeb5316d0a6027d646ae552804c3baa5e3bd53f7f33db50904d51505c8a0e5', 'com.android.support:appcompat-v7:5dbeb5316d0a6027d646ae552804c3baa5e3bd53f7f33db50904d51505c8a0e5',
'com.android.support:recyclerview-v7:e525ad3f33c84bb12b73d2dc975b55364a53f0f2d0697e043efba59ba73e22d2', 'com.android.support:recyclerview-v7:e525ad3f33c84bb12b73d2dc975b55364a53f0f2d0697e043efba59ba73e22d2',
'com.android.support:cardview-v7:45c48c2ab056bc7a8573970b10f8902742c5d443f180dae43c56557397ac39af', '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:openpgp-api-lib:b17bb282321351e4b00b4cd6422a57aadc13decae264019a88707bcb556439ea',
//'OpenKeychain.extern:openkeychain-api-lib:5f95f01c066069d4bde68992fd8da5faac21510d009b1fdae7a2e28e43e82cf4', //'OpenKeychain.extern:openkeychain-api-lib:5f95f01c066069d4bde68992fd8da5faac21510d009b1fdae7a2e28e43e82cf4',
//'OpenKeychain.extern:html-textview:b58e343cf4c145e91f888806d06a2a7770a9e9331a72f08cfcf1128db30dcff3', //'OpenKeychain.extern:html-textview:b58e343cf4c145e91f888806d06a2a7770a9e9331a72f08cfcf1128db30dcff3',
@@ -52,16 +66,6 @@ dependencyVerification {
//'OpenKeychain.extern.KeybaseLib:Lib:af9bff087148e0859430d0b99ece096c41b315c5dc1ed500a68580b9b0e5ab11', //'OpenKeychain.extern.KeybaseLib:Lib:af9bff087148e0859430d0b99ece096c41b315c5dc1ed500a68580b9b0e5ab11',
//'OpenKeychain.extern.TokenAutoComplete:library:40d4212a95e947efdb02f2ca66c95a27d49fba848471a6317eca2b9cc18e8780', //'OpenKeychain.extern.TokenAutoComplete:library:40d4212a95e947efdb02f2ca66c95a27d49fba848471a6317eca2b9cc18e8780',
//'OpenKeychain.extern:safeslinger-exchange:94a1ce68217af7499579a042758283b1530912c53241bdfa06d1a079a5ae3faf', //'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" /> <uses-permission android:name="android.permission.READ_PROFILE" />
<!-- android:allowBackup="false": Don't allow backup over adb backup or other apps! --> <!-- 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 <application
android:name=".KeychainApplication" android:name=".KeychainApplication"
tools:replace="android:allowBackup"
android:allowBackup="false" android:allowBackup="false"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher" 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_NAME = "OpenKeychain";
public static final String ACCOUNT_TYPE = PACKAGE_NAME + ".account"; 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 // as defined in http://tools.ietf.org/html/rfc3156, section 7
public static final String NFC_MIME = "application/pgp-keys"; 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 INTENT_PREFIX = PACKAGE_NAME + ".action.";
public static final String EXTRA_PREFIX = PACKAGE_NAME + "."; 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 int TEMPFILE_TTL = 24 * 60 * 60 * 1000; // 1 day
public static final String SAFESLINGER_SERVER = "safeslinger-openpgp.appspot.com"; 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) { static void brandGlowEffect(Context context, int brandColor) {
try { // no hack on Android 5
// terrible hack to brand the edge overscroll glow effect if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
// https://gist.github.com/menny/7878762#file-brandgloweffect_full-java try {
// terrible hack to brand the edge overscroll glow effect
// https://gist.github.com/menny/7878762#file-brandgloweffect_full-java
//glow //glow
int glowDrawableId = context.getResources().getIdentifier("overscroll_glow", "drawable", "android"); int glowDrawableId = context.getResources().getIdentifier("overscroll_glow", "drawable", "android");
Drawable androidGlow = context.getResources().getDrawable(glowDrawableId); Drawable androidGlow = context.getResources().getDrawable(glowDrawableId);
androidGlow.setColorFilter(brandColor, PorterDuff.Mode.SRC_IN); androidGlow.setColorFilter(brandColor, PorterDuff.Mode.SRC_IN);
//edge //edge
int edgeDrawableId = context.getResources().getIdentifier("overscroll_edge", "drawable", "android"); int edgeDrawableId = context.getResources().getIdentifier("overscroll_edge", "drawable", "android");
Drawable androidEdge = context.getResources().getDrawable(edgeDrawableId); Drawable androidEdge = context.getResources().getDrawable(edgeDrawableId);
androidEdge.setColorFilter(brandColor, PorterDuff.Mode.SRC_IN); androidEdge.setColorFilter(brandColor, PorterDuff.Mode.SRC_IN);
} catch (Resources.NotFoundException e) { } catch (Resources.NotFoundException e) {
// no hack on Android 5 }
} }
} }
} }

View File

@@ -38,6 +38,8 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/** Represent the result of an operation. /** Represent the result of an operation.
* *
@@ -51,6 +53,56 @@ import java.util.List;
public abstract class OperationResult implements Parcelable { public abstract class OperationResult implements Parcelable {
public static final String EXTRA_RESULT = "operation_result"; 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: /** Holds the overall result, the number specifying varying degrees of success:
* - The first bit is 0 on overall success, 1 on overall failure * - 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; public static final int RESULT_WARNINGS = 4;
/// A list of log entries tied to the operation result. /// A list of log entries tied to the operation result.
final OperationLog mLog; protected OperationLog mLog;
public OperationResult(int result, OperationLog log) { public OperationResult(int result, OperationLog log) {
mResult = result; mResult = result;
@@ -74,8 +126,11 @@ public abstract class OperationResult implements Parcelable {
public OperationResult(Parcel source) { public OperationResult(Parcel source) {
mResult = source.readInt(); mResult = source.readInt();
mLog = new OperationLog(); long mostSig = source.readLong();
mLog.addAll(source.createTypedArrayList(LogEntryParcel.CREATOR)); 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() { 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_URL (LogLevel.ERROR, R.string.msg_lv_fetch_error_url),
MSG_LV_FETCH_ERROR_IO (LogLevel.ERROR, R.string.msg_lv_fetch_error_io), 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; public final int mMsgId;
@@ -755,9 +816,11 @@ public abstract class OperationResult implements Parcelable {
@Override @Override
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mResult); dest.writeInt(mResult);
if (mLog != null) { // Get a ticket for our log.
dest.writeTypedList(mLog.toList()); 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> { 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[]{ private static final int[] PREFERRED_HASH_ALGORITHMS = new int[]{
HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA512,
HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA384,
HashAlgorithmTags.SHA224,
HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA256,
HashAlgorithmTags.SHA224,
HashAlgorithmTags.RIPEMD160 HashAlgorithmTags.RIPEMD160
}; };
private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[]{ 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_S2K_COUNT = 0x90;
private static final int SECRET_KEY_ENCRYPTOR_HASH_ALGO = HashAlgorithmTags.SHA256; 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_ENCRYPTOR_SYMMETRIC_ALGO = SymmetricKeyAlgorithmTags.AES_256;
private static final int SECRET_KEY_SIGNATURE_HASH_ALGO = HashAlgorithmTags.SHA256;
public PgpKeyOperation(Progressable progress) { public PgpKeyOperation(Progressable progress) {
super(); super();
@@ -1025,7 +1026,7 @@ public class PgpKeyOperation {
// add packet with EMPTY notation data (updates old one, but will be stripped later) // add packet with EMPTY notation data (updates old one, but will be stripped later)
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512) masterPrivateKey.getPublicKeyPacket().getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
{ // set subpackets { // set subpackets
@@ -1051,7 +1052,7 @@ public class PgpKeyOperation {
// add packet with "pin" notation data // add packet with "pin" notation data
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512) masterPrivateKey.getPublicKeyPacket().getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
{ // set subpackets { // set subpackets
@@ -1236,7 +1237,7 @@ public class PgpKeyOperation {
int flags, long expiry) int flags, long expiry)
throws IOException, PGPException, SignatureException { throws IOException, PGPException, SignatureException {
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512) masterPrivateKey.getPublicKeyPacket().getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
@@ -1279,7 +1280,7 @@ public class PgpKeyOperation {
PGPUserAttributeSubpacketVector vector) PGPUserAttributeSubpacketVector vector)
throws IOException, PGPException, SignatureException { throws IOException, PGPException, SignatureException {
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512) masterPrivateKey.getPublicKeyPacket().getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
@@ -1298,7 +1299,7 @@ public class PgpKeyOperation {
PGPPrivateKey masterPrivateKey, PGPPublicKey pKey, String userId) PGPPrivateKey masterPrivateKey, PGPPublicKey pKey, String userId)
throws IOException, PGPException, SignatureException { throws IOException, PGPException, SignatureException {
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512) masterPrivateKey.getPublicKeyPacket().getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator();
@@ -1312,7 +1313,7 @@ public class PgpKeyOperation {
PGPPublicKey masterPublicKey, PGPPrivateKey masterPrivateKey, PGPPublicKey pKey) PGPPublicKey masterPublicKey, PGPPrivateKey masterPrivateKey, PGPPublicKey pKey)
throws IOException, PGPException, SignatureException { throws IOException, PGPException, SignatureException {
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA512) masterPublicKey.getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator();
@@ -1356,7 +1357,7 @@ public class PgpKeyOperation {
PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator();
subHashedPacketsGen.setSignatureCreationTime(false, creationTime); subHashedPacketsGen.setSignatureCreationTime(false, creationTime);
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
pKey.getAlgorithm(), HashAlgorithmTags.SHA512) pKey.getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
sGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey); sGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey);
@@ -1377,7 +1378,7 @@ public class PgpKeyOperation {
} }
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA512) masterPublicKey.getAlgorithm(), SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
sGen.init(PGPSignature.SUBKEY_BINDING, masterPrivateKey); 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_NAME = "name";
public static final String EXTRA_EMAIL = "email"; public static final String EXTRA_EMAIL = "email";
public static final int FRAG_ACTION_START = 0; public static enum FragAction {
public static final int FRAG_ACTION_TO_RIGHT = 1; START,
public static final int FRAG_ACTION_TO_LEFT = 2; TO_RIGHT,
TO_LEFT
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@@ -42,7 +44,7 @@ public class CreateKeyActivity extends BaseActivity {
getIntent().getStringExtra(EXTRA_NAME), getIntent().getStringExtra(EXTRA_NAME),
getIntent().getStringExtra(EXTRA_EMAIL) getIntent().getStringExtra(EXTRA_EMAIL)
); );
loadFragment(null, frag, FRAG_ACTION_START); loadFragment(null, frag, FragAction.START);
} }
@Override @Override
@@ -50,7 +52,7 @@ public class CreateKeyActivity extends BaseActivity {
setContentView(R.layout.create_key_activity); 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, // However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else // then we don't need to do anything and should return or else
// we could end up with overlapping fragments. // we could end up with overlapping fragments.
@@ -63,15 +65,15 @@ public class CreateKeyActivity extends BaseActivity {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
switch (action) { switch (action) {
case FRAG_ACTION_START: case START:
transaction.setCustomAnimations(0, 0); transaction.setCustomAnimations(0, 0);
transaction.replace(R.id.create_key_fragment_container, fragment) transaction.replace(R.id.create_key_fragment_container, fragment)
.commitAllowingStateLoss(); .commitAllowingStateLoss();
break; break;
case FRAG_ACTION_TO_LEFT: case TO_LEFT:
getSupportFragmentManager().popBackStackImmediate(); getSupportFragmentManager().popBackStackImmediate();
break; 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, 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); R.anim.frag_slide_in_from_left, R.anim.frag_slide_out_to_right);
transaction.addToBackStack(null); 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;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel; 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.Log;
import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.Preferences;
@@ -117,7 +118,7 @@ public class CreateKeyFinalFragment extends Fragment {
mBackButton.setOnClickListener(new View.OnClickListener() { mBackButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { 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 android.widget.EditText;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
import org.sufficientlysecure.keychain.util.ContactHelper; import org.sufficientlysecure.keychain.util.ContactHelper;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@@ -161,7 +162,7 @@ public class CreateKeyInputFragment extends Fragment {
); );
hideKeyboard(); 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.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
public abstract class DecryptFragment extends Fragment { public abstract class DecryptFragment extends Fragment {
private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006; private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
@@ -141,16 +142,16 @@ public abstract class DecryptFragment extends Fragment {
if (signatureResult.isSignatureOnly()) { if (signatureResult.isSignatureOnly()) {
mEncryptionText.setText(R.string.decrypt_result_not_encrypted); 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 { } else {
mEncryptionText.setText(R.string.decrypt_result_encrypted); 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()) { switch (signatureResult.getStatus()) {
case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: {
mSignatureText.setText(R.string.decrypt_result_signature_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); setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId); setShowAction(mSignatureKeyId);
@@ -161,7 +162,7 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: {
mSignatureText.setText(R.string.decrypt_result_signature_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); setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId); setShowAction(mSignatureKeyId);
@@ -172,11 +173,11 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_KEY_MISSING: { case OpenPgpSignatureResult.SIGNATURE_KEY_MISSING: {
mSignatureText.setText(R.string.decrypt_result_signature_missing_key); 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); setSignatureLayoutVisibility(View.VISIBLE);
mSignatureAction.setText(R.string.decrypt_result_action_Lookup); 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() { mSignatureLayout.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@@ -190,7 +191,7 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED: { case OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED: {
mSignatureText.setText(R.string.decrypt_result_signature_expired_key); 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); setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId); setShowAction(mSignatureKeyId);
@@ -201,7 +202,7 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED: { case OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED: {
mSignatureText.setText(R.string.decrypt_result_signature_revoked_key); 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); setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId); setShowAction(mSignatureKeyId);
@@ -212,7 +213,7 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_ERROR: { case OpenPgpSignatureResult.SIGNATURE_ERROR: {
mSignatureText.setText(R.string.decrypt_result_invalid_signature); 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); setSignatureLayoutVisibility(View.GONE);
@@ -224,9 +225,9 @@ public abstract class DecryptFragment extends Fragment {
setSignatureLayoutVisibility(View.GONE); setSignatureLayoutVisibility(View.GONE);
mSignatureText.setText(R.string.decrypt_result_no_signature); 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); mEncryptionText.setText(R.string.decrypt_result_encrypted);
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, KeyFormattingUtils.STATE_ENCRYPTED); KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED);
valid = true; 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_START = 0;
public static final int TAB_FAQ = 1; public static final int TAB_FAQ = 1;
public static final int TAB_WOT = 2; public static final int TAB_TRUST = 2;
public static final int TAB_NFC = 3; public static final int TAB_CHANGELOG = 3;
public static final int TAB_CHANGELOG = 4; public static final int TAB_ABOUT = 4;
public static final int TAB_ABOUT = 5;
ViewPager mViewPager; ViewPager mViewPager;
private PagerTabStripAdapter mTabsAdapter; private PagerTabStripAdapter mTabsAdapter;
@@ -69,21 +68,11 @@ public class HelpActivity extends BaseActivity {
mTabsAdapter.addTab(HelpHtmlFragment.class, startBundle, mTabsAdapter.addTab(HelpHtmlFragment.class, startBundle,
getString(R.string.help_tab_start)); 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(); 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, mTabsAdapter.addTab(HelpHtmlFragment.class, wotBundle,
getString(R.string.help_tab_wot)); 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(); Bundle changelogBundle = new Bundle();
changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog); changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog);
mTabsAdapter.addTab(HelpHtmlFragment.class, changelogBundle, 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.dialog.DeleteKeyDialogFragment;
import org.sufficientlysecure.keychain.ui.util.Highlighter; import org.sufficientlysecure.keychain.ui.util.Highlighter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; 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.Notify;
import org.sufficientlysecure.keychain.util.ExportHelper; import org.sufficientlysecure.keychain.util.ExportHelper;
import org.sufficientlysecure.keychain.util.FabContainer; import org.sufficientlysecure.keychain.util.FabContainer;
@@ -77,7 +78,6 @@ import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.Preferences;
import java.io.IOException; import java.io.IOException;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
@@ -268,7 +268,7 @@ public class KeyListFragment extends LoaderFragment
KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID,
KeyRings.USER_ID, KeyRings.USER_ID,
KeyRings.IS_REVOKED, KeyRings.IS_REVOKED,
KeyRings.EXPIRY, KeyRings.IS_EXPIRED,
KeyRings.VERIFIED, KeyRings.VERIFIED,
KeyRings.HAS_ANY_SECRET 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_MASTER_KEY_ID = 1;
static final int INDEX_USER_ID = 2; static final int INDEX_USER_ID = 2;
static final int INDEX_IS_REVOKED = 3; 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_VERIFIED = 5;
static final int INDEX_HAS_ANY_SECRET = 6; 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); long masterKeyId = cursor.getLong(INDEX_MASTER_KEY_ID);
boolean isSecret = cursor.getInt(INDEX_HAS_ANY_SECRET) != 0; boolean isSecret = cursor.getInt(INDEX_HAS_ANY_SECRET) != 0;
boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0; boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
boolean isExpired = !cursor.isNull(INDEX_EXPIRY) boolean isExpired = cursor.getInt(INDEX_IS_EXPIRED) != 0;
&& new Date(cursor.getLong(INDEX_EXPIRY) * 1000).before(new Date());
boolean isVerified = cursor.getInt(INDEX_VERIFIED) > 0; boolean isVerified = cursor.getInt(INDEX_VERIFIED) > 0;
h.mMasterKeyId = masterKeyId; h.mMasterKeyId = masterKeyId;
// Note: order is important! // Note: order is important!
if (isRevoked) { 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.mStatus.setVisibility(View.VISIBLE);
h.mSlinger.setVisibility(View.GONE); h.mSlinger.setVisibility(View.GONE);
h.mMainUserId.setTextColor(context.getResources().getColor(R.color.bg_gray)); h.mMainUserId.setTextColor(context.getResources().getColor(R.color.bg_gray));
h.mMainUserIdRest.setTextColor(context.getResources().getColor(R.color.bg_gray)); h.mMainUserIdRest.setTextColor(context.getResources().getColor(R.color.bg_gray));
} else if (isExpired) { } 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.mStatus.setVisibility(View.VISIBLE);
h.mSlinger.setVisibility(View.GONE); h.mSlinger.setVisibility(View.GONE);
h.mMainUserId.setTextColor(context.getResources().getColor(R.color.bg_gray)); h.mMainUserId.setTextColor(context.getResources().getColor(R.color.bg_gray));
@@ -735,10 +734,10 @@ public class KeyListFragment extends LoaderFragment
} else { } else {
// this is a public key - show if it's verified // this is a public key - show if it's verified
if (isVerified) { if (isVerified) {
KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, KeyFormattingUtils.STATE_VERIFIED); KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, State.VERIFIED);
h.mStatus.setVisibility(View.VISIBLE); h.mStatus.setVisibility(View.VISIBLE);
} else { } else {
KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, KeyFormattingUtils.STATE_UNVERIFIED); KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, State.UNVERIFIED);
h.mStatus.setVisibility(View.VISIBLE); h.mStatus.setVisibility(View.VISIBLE);
} }
h.mSlinger.setVisibility(View.GONE); h.mSlinger.setVisibility(View.GONE);

View File

@@ -22,9 +22,13 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcel;
import android.support.v4.app.ListFragment; import android.support.v4.app.ListFragment;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
@@ -33,11 +37,19 @@ import android.widget.ArrayAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogLevel; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogLevel;
import org.sufficientlysecure.keychain.operations.results.OperationResult.SubLogEntryParcel; 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 { public class LogDisplayFragment extends ListFragment implements OnItemClickListener {
@@ -46,6 +58,12 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
OperationResult mResult; OperationResult mResult;
public static final String EXTRA_RESULT = "log"; public static final String EXTRA_RESULT = "log";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override @Override
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
@@ -70,6 +88,183 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
getListView().setFastScrollEnabled(true); getListView().setFastScrollEnabled(true);
getListView().setDividerHeight(0); 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 @Override
@@ -109,7 +304,7 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
mSecondImg = secondImg; mSecondImg = secondImg;
} }
} }
// Check if convertView.setPadding is redundant
@Override @Override
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
LogEntryParcel entry = getItem(position); LogEntryParcel entry = getItem(position);
@@ -132,7 +327,6 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
if (entry instanceof SubLogEntryParcel) { if (entry instanceof SubLogEntryParcel) {
ih.mSub.setVisibility(View.VISIBLE); ih.mSub.setVisibility(View.VISIBLE);
convertView.setClickable(false); convertView.setClickable(false);
convertView.setPadding((entry.mIndent) * dipFactor, 0, 0, 0); convertView.setPadding((entry.mIndent) * dipFactor, 0, 0, 0);
OperationResult result = ((SubLogEntryParcel) entry).getSubResult(); 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.compatibility.DialogFragmentWorkaround;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; 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.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
@@ -149,6 +150,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
public static class PassphraseDialogFragment extends DialogFragment implements TextView.OnEditorActionListener { public static class PassphraseDialogFragment extends DialogFragment implements TextView.OnEditorActionListener {
private EditText mPassphraseEditText; private EditText mPassphraseEditText;
private TextView mPassphraseText;
private View mInput, mProgress; private View mInput, mProgress;
private CanonicalizedSecretKeyRing mSecretRing = null; 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 // 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 // hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay
ContextThemeWrapper theme = new ContextThemeWrapper(activity, ContextThemeWrapper theme = new ContextThemeWrapper(activity,
R.style.Theme_AppCompat_Light); R.style.Theme_AppCompat_Light_Dialog);
mSubKeyId = getArguments().getLong(EXTRA_SUBKEY_ID); mSubKeyId = getArguments().getLong(EXTRA_SUBKEY_ID);
mServiceIntent = getArguments().getParcelable(EXTRA_DATA); mServiceIntent = getArguments().getParcelable(EXTRA_DATA);
@@ -176,13 +178,30 @@ public class PassphraseDialogActivity extends FragmentActivity {
alert.setTitle(R.string.title_unlock); 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; String userId;
CanonicalizedSecretKey.SecretKeyType keyType = CanonicalizedSecretKey.SecretKeyType.PASSPHRASE; CanonicalizedSecretKey.SecretKeyType keyType = CanonicalizedSecretKey.SecretKeyType.PASSPHRASE;
String message;
if (mSubKeyId == Constants.key.symmetric || mSubKeyId == Constants.key.none) { 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 { } else {
String message;
try { try {
ProviderHelper helper = new ProviderHelper(activity); ProviderHelper helper = new ProviderHelper(activity);
mSecretRing = helper.getCanonicalizedSecretKeyRing( 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 // above can't be statically verified to have been set in all cases because
// the catch clause doesn't return. // the catch clause doesn't return.
try { 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) { } catch (PgpKeyNotFoundException e) {
userId = null; userId = null;
} }
@@ -231,33 +256,16 @@ public class PassphraseDialogActivity extends FragmentActivity {
alert.setCancelable(false); alert.setCancelable(false);
return alert.create(); return alert.create();
} }
alert.setMessage(message);
} }
LayoutInflater inflater = LayoutInflater.from(theme); mPassphraseText.setText(message);
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();
}
});
if (keyType == CanonicalizedSecretKey.SecretKeyType.PATTERN) { if (keyType == CanonicalizedSecretKey.SecretKeyType.PATTERN) {
// start pattern dialog and show progress circle here... // start pattern dialog and show progress circle here...
// Intent patternActivity = new Intent(getActivity(), LockPatternActivity.class); // Intent patternActivity = new Intent(getActivity(), LockPatternActivity.class);
// patternActivity.putExtra(LockPatternActivity.EXTRA_PATTERN, "123"); // patternActivity.putExtra(LockPatternActivity.EXTRA_PATTERN, "123");
// startActivityForResult(patternActivity, REQUEST_CODE_ENTER_PATTERN); // startActivityForResult(patternActivity, REQUEST_CODE_ENTER_PATTERN);
mInput.setVisibility(View.GONE); mInput.setVisibility(View.INVISIBLE);
mProgress.setVisibility(View.VISIBLE); mProgress.setVisibility(View.VISIBLE);
} else { } else {
// Hack to open keyboard. // Hack to open keyboard.
@@ -325,7 +333,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
return; return;
} }
mInput.setVisibility(View.GONE); mInput.setVisibility(View.INVISIBLE);
mProgress.setVisibility(View.VISIBLE); mProgress.setVisibility(View.VISIBLE);
positive.setEnabled(false); positive.setEnabled(false);
@@ -367,7 +375,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
mPassphraseEditText.setText(""); mPassphraseEditText.setText("");
mPassphraseEditText.setError(getString(R.string.wrong_passphrase)); mPassphraseEditText.setError(getString(R.string.wrong_passphrase));
mInput.setVisibility(View.VISIBLE); mInput.setVisibility(View.VISIBLE);
mProgress.setVisibility(View.GONE); mProgress.setVisibility(View.INVISIBLE);
positive.setEnabled(true); positive.setEnabled(true);
return; 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.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter; import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import java.util.Vector; import java.util.Vector;
@@ -136,7 +137,7 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T
mSearchView.setId(SEARCH_ID); mSearchView.setId(SEARCH_ID);
mSearchView.setHint(R.string.menu_search); mSearchView.setHint(R.string.menu_search);
mSearchView.setCompoundDrawablesWithIntrinsicBounds( 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( linearLayout.addView(mSearchView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 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 // Check if key is viable for our purposes
if (cursor.getInt(mIndexHasEncrypt) == 0) { if (cursor.getInt(mIndexHasEncrypt) == 0) {
h.statusIcon.setVisibility(View.VISIBLE); h.statusIcon.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, KeyFormattingUtils.STATE_UNAVAILABLE); KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, State.UNAVAILABLE);
enabled = false; enabled = false;
} else if (cursor.getInt(mIndexIsVerified) != 0) { } else if (cursor.getInt(mIndexIsVerified) != 0) {
h.statusIcon.setVisibility(View.VISIBLE); h.statusIcon.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, KeyFormattingUtils.STATE_VERIFIED); KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, State.VERIFIED);
enabled = true; enabled = true;
} else { } else {
h.statusIcon.setVisibility(View.VISIBLE); h.statusIcon.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, KeyFormattingUtils.STATE_UNVERIFIED); KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, State.UNVERIFIED);
enabled = true; 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.linked.LinkedIdWizard;
import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; 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.Notify;
import org.sufficientlysecure.keychain.ui.util.QrCodeUtils; 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.ContactHelper;
import org.sufficientlysecure.keychain.util.ExportHelper; import org.sufficientlysecure.keychain.util.ExportHelper;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.Preferences;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
public class ViewKeyActivity extends BaseActivity implements public class ViewKeyActivity extends BaseActivity implements
@@ -106,7 +105,7 @@ public class ViewKeyActivity extends BaseActivity implements
private ImageButton mActionEncryptText; private ImageButton mActionEncryptText;
private ImageButton mActionNfc; private ImageButton mActionNfc;
private FloatingActionButton mFab; private FloatingActionButton mFab;
private AspectRatioImageView mPhoto; private ImageView mPhoto;
private ImageView mQrCode; private ImageView mQrCode;
private CardView mQrCodeLayout; private CardView mQrCodeLayout;
@@ -122,6 +121,9 @@ public class ViewKeyActivity extends BaseActivity implements
private boolean mIsSecret = false; private boolean mIsSecret = false;
private boolean mHasEncrypt = false; private boolean mHasEncrypt = false;
private boolean mIsVerified = false; private boolean mIsVerified = false;
private boolean mIsRevoked = false;
private boolean mIsExpired = false;
private MenuItem mRefreshItem; private MenuItem mRefreshItem;
private boolean mIsRefreshing; private boolean mIsRefreshing;
private Animation mRotate, mRotateSpin; private Animation mRotate, mRotateSpin;
@@ -148,7 +150,7 @@ public class ViewKeyActivity extends BaseActivity implements
mActionEncryptText = (ImageButton) findViewById(R.id.view_key_action_encrypt_text); mActionEncryptText = (ImageButton) findViewById(R.id.view_key_action_encrypt_text);
mActionNfc = (ImageButton) findViewById(R.id.view_key_action_nfc); mActionNfc = (ImageButton) findViewById(R.id.view_key_action_nfc);
mFab = (FloatingActionButton) findViewById(R.id.fab); 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); mQrCode = (ImageView) findViewById(R.id.view_key_qr_code);
mQrCodeLayout = (CardView) findViewById(R.id.view_key_qr_code_layout); 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.setRepeatCount(Animation.INFINITE);
mRotate.setAnimationListener(new Animation.AnimationListener() { mRotate.setAnimationListener(new Animation.AnimationListener() {
@Override @Override
@@ -358,7 +360,7 @@ public class ViewKeyActivity extends BaseActivity implements
addLinked.setVisible(mIsSecret); addLinked.setVisible(mIsSecret);
MenuItem certifyFingerprint = menu.findItem(R.id.menu_key_view_certify_fingerprint); MenuItem certifyFingerprint = menu.findItem(R.id.menu_key_view_certify_fingerprint);
certifyFingerprint.setVisible(!mIsSecret && !mIsVerified); certifyFingerprint.setVisible(!mIsSecret && !mIsVerified && !mIsExpired && !mIsRevoked);
return true; return true;
} }
@@ -409,12 +411,12 @@ public class ViewKeyActivity extends BaseActivity implements
private void certifyImmediate() { private void certifyImmediate() {
Intent intent = new Intent(this, CertifyKeyActivity.class); 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); startCertifyIntent(intent);
} }
private void startCertifyIntent (Intent intent) { private void startCertifyIntent(Intent intent) {
// Message is received after signing is done in KeychainIntentService // Message is received after signing is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this) { KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this) {
public void handleMessage(Message message) { public void handleMessage(Message message) {
@@ -761,7 +763,7 @@ public class ViewKeyActivity extends BaseActivity implements
KeychainContract.KeyRings.MASTER_KEY_ID, KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.KeyRings.USER_ID, KeychainContract.KeyRings.USER_ID,
KeychainContract.KeyRings.IS_REVOKED, KeychainContract.KeyRings.IS_REVOKED,
KeychainContract.KeyRings.EXPIRY, KeychainContract.KeyRings.IS_EXPIRED,
KeychainContract.KeyRings.VERIFIED, KeychainContract.KeyRings.VERIFIED,
KeychainContract.KeyRings.HAS_ANY_SECRET, KeychainContract.KeyRings.HAS_ANY_SECRET,
KeychainContract.KeyRings.FINGERPRINT, 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_MASTER_KEY_ID = 1;
static final int INDEX_USER_ID = 2; static final int INDEX_USER_ID = 2;
static final int INDEX_IS_REVOKED = 3; 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_VERIFIED = 5;
static final int INDEX_HAS_ANY_SECRET = 6; static final int INDEX_HAS_ANY_SECRET = 6;
static final int INDEX_FINGERPRINT = 7; static final int INDEX_FINGERPRINT = 7;
@@ -820,9 +822,8 @@ public class ViewKeyActivity extends BaseActivity implements
mIsSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0; mIsSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
mHasEncrypt = data.getInt(INDEX_HAS_ENCRYPT) != 0; mHasEncrypt = data.getInt(INDEX_HAS_ENCRYPT) != 0;
boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0; mIsRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
boolean isExpired = !data.isNull(INDEX_EXPIRY) mIsExpired = data.getInt(INDEX_IS_EXPIRED) != 0;
&& new Date(data.getLong(INDEX_EXPIRY) * 1000).before(new Date());
mIsVerified = data.getInt(INDEX_VERIFIED) > 0; mIsVerified = data.getInt(INDEX_VERIFIED) > 0;
// if the refresh animation isn't playing // 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 // this is done at the end of the animation otherwise
} }
AsyncTask<String, Void, Bitmap> photoTask = AsyncTask<Long, Void, Bitmap> photoTask =
new AsyncTask<String, Void, Bitmap>() { new AsyncTask<Long, Void, Bitmap>() {
protected Bitmap doInBackground(String... fingerprint) { protected Bitmap doInBackground(Long... mMasterKeyId) {
return ContactHelper.photoFromFingerprint(getContentResolver(), fingerprint[0]); return ContactHelper.loadPhotoByMasterKeyId(getContentResolver(), mMasterKeyId[0], true);
} }
protected void onPostExecute(Bitmap photo) { protected void onPostExecute(Bitmap photo) {
@@ -846,11 +847,11 @@ public class ViewKeyActivity extends BaseActivity implements
// Note: order is important // Note: order is important
int color; int color;
if (isRevoked) { if (mIsRevoked) {
mStatusText.setText(R.string.view_key_revoked); mStatusText.setText(R.string.view_key_revoked);
mStatusImage.setVisibility(View.VISIBLE); mStatusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText, 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); color = getResources().getColor(R.color.android_red_light);
mActionEncryptFile.setVisibility(View.GONE); mActionEncryptFile.setVisibility(View.GONE);
@@ -858,7 +859,7 @@ public class ViewKeyActivity extends BaseActivity implements
mActionNfc.setVisibility(View.GONE); mActionNfc.setVisibility(View.GONE);
mFab.setVisibility(View.GONE); mFab.setVisibility(View.GONE);
mQrCodeLayout.setVisibility(View.GONE); mQrCodeLayout.setVisibility(View.GONE);
} else if (isExpired) { } else if (mIsExpired) {
if (mIsSecret) { if (mIsSecret) {
mStatusText.setText(R.string.view_key_expired_secret); mStatusText.setText(R.string.view_key_expired_secret);
} else { } else {
@@ -866,7 +867,7 @@ public class ViewKeyActivity extends BaseActivity implements
} }
mStatusImage.setVisibility(View.VISIBLE); mStatusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText, 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); color = getResources().getColor(R.color.android_red_light);
mActionEncryptFile.setVisibility(View.GONE); mActionEncryptFile.setVisibility(View.GONE);
@@ -879,10 +880,10 @@ public class ViewKeyActivity extends BaseActivity implements
mStatusImage.setVisibility(View.GONE); mStatusImage.setVisibility(View.GONE);
color = getResources().getColor(R.color.primary); color = getResources().getColor(R.color.primary);
// reload qr code only if the fingerprint changed // reload qr code only if the fingerprint changed
if ( !mFingerprint.equals(oldFingerprint)) { if (!mFingerprint.equals(oldFingerprint)) {
loadQrCode(mFingerprint); loadQrCode(mFingerprint);
} }
photoTask.execute(mFingerprint); photoTask.execute(mMasterKeyId);
mQrCodeLayout.setVisibility(View.VISIBLE); mQrCodeLayout.setVisibility(View.VISIBLE);
// and place leftOf qr code // and place leftOf qr code
@@ -926,16 +927,16 @@ public class ViewKeyActivity extends BaseActivity implements
mStatusText.setText(R.string.view_key_verified); mStatusText.setText(R.string.view_key_verified);
mStatusImage.setVisibility(View.VISIBLE); mStatusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText, KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
KeyFormattingUtils.STATE_VERIFIED, R.color.icons, true); State.VERIFIED, R.color.icons, true);
color = getResources().getColor(R.color.primary); color = getResources().getColor(R.color.primary);
photoTask.execute(mFingerprint); photoTask.execute(mMasterKeyId);
mFab.setVisibility(View.GONE); mFab.setVisibility(View.GONE);
} else { } else {
mStatusText.setText(R.string.view_key_unverified); mStatusText.setText(R.string.view_key_unverified);
mStatusImage.setVisibility(View.VISIBLE); mStatusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText, 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); color = getResources().getColor(R.color.android_orange_light);
mFab.setVisibility(View.VISIBLE); mFab.setVisibility(View.VISIBLE);
@@ -943,27 +944,21 @@ public class ViewKeyActivity extends BaseActivity implements
} }
if (mPreviousColor == 0 || mPreviousColor == color) { if (mPreviousColor == 0 || mPreviousColor == color) {
mToolbar.setBackgroundColor(color);
mStatusBar.setBackgroundColor(color); mStatusBar.setBackgroundColor(color);
mBigToolbar.setBackgroundColor(color); mBigToolbar.setBackgroundColor(color);
mPreviousColor = color; mPreviousColor = color;
} else { } else {
ObjectAnimator colorFade1 = ObjectAnimator colorFade1 =
ObjectAnimator.ofObject(mToolbar, "backgroundColor",
new ArgbEvaluator(), mPreviousColor, color);
ObjectAnimator colorFade2 =
ObjectAnimator.ofObject(mStatusBar, "backgroundColor", ObjectAnimator.ofObject(mStatusBar, "backgroundColor",
new ArgbEvaluator(), mPreviousColor, color); new ArgbEvaluator(), mPreviousColor, color);
ObjectAnimator colorFade3 = ObjectAnimator colorFade2 =
ObjectAnimator.ofObject(mBigToolbar, "backgroundColor", ObjectAnimator.ofObject(mBigToolbar, "backgroundColor",
new ArgbEvaluator(), mPreviousColor, color); new ArgbEvaluator(), mPreviousColor, color);
colorFade1.setDuration(1200); colorFade1.setDuration(1200);
colorFade2.setDuration(1200); colorFade2.setDuration(1200);
colorFade3.setDuration(1200);
colorFade1.start(); colorFade1.start();
colorFade2.start(); colorFade2.start();
colorFade3.start();
mPreviousColor = color; 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.ExportHelper;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import java.util.Date;
public class ViewKeyAdvActivity extends BaseActivity implements public class ViewKeyAdvActivity extends BaseActivity implements
LoaderManager.LoaderCallbacks<Cursor> { LoaderManager.LoaderCallbacks<Cursor> {
@@ -159,7 +157,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
KeychainContract.KeyRings.MASTER_KEY_ID, KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.KeyRings.USER_ID, KeychainContract.KeyRings.USER_ID,
KeychainContract.KeyRings.IS_REVOKED, KeychainContract.KeyRings.IS_REVOKED,
KeychainContract.KeyRings.EXPIRY, KeychainContract.KeyRings.IS_EXPIRED,
KeychainContract.KeyRings.VERIFIED, KeychainContract.KeyRings.VERIFIED,
KeychainContract.KeyRings.HAS_ANY_SECRET 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_MASTER_KEY_ID = 1;
static final int INDEX_USER_ID = 2; static final int INDEX_USER_ID = 2;
static final int INDEX_IS_REVOKED = 3; 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_VERIFIED = 5;
static final int INDEX_HAS_ANY_SECRET = 6; 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 isSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0; boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
boolean isExpired = !data.isNull(INDEX_EXPIRY) boolean isExpired = data.getInt(INDEX_IS_EXPIRED) != 0;
&& new Date(data.getLong(INDEX_EXPIRY) * 1000).before(new Date());
boolean isVerified = data.getInt(INDEX_VERIFIED) > 0; boolean isVerified = data.getInt(INDEX_VERIFIED) > 0;
// Note: order is important // Note: order is important

View File

@@ -260,7 +260,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
static final String[] UNIFIED_PROJECTION = new String[]{ static final String[] UNIFIED_PROJECTION = new String[]{
KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET, KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET,
KeyRings.USER_ID, KeyRings.FINGERPRINT, 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; 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_ALGORITHM = 5;
static final int INDEX_UNIFIED_KEY_SIZE = 6; static final int INDEX_UNIFIED_KEY_SIZE = 6;
static final int INDEX_UNIFIED_CREATION = 7; 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) { public Loader<Cursor> onCreateLoader(int id, Bundle args) {
setContentShown(false); setContentShown(false);

View File

@@ -114,12 +114,12 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
static final String[] UNIFIED_PROJECTION = new String[]{ static final String[] UNIFIED_PROJECTION = new String[]{
KeyRings._ID, KeyRings.MASTER_KEY_ID, 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_MASTER_KEY_ID = 1;
static final int INDEX_UNIFIED_HAS_ANY_SECRET = 2; static final int INDEX_UNIFIED_HAS_ANY_SECRET = 2;
static final int INDEX_UNIFIED_IS_REVOKED = 3; 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; static final int INDEX_UNIFIED_HAS_ENCRYPT = 5;
public Loader<Cursor> onCreateLoader(int id, Bundle args) { 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[]{ 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 KeyRings.HAS_ANY_SECRET, KeyRings.VERIFIED
}; };
static final int INDEX_TRUST_FINGERPRINT = 1; static final int INDEX_TRUST_FINGERPRINT = 1;
static final int INDEX_TRUST_IS_REVOKED = 2; 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_UNIFIED_HAS_ANY_SECRET = 4;
static final int INDEX_VERIFIED = 5; static final int INDEX_VERIFIED = 5;
@@ -169,8 +169,7 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
nothingSpecial = false; nothingSpecial = false;
} else { } else {
Date expiryDate = new Date(data.getLong(INDEX_TRUST_EXPIRY) * 1000); if (data.getInt(INDEX_TRUST_IS_EXPIRED) != 0) {
if (!data.isNull(INDEX_TRUST_EXPIRY) && expiryDate.before(new Date())) {
// if expired, dont trust it! // if expired, dont trust it!
message.append(getString(R.string.key_trust_expired)). 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.FormattingUtils;
import org.sufficientlysecure.keychain.ui.util.Highlighter; import org.sufficientlysecure.keychain.ui.util.Highlighter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@@ -175,9 +176,9 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
} }
if (entry.isRevoked()) { 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()) { } 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()) { 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.pgp.linked.resources.DnsResource;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; 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.linked.LinkedIdViewFragment;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import java.io.IOException; import java.io.IOException;
import java.util.WeakHashMap; import java.util.WeakHashMap;
@@ -66,15 +66,15 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {
switch (isVerified) { switch (isVerified) {
case Certs.VERIFIED_SECRET: case Certs.VERIFIED_SECRET:
KeyFormattingUtils.setStatusImage(mContext, holder.vVerified, KeyFormattingUtils.setStatusImage(mContext, holder.vVerified,
null, KeyFormattingUtils.STATE_VERIFIED, KeyFormattingUtils.DEFAULT_COLOR); null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break; break;
case Certs.VERIFIED_SELF: case Certs.VERIFIED_SELF:
KeyFormattingUtils.setStatusImage(mContext, holder.vVerified, KeyFormattingUtils.setStatusImage(mContext, holder.vVerified,
null, KeyFormattingUtils.STATE_UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR); null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break; break;
default: default:
KeyFormattingUtils.setStatusImage(mContext, holder.vVerified, KeyFormattingUtils.setStatusImage(mContext, holder.vVerified,
null, KeyFormattingUtils.STATE_INVALID, KeyFormattingUtils.DEFAULT_COLOR); null, State.INVALID, KeyFormattingUtils.DEFAULT_COLOR);
break; break;
} }

View File

@@ -33,6 +33,7 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.ui.util.Highlighter; import org.sufficientlysecure.keychain.ui.util.Highlighter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; 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; boolean enabled;
if (cursor.getInt(mIndexIsRevoked) != 0) { if (cursor.getInt(mIndexIsRevoked) != 0) {
h.statusIcon.setVisibility(View.VISIBLE); 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; enabled = false;
} else if (cursor.getInt(mIndexIsExpiry) != 0) { } else if (cursor.getInt(mIndexIsExpiry) != 0) {
h.statusIcon.setVisibility(View.VISIBLE); 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; enabled = false;
} else { } else {
h.statusIcon.setVisibility(View.GONE); h.statusIcon.setVisibility(View.GONE);

View File

@@ -272,12 +272,12 @@ public class SubkeysAdapter extends CursorAdapter {
PorterDuff.Mode.SRC_IN); PorterDuff.Mode.SRC_IN);
if (isRevoked) { if (isRevoked) {
vStatus.setImageResource(R.drawable.status_signature_revoked_cutout_24px); vStatus.setImageResource(R.drawable.status_signature_revoked_cutout_24dp);
vStatus.setColorFilter( vStatus.setColorFilter(
mContext.getResources().getColor(R.color.bg_gray), mContext.getResources().getColor(R.color.bg_gray),
PorterDuff.Mode.SRC_IN); PorterDuff.Mode.SRC_IN);
} else if (isExpired) { } else if (isExpired) {
vStatus.setImageResource(R.drawable.status_signature_expired_cutout_24px); vStatus.setImageResource(R.drawable.status_signature_expired_cutout_24dp);
vStatus.setColorFilter( vStatus.setColorFilter(
mContext.getResources().getColor(R.color.bg_gray), mContext.getResources().getColor(R.color.bg_gray),
PorterDuff.Mode.SRC_IN); 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.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
public class UserIdsAdapter extends UserAttributesAdapter { public class UserIdsAdapter extends UserAttributesAdapter {
protected LayoutInflater mInflater; protected LayoutInflater mInflater;
@@ -127,7 +128,7 @@ public class UserIdsAdapter extends UserAttributesAdapter {
if (isRevoked) { if (isRevoked) {
// set revocation icon (can this even be primary?) // 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 // disable revoked user ids
vName.setEnabled(false); vName.setEnabled(false);
@@ -149,13 +150,13 @@ public class UserIdsAdapter extends UserAttributesAdapter {
int isVerified = cursor.getInt(INDEX_VERIFIED); int isVerified = cursor.getInt(INDEX_VERIFIED);
switch (isVerified) { switch (isVerified) {
case Certs.VERIFIED_SECRET: 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; break;
case Certs.VERIFIED_SELF: 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; break;
default: default:
KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_INVALID, KeyFormattingUtils.DEFAULT_COLOR); KeyFormattingUtils.setStatusImage(mContext, vVerified, null, State.INVALID, KeyFormattingUtils.DEFAULT_COLOR);
break; break;
} }
} }

View File

@@ -24,7 +24,6 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
@@ -73,10 +72,8 @@ public class UserIdsAddedAdapter extends ArrayAdapter<String> {
holder.vDelete.setVisibility(View.VISIBLE); // always visible holder.vDelete.setVisibility(View.VISIBLE); // always visible
// not used: // 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); View certifiedLayout = convertView.findViewById(R.id.user_id_item_certified_layout);
ImageView editImage = (ImageView) convertView.findViewById(R.id.user_id_item_edit_image); ImageView editImage = (ImageView) convertView.findViewById(R.id.user_id_item_edit_image);
checkBox.setVisibility(View.GONE);
certifiedLayout.setVisibility(View.GONE); certifiedLayout.setVisibility(View.GONE);
editImage.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
// date picker works based on default time zone Calendar minDateCal = Calendar.getInstance(TimeZone.getDefault());
Calendar minDateCal = Calendar.getInstance(TimeZone.getDefault()); minDateCal.add(Calendar.DAY_OF_YEAR, 1); // at least one day after creation (today)
minDateCal.add(Calendar.DAY_OF_YEAR, 1); // at least one day after creation (today) mExpiryDatePicker.setMinDate(minDateCal.getTime().getTime());
mExpiryDatePicker.setMinDate(minDateCal.getTime().getTime());
}
{ {
ArrayList<Choice<Algorithm>> choices = new ArrayList<>(); ArrayList<Choice<Algorithm>> choices = new ArrayList<>();
@@ -283,7 +281,7 @@ public class AddSubkeyDialogFragment extends DialogFragment {
// For EC keys, add a curve // For EC keys, add a curve
if (algorithm == Algorithm.ECDH || algorithm == Algorithm.ECDSA) { if (algorithm == Algorithm.ECDH || algorithm == Algorithm.ECDSA) {
curve = ((Choice<Curve>) mCurveSpinner.getSelectedItem()).getId(); curve = ((Choice<Curve>) mCurveSpinner.getSelectedItem()).getId();
// Otherwise, get a keysize // Otherwise, get a keysize
} else { } else {
keySize = getProperKeyLength(algorithm, getSelectedKeyLength()); 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; package org.sufficientlysecure.keychain.ui.dialog;
import android.app.AlertDialog; import android.app.AlertDialog;

View File

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

View File

@@ -25,11 +25,14 @@ import android.os.Message;
import android.os.Messenger; import android.os.Messenger;
import android.os.RemoteException; import android.os.RemoteException;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.text.format.DateFormat;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.DatePicker; import android.widget.DatePicker;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; 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 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 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() { noExpiry.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) { if (isChecked) {
datePicker.setVisibility(View.GONE); expiryLayout.setVisibility(View.GONE);
} else { } else {
datePicker.setVisibility(View.VISIBLE); expiryLayout.setVisibility(View.VISIBLE);
} }
} }
}); });
// init date picker with default selected date
if (expiry == 0L) { if (expiry == 0L) {
noExpiry.setChecked(true); noExpiry.setChecked(true);
datePicker.setVisibility(View.GONE); expiryLayout.setVisibility(View.GONE);
Calendar todayCal = Calendar.getInstance(TimeZone.getDefault()); currentExpiry.setText(R.string.btn_no_date);
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
);
}
} else { } else {
noExpiry.setChecked(false); noExpiry.setChecked(false);
datePicker.setVisibility(View.VISIBLE); expiryLayout.setVisibility(View.VISIBLE);
// set date picker to current expiry // convert from UTC to time zone of device
datePicker.init( Calendar expiryCalTimeZone = (Calendar) expiryCal.clone();
expiryCal.get(Calendar.YEAR), expiryCalTimeZone.setTimeZone(TimeZone.getDefault());
expiryCal.get(Calendar.MONTH), currentExpiry.setText(DateFormat.getDateFormat(
expiryCal.get(Calendar.DAY_OF_MONTH), getActivity()).format(expiryCalTimeZone.getTime()));
null
);
} }
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { // date picker works based on default time zone
datePicker.setMinDate(creationCal.getTime().getTime()); 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() { 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