Compare commits

...

87 Commits

Author SHA1 Message Date
akwizgran
a114d4db15 Bump version numbers for 1.0.11 release. 2018-07-04 08:45:03 +01:00
akwizgran
73b7879c64 Update translations. 2018-07-04 08:44:00 +01:00
akwizgran
e622a518ac Merge branch 'fix_npe_keyfrag' into 'master'
Fix a possible null reference bug

See merge request briar/briar!853
2018-07-03 17:20:59 +00:00
goapunk
28ea3d014a Fix a possible null reference bug 2018-07-03 11:33:13 +02:00
akwizgran
457d77ca51 Bump version numbers for 1.0.10 release. 2018-07-02 14:06:49 +01:00
akwizgran
581c67f5fd Update translations. 2018-07-02 14:04:51 +01:00
Torsten Grote
1dcb9aa1d0 Merge branch '1329-auth-cookie' into 'master'
Delete old auth cookie before starting Tor

Closes #1329

See merge request briar/briar!852
2018-06-29 15:38:23 +00:00
akwizgran
d97dcfff30 Merge branch 'no_screenfilter_warning_splash' into 'master'
Don't show screenfilter warning in SplashScreenActivity

See merge request briar/briar!832
2018-06-29 14:41:09 +00:00
akwizgran
e166d9dd15 Merge branch '1327-setup-crash' into 'master'
Ensure that pressing back after setup will always return the user to home

Closes #1327

See merge request briar/briar!849
2018-06-29 14:40:43 +00:00
akwizgran
2e002d132c Delete old auth cookie before starting Tor. 2018-06-29 15:28:50 +01:00
Torsten Grote
da629df630 Ensure that pressing back after setup will always return the user to home 2018-06-26 11:42:54 -03:00
Nico Alt
135372ebee Use consistent language for forum posts
Fixes #888.
2018-06-26 14:25:24 +02:00
akwizgran
b083122d72 Merge branch '47-sign-in-reminder' into 'master'
Remind the user to sign in

See merge request briar/briar!841
2018-06-22 14:49:09 +00:00
akwizgran
649433a506 Merge branch '1032-message-icon' into 'master'
Use message icon rather than mail icon for private messages

Closes #1032

See merge request briar/briar!846
2018-06-22 14:18:20 +00:00
Torsten Grote
eff3a69734 Disable sign-in reminder with a feature flag in release builds 2018-06-22 10:59:27 -03:00
Torsten Grote
62de50af76 Remind the user to sign in only when an account has been created 2018-06-22 10:46:27 -03:00
Torsten Grote
1f9def8418 Minimal Sign-in reminder 2018-06-22 10:46:27 -03:00
Torsten Grote
1e80069980 Merge branch 'feature-flags' into 'master'
Add feature flag for dark theme

See merge request briar/briar!843
2018-06-22 13:43:56 +00:00
Torsten Grote
bfde71c151 Merge branch '1307-readable-log' into 'master'
Display log file in a reader-friendly way

Closes #1307

See merge request briar/briar!845
2018-06-22 13:42:40 +00:00
akwizgran
bce0a3150b Use message icon rather than mail icon. 2018-06-22 13:48:52 +01:00
akwizgran
ee59b9b3ad Unescape newlines when showing log. 2018-06-22 11:17:54 +01:00
akwizgran
55918a88b2 Merge branch '1251-dark-theme-fixes' into 'master'
Dark Theme Fixes

See merge request briar/briar!844
2018-06-21 12:49:15 +00:00
Torsten Grote
679c1c3719 Fix RSS feed delete button and disabled button text 2018-06-21 09:40:55 -03:00
akwizgran
21f33d6cfb Add feature flag for dark theme. 2018-06-21 13:28:32 +01:00
akwizgran
912b1b5b1d Merge branch 'factor_out_keyagreement_ui-theme' into 'master'
Factor out keyagreement ui theme

See merge request briar/briar!835
2018-06-21 11:38:49 +00:00
goapunk
0ad20037ae Pass String instead of the TextView 2018-06-20 18:36:39 +02:00
akwizgran
62d893f7b1 Merge branch 'android-gradle-3.1.3' into 'master'
Upgrade Android Gradle Plugin to 3.1.3

See merge request briar/briar!842
2018-06-20 15:45:55 +00:00
goapunk
497213e56d add KeyAgreementEventListener interface 2018-06-20 15:44:42 +02:00
akwizgran
f5c0d0b2cb Merge branch '1251-dark-theme' into 'master'
Implement Dark Theme (DayNight with automatic option)

See merge request akwizgran/briar!818
2018-06-20 13:43:04 +00:00
goapunk
f4131d6f32 address reviews 2018-06-20 15:32:51 +02:00
goapunk
06deba4bd4 Create a dedicated qrCodeView 2018-06-20 15:32:42 +02:00
goapunk
26643e491b Add some abstraction to the keyagreement ui 2018-06-20 15:32:23 +02:00
Torsten Grote
6ef4130f8f Upgrade Android Gradle Plugin to 3.1.3 2018-06-19 17:36:35 -03:00
Torsten Grote
ba5b2f601b Applying night mode to DevReportActivity 2018-06-19 14:19:15 -03:00
Torsten Grote
5be672f0e7 Remove unused resources 2018-06-19 13:30:01 -03:00
Torsten Grote
fa525564c0 Hide Theme Settings in release builds for now 2018-06-19 13:30:01 -03:00
Torsten Grote
dee0ca238b Address first round of review comments 2018-06-19 13:30:00 -03:00
Torsten Grote
3c6b43b2bd Implement Dark Theme (DayNight with automatic option)
This is just a first rough implementation.
A real UI designer should look over this.
2018-06-19 13:29:13 -03:00
Administrator
dcacae0729 Merge branch 'language_improvements' into 'master'
Language improvements

See merge request akwizgran/briar!829
2018-06-19 16:27:50 +00:00
akwizgran
aefc5c519e Merge branch '1297-opendb-gui' into 'master'
Resolve ""Decrypting database" label needs some padding"

Closes #1297

See merge request akwizgran/briar!830
2018-06-18 14:19:34 +00:00
akwizgran
7225adf24e Merge branch 'fix_translation_verification' into 'master'
Use project path for translation verification

See merge request akwizgran/briar!840
2018-06-18 14:18:49 +00:00
goapunk
30228cf025 Use project path for translation verification 2018-06-17 16:11:22 +02:00
Torsten Grote
99e2b7eaab Merge branch 'exception-logging-method' into 'master'
Add utility method for logging exceptions

See merge request akwizgran/briar!838
2018-06-16 13:38:25 +00:00
Torsten Grote
2f7d5b869c Merge branch 'hide-ui-if-not-in-foreground' into 'master'
Don't hide UI on low memory if we're in the foreground

See merge request akwizgran/briar!839
2018-06-15 20:19:05 +00:00
akwizgran
d5d6db6723 Add utility method for logging exceptions. 2018-06-15 17:09:34 +01:00
Torsten Grote
b026031d66 Merge branch 'fine-logging' into 'master'
Replace logging boilerplate with a static method

See merge request akwizgran/briar!837
2018-06-15 15:30:31 +00:00
akwizgran
abe14f19e6 Replace boilerplate with static method. 2018-06-15 16:17:08 +01:00
Torsten Grote
fa17549972 Merge branch 'fine-logging' into 'master'
Move logging of time measurements to FINE level

See merge request akwizgran/briar!836
2018-06-15 15:00:25 +00:00
akwizgran
0d2a91289f Don't calculate duration unless needed. 2018-06-15 15:52:05 +01:00
Torsten Grote
2e22318b27 Merge branch '1291-huawei-protected-apps' into 'master'
Don't show Huawei protected apps button on API 24+

Closes #1291

See merge request akwizgran/briar!823
2018-06-15 14:35:46 +00:00
akwizgran
11f0bd1ae0 Merge branch '1288-placeholder-texts' into 'master'
Use placeholder text for text fields and add show password button

Closes #1096 and #1288

See merge request akwizgran/briar!834
2018-06-15 14:22:21 +00:00
akwizgran
e2d636e274 Don't hide UI on low memory if we're in the foreground. 2018-06-15 15:14:13 +01:00
Torsten Grote
f41b76c567 Shorten password hints 2018-06-15 11:13:38 -03:00
akwizgran
08931e64cb Use System.nanoTime() for timing measurements. 2018-06-15 13:01:48 +01:00
akwizgran
ccee1febbc Move timing measurements down to FINE log level. 2018-06-15 13:01:48 +01:00
Torsten Grote
7bfc1c3579 Add buttons to show passwords wherever they can be entered
Closes #1096
2018-06-14 15:40:17 -03:00
Torsten Grote
2dc94a95ed Use placeholder texts for text fields
Closes #1288
2018-06-14 15:36:08 -03:00
Torsten Grote
a47a1cf442 Merge branch '1316-make-introduction-string' into 'master'
Use separate strings for introduction menu item and button

Closes #1316

See merge request akwizgran/briar!833
2018-06-13 20:16:34 +00:00
akwizgran
4adb27a1ce Use separate strings for introduction menu item and button. 2018-06-13 16:50:24 +01:00
akwizgran
841c31ebce Bump version numbers for 1.0.9 release. 2018-06-13 15:38:49 +01:00
akwizgran
d6810cf87f Update translations. 2018-06-13 15:36:57 +01:00
goapunk
7a2df3d6cb simplify 2018-06-13 13:38:15 +02:00
goapunk
0c65ff4783 remove the unncessary synchronization from reset 2018-06-13 12:42:03 +02:00
goapunk
8b10b7ed23 Don't show screenfilter warning here 2018-06-13 12:36:43 +02:00
goapunk
9743255ce9 immutable version 2018-06-13 12:32:38 +02:00
jRustig
c845dfc7f4 Fix padding in activity_open_database
Closes #1297
2018-06-13 10:00:42 +02:00
akwizgran
a8a02b9e45 Merge branch '992-refresh-wake-lock' into 'master'
Renew the wake lock every minute to avoid wake lock killers

See merge request akwizgran/briar!827
2018-06-12 16:59:32 +00:00
akwizgran
6703be1c32 Add thread safety, null safety annotations. 2018-06-12 17:50:58 +01:00
goapunk
fc99dedb53 Detect if system language changed 2018-06-12 16:23:32 +02:00
goapunk
65a461a0db Reset Localizer on account deletion 2018-06-12 12:15:47 +02:00
akwizgran
a44a68f231 Bump version numbers for 1.0.8 release. 2018-06-08 13:00:39 +01:00
akwizgran
4ac6baa23d Update translations. 2018-06-08 13:00:39 +01:00
akwizgran
4cde50b7f5 Merge branch '1293-cookie-file-polling' into 'master'
Poll for creation of Tor auth cookie file

Closes #1293

See merge request akwizgran/briar!828
2018-06-08 11:30:12 +00:00
akwizgran
da40eca80b Merge branch '1160-language-setting' into 'master'
Add language setting

Closes #1160 and #1222

See merge request akwizgran/briar!679
2018-06-08 11:20:39 +00:00
akwizgran
fa267d38af Filter out RTL languages on API < 17. 2018-06-08 13:07:30 +02:00
akwizgran
ba20fbeb47 Poll for creation of cookie file. 2018-06-08 10:40:38 +01:00
akwizgran
d7f39af6d1 Reduce wake lock refresh interval to 1 minute. 2018-06-07 10:46:16 +01:00
akwizgran
4f732c3997 Acquire wake lock with a timeout. 2018-06-07 10:46:16 +01:00
akwizgran
74cfd313ab Code cleanup. 2018-06-07 10:46:16 +01:00
akwizgran
c089a099f0 Refactor wake lock to use existing ScheduledExecutorService. 2018-06-07 10:46:15 +01:00
goapunk
98a0d09899 Renew the wake lock every 30min
Signed-off-by: goapunk <noobie@goapunks.net>
2018-06-07 10:46:15 +01:00
goapunk
18c4195115 fix region and title 2018-06-07 11:42:31 +02:00
goapunk
8bc28f99c1 Improvements:
* Force LTR by prefixing language names with the LRM marker
* Add Polish
* Cleanup
2018-06-07 10:19:17 +02:00
goapunk
1834146ad0 fix hebrew 2018-06-07 10:19:17 +02:00
goapunk
695b543ba9 fix review 2018-06-06 11:16:24 +02:00
goapunk
75e910e1d9 Add a language setting 2018-06-06 11:16:21 +02:00
akwizgran
5e679e7a10 Don't show Huawei protected apps button on API 24+. 2018-05-31 09:48:38 +01:00
273 changed files with 3071 additions and 1952 deletions

View File

@@ -8,8 +8,8 @@ android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 26
versionCode 10007
versionName "1.0.7"
versionCode 10011
versionName "1.0.11"
consumerProguardFiles 'proguard-rules.txt'
}
@@ -35,32 +35,32 @@ dependencies {
dependencyVerification {
verify = [
'com.android.tools.analytics-library:protos:26.1.2:protos-26.1.2.jar:52672a0b42b572a06aecc3535d5068eb46c0e15d129b9f1085d3c16a1da5cdbb',
'com.android.tools.analytics-library:shared:26.1.2:shared-26.1.2.jar:5c7e0eda18c6f87feeb83628c707e8aaa3298b41fb72e38efe31ad1675f9e8e9',
'com.android.tools.analytics-library:tracker:26.1.2:tracker-26.1.2.jar:06f97aa0adf44ffb06f8681c6a79d9be153a08f61d21eddc42b8d3db96df4282',
'com.android.tools.build:apksig:3.1.2:apksig-3.1.2.jar:40696a4559124d1d57873d208857eee059d48859239d569c7d18374ac644a8be',
'com.android.tools.build:builder-model:3.1.2:builder-model-3.1.2.jar:d49bfa2a135c9562b6ca7aa4342036cfa1582c7074c2d1d93d1dae8b3a134e17',
'com.android.tools.build:builder-test-api:3.1.2:builder-test-api-3.1.2.jar:dfe2a50b740d41b11189101062434d4283d18647e89a492ad51710c719363e9f',
'com.android.tools.build:builder:3.1.2:builder-3.1.2.jar:b60f825a42e2efe8433619fbc759f3d9effecab718279048d36881188ceb1d14',
'com.android.tools.build:gradle-api:3.1.2:gradle-api-3.1.2.jar:e58bcc5b893e4583ab0f5c8ef89c4dbcce202b405a9d7fcc116d21e5357d4893',
'com.android.tools.build:manifest-merger:26.1.2:manifest-merger-26.1.2.jar:9c61c27ea5266573107b954acf1216d398f4d7e7ae6fad6409d6b2b767eb091c',
'com.android.tools.ddms:ddmlib:26.1.2:ddmlib-26.1.2.jar:18a2a5fbef36882f07d03c2b9e59eba05cf8248177bf5cbff736e4b582804c44',
'com.android.tools.external.com-intellij:intellij-core:26.1.2:intellij-core-26.1.2.jar:37c5acf279f1ae3e85b1a5be3c9f15f43bde7b08f978eefefffb9c4035760c52',
'com.android.tools.external.com-intellij:kotlin-compiler:26.1.2:kotlin-compiler-26.1.2.jar:152df0bee7580326c77316b669a9d96e3b09efb1d45f545dce4147271b0b8944',
'com.android.tools.external.org-jetbrains:uast:26.1.2:uast-26.1.2.jar:02d39582206d3f5fc0a6cb18bfd9e8b9f9c1acb805ec6dac08b4e3a56849d279',
'com.android.tools.layoutlib:layoutlib-api:26.1.2:layoutlib-api-26.1.2.jar:20220039fcc7d799f928153beff862e704457c0f55ab44258f3745ebeb662b4f',
'com.android.tools.lint:lint-api:26.1.2:lint-api-26.1.2.jar:e1d5b62b870a7c566e9877a6b96b27784a4d713f8caa07fdcb4705d47a40a1d9',
'com.android.tools.lint:lint-checks:26.1.2:lint-checks-26.1.2.jar:211e2afd58504372385d71b1e5be982c2b5121ab6fee1c04ddabeb75a8729e07',
'com.android.tools.lint:lint-gradle-api:26.1.2:lint-gradle-api-26.1.2.jar:71284f2a8b03c3e55c94511c9eb36f8184fbb85324325fc6b78abf5183f03d90',
'com.android.tools.lint:lint-gradle:26.1.2:lint-gradle-26.1.2.jar:855f0c82b7fc690df1b7319c0774f7517f7f8f5dd4eee1f6077dcf50e07c6240',
'com.android.tools.lint:lint-kotlin:26.1.2:lint-kotlin-26.1.2.jar:1e591f70bcbbc11569720a9bbcca2bc1f3d4f789f01f40f642848d920643d484',
'com.android.tools.lint:lint:26.1.2:lint-26.1.2.jar:93736c62e9f1976998c2b4aa716aea0734cdb162d05502f4af7292654aedb182',
'com.android.tools:annotations:26.1.2:annotations-26.1.2.jar:72773dcaf5c4ccca828e3c8467f1b78a8a00b3cc5f8ad1aab88fcf9379928018',
'com.android.tools:common:26.1.2:common-26.1.2.jar:ea4320f0c17dcbc4491896bb705c4d25ec08bd62ef02ab0579fe154e75e788e6',
'com.android.tools:dvlib:26.1.2:dvlib-26.1.2.jar:1187aa4fb666595c96c4deb6bc0e0f4b7e396bde9f6243330b49a232946130ea',
'com.android.tools:repository:26.1.2:repository-26.1.2.jar:8b86e512ad6d32bd76989451eefe2b271f5efce6d4d65ecb173afaf14606e01a',
'com.android.tools:sdk-common:26.1.2:sdk-common-26.1.2.jar:23584720a60a21cdcb5b1ec10269e3013789d6805d153cc696c39ec7ce251896',
'com.android.tools:sdklib:26.1.2:sdklib-26.1.2.jar:d3870fafc59ab8efa70d3f9649f40ee299c8ec5b58377b06e8853d7272a5bf4e',
'com.android.tools.analytics-library:protos:26.1.3:protos-26.1.3.jar:818c9f256f141d9dafec03a1aa2b94d240b2c140acfd7ee31a8b3e6c2b9479e3',
'com.android.tools.analytics-library:shared:26.1.3:shared-26.1.3.jar:7110706c7ada96c8b6f5ca80c478291bc7899d46277de2c48527e045442401a3',
'com.android.tools.analytics-library:tracker:26.1.3:tracker-26.1.3.jar:4155424bf2ce4872da83332579a1707252bc66cbd77c5144fdc4483d0f2e1418',
'com.android.tools.build:apksig:3.1.3:apksig-3.1.3.jar:7e1f8e675a6e768e5b56405e41d6c3cc05befe62e601b04177de1029902c9c89',
'com.android.tools.build:builder-model:3.1.3:builder-model-3.1.3.jar:06ad1c422d679fc698451479cb40ba863849d67bfd1de23f6d2c16d78b024b0b',
'com.android.tools.build:builder-test-api:3.1.3:builder-test-api-3.1.3.jar:4d989f780436794f0f8b2f50e9e079b786571eac90f26c208ab2ae6d4012f389',
'com.android.tools.build:builder:3.1.3:builder-3.1.3.jar:8a1092012c89d0ec1ee2eff09c5708c71ef4482a6862df8d3a44a67fccace01c',
'com.android.tools.build:gradle-api:3.1.3:gradle-api-3.1.3.jar:01e4df521456aef66514336f1d492346730dd1fb8f6433a89f62da834941ed72',
'com.android.tools.build:manifest-merger:26.1.3:manifest-merger-26.1.3.jar:1e4fc7e932adb4607082409800e5e6fccb42e6c5360ae5990094bf522f3ada55',
'com.android.tools.ddms:ddmlib:26.1.3:ddmlib-26.1.3.jar:c54931cd68df5d1ea2923b3b320eae47cd2307a5a916bb8674c0acf93cd1d3cd',
'com.android.tools.external.com-intellij:intellij-core:26.1.3:intellij-core-26.1.3.jar:af67f5535fef2e1a28b1007a4acb8c5deb6a1e33b8afe7b11d012c9e778ebcec',
'com.android.tools.external.com-intellij:kotlin-compiler:26.1.3:kotlin-compiler-26.1.3.jar:c746d2859dc11cc05c84b692b3498d3a621e0929511f8440ee009c6557838fd4',
'com.android.tools.external.org-jetbrains:uast:26.1.3:uast-26.1.3.jar:3f3f6651d0c7685a77ecb22e9c82d6b49fdf24322c17360768dc530678f43265',
'com.android.tools.layoutlib:layoutlib-api:26.1.3:layoutlib-api-26.1.3.jar:10bc73ce706c45629872d6a999dbe12116df64e24f47ff93b7b13121ff57b4b0',
'com.android.tools.lint:lint-api:26.1.3:lint-api-26.1.3.jar:6f97323f9af8deda86278717885b5c927f3766757db89709f52d11d42b6fb751',
'com.android.tools.lint:lint-checks:26.1.3:lint-checks-26.1.3.jar:73c3d53784c9ce3e6d5968506581918e0179645d20809927ca4a001dd766b001',
'com.android.tools.lint:lint-gradle-api:26.1.3:lint-gradle-api-26.1.3.jar:7ca3c4866ec21dc21d53a9d86f752b77ace6f6c610a0c9dc877313856c733d9d',
'com.android.tools.lint:lint-gradle:26.1.3:lint-gradle-26.1.3.jar:db0c354b8f4b6f6637e31f91c564785a59ff896325331fcbc3de7458e0b6c067',
'com.android.tools.lint:lint-kotlin:26.1.3:lint-kotlin-26.1.3.jar:94e2b0f4565a241561cfb8fc1222bb3f132a3b98d2a90421dbb72ee8358e7d68',
'com.android.tools.lint:lint:26.1.3:lint-26.1.3.jar:8d5f32c989c6d191d712e90ad3ca2d1c409313599551d04d834caa44d26c78df',
'com.android.tools:annotations:26.1.3:annotations-26.1.3.jar:c950430b24ac5d58fc97e7283b8f0115f99587e76e08b4e1e2aaa780f2d77323',
'com.android.tools:common:26.1.3:common-26.1.3.jar:7c31a90581a148ab219f615a59667f0dded7fa39b248529784474da3c2274ef2',
'com.android.tools:dvlib:26.1.3:dvlib-26.1.3.jar:0cae87906f53d3f1088366a916ed180a7312b6d9919b90797f238875c8492855',
'com.android.tools:repository:26.1.3:repository-26.1.3.jar:52d4539cc68db91b261e2a33b2c8206b26e05539078758dc28cfb3854adb4f59',
'com.android.tools:sdk-common:26.1.3:sdk-common-26.1.3.jar:1948603ca9ff22c7ebb3178000bffa3a9dd2ca1cc5cb0c793cae08468b8fcfc1',
'com.android.tools:sdklib:26.1.3:sdklib-26.1.3.jar:4adcfaad9514607098d2c51503c39811112d3050f4d1e744c01c7f08f591032b',
'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed',
'com.google.code.gson:gson:2.7:gson-2.7.jar:2d43eb5ea9e133d2ee2405cc14f5ee08951b8361302fdd93494a3a997b508d32',
'com.google.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',

View File

@@ -38,6 +38,7 @@ import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE;
import static android.bluetooth.BluetoothAdapter.STATE_OFF;
import static android.bluetooth.BluetoothAdapter.STATE_ON;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@@ -145,7 +146,7 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
try {
if (ss != null) ss.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -185,7 +186,7 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
try {
if (c != null) c.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}

View File

@@ -10,7 +10,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.FileObserver;
import android.os.PowerManager;
import net.freehaven.tor.control.EventHandler;
@@ -34,8 +33,10 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.util.IoUtils;
import org.briarproject.bramble.util.RenewableWakeLock;
import org.briarproject.bramble.util.StringUtils;
import java.io.Closeable;
@@ -55,7 +56,6 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
@@ -78,7 +78,6 @@ import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
@@ -92,6 +91,7 @@ import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WIFI;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT;
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion;
@MethodsNotNullByDefault
@@ -102,8 +102,11 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
"CIRC", "ORCONN", "HS_DESC", "NOTICE", "WARN", "ERR"
};
private static final String OWNER = "__OwningControllerProcess";
private static final int COOKIE_TIMEOUT = 3000; // Milliseconds
private static final int COOKIE_TIMEOUT_MS = 3000;
private static final int COOKIE_POLLING_INTERVAL_MS = 200;
private static final Pattern ONION = Pattern.compile("[a-z2-7]{16}");
// This tag may prevent Huawei's power manager from killing us
private static final String WAKE_LOCK_TAG = "LocationManagerService";
private static final Logger LOG =
Logger.getLogger(TorPlugin.class.getName());
@@ -112,6 +115,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private final Context appContext;
private final LocationUtils locationUtils;
private final SocketFactory torSocketFactory;
private final Clock clock;
private final Backoff backoff;
private final DuplexPluginCallback callback;
private final String architecture;
@@ -119,7 +123,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private final ConnectionStatus connectionStatus;
private final File torDirectory, torFile, geoIpFile, configFile;
private final File doneFile, cookieFile;
private final PowerManager.WakeLock wakeLock;
private final RenewableWakeLock wakeLock;
private final AtomicReference<Future<?>> connectivityCheck =
new AtomicReference<>();
private final AtomicBoolean used = new AtomicBoolean(false);
@@ -132,7 +136,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
TorPlugin(Executor ioExecutor, ScheduledExecutorService scheduler,
Context appContext, LocationUtils locationUtils,
SocketFactory torSocketFactory, Backoff backoff,
SocketFactory torSocketFactory, Clock clock, Backoff backoff,
DuplexPluginCallback callback, String architecture,
int maxLatency, int maxIdleTime) {
this.ioExecutor = ioExecutor;
@@ -140,6 +144,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
this.appContext = appContext;
this.locationUtils = locationUtils;
this.torSocketFactory = torSocketFactory;
this.clock = clock;
this.backoff = backoff;
this.callback = callback;
this.architecture = architecture;
@@ -155,14 +160,13 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
configFile = new File(torDirectory, "torrc");
doneFile = new File(torDirectory, "done");
cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
Object o = appContext.getSystemService(POWER_SERVICE);
PowerManager pm = (PowerManager) o;
// This tag will prevent Huawei's powermanager from killing us.
wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "LocationManagerService");
wakeLock.setReferenceCounted(false);
// Don't execute more than one connection status check at a time
connectionStatusExecutor = new PoliteExecutor("TorPlugin",
ioExecutor, 1);
PowerManager pm = (PowerManager)
appContext.getSystemService(POWER_SERVICE);
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
WAKE_LOCK_TAG, 1, MINUTES);
}
@Override
@@ -185,13 +189,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (used.getAndSet(true)) throw new IllegalStateException();
// Install or update the assets if necessary
if (!assetsAreUpToDate()) installAssets();
// Watch for the auth cookie file being created
if (cookieFile.getParentFile().mkdirs())
LOG.info("Created directory for cookie file");
if (cookieFile.delete()) LOG.info("Deleted old cookie file");
CountDownLatch latch = new CountDownLatch(1);
FileObserver obs = new CreateObserver(cookieFile, latch);
obs.startWatching();
if (cookieFile.exists() && !cookieFile.delete())
LOG.warning("Old auth cookie not deleted");
// Start a new Tor process
LOG.info("Starting Tor");
String torPath = torFile.getAbsolutePath();
@@ -232,11 +231,16 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
throw new PluginException();
}
// Wait for the auth cookie file to be created/updated
if (!latch.await(COOKIE_TIMEOUT, MILLISECONDS)) {
LOG.warning("Auth cookie not created");
if (LOG.isLoggable(INFO)) listFiles(torDirectory);
throw new PluginException();
long start = clock.currentTimeMillis();
while (cookieFile.length() < 32) {
if (clock.currentTimeMillis() - start > COOKIE_TIMEOUT_MS) {
LOG.warning("Auth cookie not created");
if (LOG.isLoggable(INFO)) listFiles(torDirectory);
throw new PluginException();
}
Thread.sleep(COOKIE_POLLING_INTERVAL_MS);
}
LOG.info("Auth cookie created");
} catch (InterruptedException e) {
LOG.warning("Interrupted while starting Tor");
Thread.currentThread().interrupt();
@@ -344,7 +348,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
try {
if (c != null) c.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -352,7 +356,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
try {
if (s != null) s.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -394,7 +398,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
ss = new ServerSocket();
ss.bind(new InetSocketAddress("127.0.0.1", port));
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
tryToClose(ss);
return;
}
@@ -420,7 +424,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
try {
if (ss != null) ss.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
} finally {
callback.transportDisabled();
}
@@ -439,7 +443,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
response = controlConnection.addOnion(portLines);
else response = controlConnection.addOnion(privKey, portLines);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return;
}
if (!response.containsKey(HS_ADDRESS)) {
@@ -507,7 +511,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
controlConnection.shutdownTor("TERM");
controlSocket.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
wakeLock.release();
@@ -685,7 +689,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
enableNetwork(true);
}
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -698,26 +702,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (oldConnectivityCheck != null) oldConnectivityCheck.cancel(false);
}
private static class CreateObserver extends FileObserver {
private final File file;
private final CountDownLatch latch;
private CreateObserver(File file, CountDownLatch latch) {
super(file.getParentFile().getAbsolutePath(), CREATE | MOVED_TO);
this.file = file;
this.latch = latch;
}
@Override
public void onEvent(int event, @Nullable String path) {
if (file.exists()) {
stopWatching();
latch.countDown();
}
}
}
private class NetworkStateReceiver extends BroadcastReceiver {
@Override

View File

@@ -12,6 +12,7 @@ import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.util.AndroidUtils;
@@ -42,11 +43,13 @@ public class TorPluginFactory implements DuplexPluginFactory {
private final EventBus eventBus;
private final SocketFactory torSocketFactory;
private final BackoffFactory backoffFactory;
private final Clock clock;
public TorPluginFactory(Executor ioExecutor,
ScheduledExecutorService scheduler, Context appContext,
LocationUtils locationUtils, EventBus eventBus,
SocketFactory torSocketFactory, BackoffFactory backoffFactory) {
SocketFactory torSocketFactory, BackoffFactory backoffFactory,
Clock clock) {
this.ioExecutor = ioExecutor;
this.scheduler = scheduler;
this.appContext = appContext;
@@ -54,6 +57,7 @@ public class TorPluginFactory implements DuplexPluginFactory {
this.eventBus = eventBus;
this.torSocketFactory = torSocketFactory;
this.backoffFactory = backoffFactory;
this.clock = clock;
}
@Override
@@ -90,7 +94,7 @@ public class TorPluginFactory implements DuplexPluginFactory {
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
TorPlugin plugin = new TorPlugin(ioExecutor, scheduler, appContext,
locationUtils, torSocketFactory, backoff, callback,
locationUtils, torSocketFactory, clock, backoff, callback,
architecture, MAX_LATENCY, MAX_IDLE_TIME);
eventBus.addListener(plugin);
return plugin;

View File

@@ -0,0 +1,100 @@
package org.briarproject.bramble.util;
import android.os.PowerManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
@ThreadSafe
@NotNullByDefault
public class RenewableWakeLock {
private static final Logger LOG =
Logger.getLogger(RenewableWakeLock.class.getName());
/**
* Automatically release the lock this many milliseconds after it's due
* to have been replaced and released.
*/
private static final int SAFETY_MARGIN_MS = 10_000;
private final PowerManager powerManager;
private final ScheduledExecutorService scheduler;
private final int levelAndFlags;
private final String tag;
private final long durationMs;
private final Runnable renewTask;
private final Object lock = new Object();
@Nullable
private PowerManager.WakeLock wakeLock; // Locking: lock
@Nullable
private ScheduledFuture future; // Locking: lock
public RenewableWakeLock(PowerManager powerManager,
ScheduledExecutorService scheduler, int levelAndFlags, String tag,
long duration, TimeUnit timeUnit) {
this.powerManager = powerManager;
this.scheduler = scheduler;
this.levelAndFlags = levelAndFlags;
this.tag = tag;
durationMs = MILLISECONDS.convert(duration, timeUnit);
renewTask = this::renew;
}
public void acquire() {
if (LOG.isLoggable(INFO)) LOG.info("Acquiring wake lock " + tag);
synchronized (lock) {
if (wakeLock != null) {
LOG.info("Already acquired");
return;
}
wakeLock = powerManager.newWakeLock(levelAndFlags, tag);
wakeLock.setReferenceCounted(false);
wakeLock.acquire(durationMs + SAFETY_MARGIN_MS);
future = scheduler.schedule(renewTask, durationMs, MILLISECONDS);
}
}
private void renew() {
if (LOG.isLoggable(INFO)) LOG.info("Renewing wake lock " + tag);
synchronized (lock) {
if (wakeLock == null) {
LOG.info("Already released");
return;
}
PowerManager.WakeLock oldWakeLock = wakeLock;
wakeLock = powerManager.newWakeLock(levelAndFlags, tag);
wakeLock.setReferenceCounted(false);
wakeLock.acquire(durationMs + SAFETY_MARGIN_MS);
oldWakeLock.release();
future = scheduler.schedule(renewTask, durationMs, MILLISECONDS);
}
}
public void release() {
if (LOG.isLoggable(INFO)) LOG.info("Releasing wake lock " + tag);
synchronized (lock) {
if (wakeLock == null) {
LOG.info("Already released");
return;
}
if (future == null) throw new AssertionError();
future.cancel(false);
future = null;
wakeLock.release();
wakeLock = null;
}
}
}

View File

@@ -0,0 +1,36 @@
package org.briarproject.bramble.util;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.logging.Level.FINE;
public class LogUtils {
private static final int NANOS_PER_MILLI = 1000 * 1000;
/**
* Returns the elapsed time in milliseconds since some arbitrary
* starting time. This is only useful for measuring elapsed time.
*/
public static long now() {
return System.nanoTime() / NANOS_PER_MILLI;
}
/**
* Logs the duration of a task.
* @param logger the logger to use
* @param task a description of the task
* @param start the start time of the task, as returned by {@link #now()}
*/
public static void logDuration(Logger logger, String task, long start) {
if (logger.isLoggable(FINE)) {
long duration = now() - start;
logger.fine(task + " took " + duration + " ms");
}
}
public static void logException(Logger logger, Level level, Throwable t) {
if (logger.isLoggable(level)) logger.log(level, t.toString(), t);
}
}

View File

@@ -5,12 +5,12 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.Executor;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.concurrent.GuardedBy;
import static java.util.logging.Level.FINE;
import static org.briarproject.bramble.util.LogUtils.now;
/**
* An {@link Executor} that delegates its tasks to another {@link Executor}
@@ -20,8 +20,6 @@ import static java.util.logging.Level.FINE;
@NotNullByDefault
public class PoliteExecutor implements Executor {
private static final Level LOG_LEVEL = FINE;
private final Object lock = new Object();
@GuardedBy("lock")
private final Queue<Runnable> queue = new LinkedList<>();
@@ -49,11 +47,11 @@ public class PoliteExecutor implements Executor {
@Override
public void execute(Runnable r) {
long submitted = System.currentTimeMillis();
long submitted = now();
Runnable wrapped = () -> {
if (log.isLoggable(LOG_LEVEL)) {
long queued = System.currentTimeMillis() - submitted;
log.log(LOG_LEVEL, "Queue time " + queued + " ms");
if (log.isLoggable(FINE)) {
long queued = now() - submitted;
log.fine("Queue time " + queued + " ms");
}
try {
r.run();

View File

@@ -6,16 +6,14 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.logging.Level.FINE;
import static org.briarproject.bramble.util.LogUtils.now;
@NotNullByDefault
public class TimeLoggingExecutor extends ThreadPoolExecutor {
private static final Level LOG_LEVEL = FINE;
private final Logger log;
public TimeLoggingExecutor(String tag, int corePoolSize, int maxPoolSize,
@@ -29,15 +27,15 @@ public class TimeLoggingExecutor extends ThreadPoolExecutor {
@Override
public void execute(Runnable r) {
if (log.isLoggable(LOG_LEVEL)) {
long submitted = System.currentTimeMillis();
if (log.isLoggable(FINE)) {
long submitted = now();
super.execute(() -> {
long started = System.currentTimeMillis();
long started = now();
long queued = started - submitted;
log.log(LOG_LEVEL, "Queue time " + queued + " ms");
log.fine("Queue time " + queued + " ms");
r.run();
long executing = System.currentTimeMillis() - started;
log.log(LOG_LEVEL, "Execution time " + executing + " ms");
long executing = now() - started;
log.fine("Execution time " + executing + " ms");
});
} else {
super.execute(r);

View File

@@ -46,6 +46,7 @@ import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.contact.RecordTypes.CONTACT_INFO;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
@@ -122,7 +123,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
in = conn.getReader().getInputStream();
out = conn.getWriter().getOutputStream();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
listener.contactExchangeFailed();
tryToClose(conn);
return;
@@ -133,7 +134,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
try {
localProperties = transportPropertyManager.getLocalProperties();
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
listener.contactExchangeFailed();
tryToClose(conn);
return;
@@ -194,7 +195,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
LOG.info("End of stream");
}
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
listener.contactExchangeFailed();
tryToClose(conn);
return;
@@ -222,11 +223,11 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
LOG.info("Pseudonym exchange succeeded");
listener.contactExchangeSucceeded(remoteInfo.author);
} catch (ContactExistsException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
tryToClose(conn);
listener.duplicateContact(remoteInfo.author);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
tryToClose(conn);
listener.contactExchangeFailed();
}
@@ -307,7 +308,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
conn.getReader().dispose(true, true);
conn.getWriter().dispose(true);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}

View File

@@ -32,6 +32,8 @@ import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now;
@NotNullByDefault
class CryptoComponentImpl implements CryptoComponent {
@@ -127,16 +129,14 @@ class CryptoComponentImpl implements CryptoComponent {
throw new IllegalArgumentException();
if (!(pub instanceof Curve25519PublicKey))
throw new IllegalArgumentException();
long now = System.currentTimeMillis();
long start = now();
byte[] secret = curve25519.calculateAgreement(pub.getEncoded(),
priv.getEncoded());
// If the shared secret is all zeroes, the public key is invalid
byte allZero = 0;
for (byte b : secret) allZero |= b;
if (allZero == 0) throw new GeneralSecurityException();
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Deriving shared secret took " + duration + " ms");
logDuration(LOG, "Deriving shared secret", start);
return secret;
}

View File

@@ -10,6 +10,8 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now;
class ScryptKdf implements PasswordBasedKdf {
@@ -50,13 +52,11 @@ class ScryptKdf implements PasswordBasedKdf {
@Override
public SecretKey deriveKey(String password, byte[] salt, int cost) {
long start = System.currentTimeMillis();
long start = now();
byte[] passwordBytes = StringUtils.toUtf8(password);
SecretKey k = new SecretKey(SCrypt.generate(passwordBytes, salt, cost,
BLOCK_SIZE, PARALLELIZATION, SecretKey.LENGTH));
long duration = System.currentTimeMillis() - start;
if (LOG.isLoggable(INFO))
LOG.info("Deriving key from password took " + duration + " ms");
logDuration(LOG, "Deriving key from password", start);
return k;
}
}

View File

@@ -16,7 +16,8 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable;
import static java.util.logging.Level.INFO;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now;
/**
* A key parser that uses the encoding defined in "SEC 1: Elliptic Curve
@@ -48,7 +49,7 @@ class Sec1KeyParser implements KeyParser {
throws GeneralSecurityException {
// The validation procedure comes from SEC 1, section 3.2.2.1. Note
// that SEC 1 parameter names are used below, not RFC 5639 names
long now = System.currentTimeMillis();
long start = now();
if (encodedKey.length != publicKeyBytes)
throw new GeneralSecurityException();
// The first byte must be 0x04
@@ -80,16 +81,14 @@ class Sec1KeyParser implements KeyParser {
// Construct a public key from the point (x, y) and the params
ECPublicKeyParameters k = new ECPublicKeyParameters(pub, params);
PublicKey p = new Sec1PublicKey(k);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Parsing public key took " + duration + " ms");
logDuration(LOG, "Parsing public key", start);
return p;
}
@Override
public PrivateKey parsePrivateKey(byte[] encodedKey)
throws GeneralSecurityException {
long now = System.currentTimeMillis();
long start = now();
if (encodedKey.length != privateKeyBytes)
throw new GeneralSecurityException();
BigInteger d = new BigInteger(1, encodedKey); // Positive signum
@@ -99,9 +98,7 @@ class Sec1KeyParser implements KeyParser {
// Construct a private key from the private value and the params
ECPrivateKeyParameters k = new ECPrivateKeyParameters(d, params);
PrivateKey p = new Sec1PrivateKey(k, keyBits);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Parsing private key took " + duration + " ms");
logDuration(LOG, "Parsing private key", start);
return p;
}
}

View File

@@ -68,13 +68,15 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
@ThreadSafe
@NotNullByDefault
@@ -108,7 +110,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
try {
close();
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
return reopened;
@@ -125,13 +127,13 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
// Don't allow reentrant locking
if (lock.getReadHoldCount() > 0) throw new IllegalStateException();
if (lock.getWriteHoldCount() > 0) throw new IllegalStateException();
long start = System.currentTimeMillis();
if (readOnly) lock.readLock().lock();
else lock.writeLock().lock();
if (LOG.isLoggable(FINE)) {
long duration = System.currentTimeMillis() - start;
if (readOnly) LOG.fine("Waited " + duration + " ms for read lock");
else LOG.fine("Waited " + duration + " ms for write lock");
long start = now();
if (readOnly) {
lock.readLock().lock();
logDuration(LOG, "Waiting for read lock", start);
} else {
lock.writeLock().lock();
logDuration(LOG, "Waiting for write lock", start);
}
try {
return new Transaction(db.startTransaction(), readOnly);

View File

@@ -66,6 +66,7 @@ import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPACE;
import static org.briarproject.bramble.db.DatabaseConstants.SCHEMA_VERSION_KEY;
import static org.briarproject.bramble.db.ExponentialBackoff.calculateExpiry;
import static org.briarproject.bramble.util.LogUtils.logException;
/**
* A generic database implementation that can be used with any JDBC-compatible
@@ -404,7 +405,7 @@ abstract class JdbcDatabase implements Database<Connection> {
try {
if (rs != null) rs.close();
} catch (SQLException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -412,7 +413,7 @@ abstract class JdbcDatabase implements Database<Connection> {
try {
if (s != null) s.close();
} catch (SQLException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -509,12 +510,11 @@ abstract class JdbcDatabase implements Database<Connection> {
}
} catch (SQLException e) {
// Try to close the connection
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
try {
txn.close();
} catch (SQLException e1) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e1.toString(), e1);
logException(LOG, WARNING, e1);
}
// Whatever happens, allow the database to close
connectionsLock.lock();

View File

@@ -10,6 +10,7 @@ import java.util.logging.Logger;
import javax.annotation.Nullable;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
class Migration38_39 implements Migration<Connection> {
@@ -48,7 +49,7 @@ class Migration38_39 implements Migration<Connection> {
try {
if (s != null) s.close();
} catch (SQLException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
}

View File

@@ -31,6 +31,7 @@ import javax.annotation.Nullable;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.CONNECTION_TIMEOUT;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
class KeyAgreementConnector {
@@ -134,7 +135,7 @@ class KeyAgreementConnector {
Thread.currentThread().interrupt();
return null;
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return null;
} finally {
stopListening();

View File

@@ -28,6 +28,7 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@@ -120,13 +121,11 @@ class KeyAgreementTaskImpl extends Thread implements KeyAgreementTask,
// Broadcast result to caller
eventBus.broadcast(new KeyAgreementFinishedEvent(result));
} catch (AbortException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
// Notify caller that the protocol was aborted
eventBus.broadcast(new KeyAgreementAbortedEvent(e.receivedAbort));
} catch (IOException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
// Notify caller that the connection failed
eventBus.broadcast(new KeyAgreementFailedEvent());
}

View File

@@ -20,6 +20,7 @@ import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PR
import static org.briarproject.bramble.api.keyagreement.RecordTypes.ABORT;
import static org.briarproject.bramble.api.keyagreement.RecordTypes.CONFIRM;
import static org.briarproject.bramble.api.keyagreement.RecordTypes.KEY;
import static org.briarproject.bramble.util.LogUtils.logException;
/**
* Handles the sending and receiving of BQP records.
@@ -72,7 +73,7 @@ class KeyAgreementTransport {
try {
writeRecord(ABORT, new byte[0]);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
exception = true;
}
tryToClose(exception);
@@ -83,7 +84,7 @@ class KeyAgreementTransport {
kac.getConnection().getReader().dispose(exception, true);
kac.getConnection().getWriter().dispose(exception);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}

View File

@@ -30,6 +30,7 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.MIGRATING_DATABASE;
@@ -43,6 +44,9 @@ import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResul
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.DB_ERROR;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SERVICE_ERROR;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
@ThreadSafe
@NotNullByDefault
@@ -101,24 +105,20 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
}
private LocalAuthor createLocalAuthor(String nickname) {
long now = System.currentTimeMillis();
long start = now();
KeyPair keyPair = crypto.generateSignatureKeyPair();
byte[] publicKey = keyPair.getPublic().getEncoded();
byte[] privateKey = keyPair.getPrivate().getEncoded();
LocalAuthor localAuthor = authorFactory
.createLocalAuthor(nickname, publicKey, privateKey);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Creating local author took " + duration + " ms");
logDuration(LOG, "Creating local author", start);
return localAuthor;
}
private void registerLocalAuthor(LocalAuthor author) throws DbException {
long now = System.currentTimeMillis();
long start = now();
identityManager.registerLocalAuthor(author);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Registering local author took " + duration + " ms");
logDuration(LOG, "Registering local author", start);
}
@Override
@@ -129,15 +129,11 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
}
try {
LOG.info("Starting services");
long start = System.currentTimeMillis();
long start = now();
boolean reopened = db.open(this);
long duration = System.currentTimeMillis() - start;
if (LOG.isLoggable(INFO)) {
if (reopened)
LOG.info("Reopening database took " + duration + " ms");
else LOG.info("Creating database took " + duration + " ms");
}
if (reopened) logDuration(LOG, "Reopening database", start);
else logDuration(LOG, "Creating database", start);
if (nickname != null) {
registerLocalAuthor(createLocalAuthor(nickname));
@@ -150,13 +146,11 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
Transaction txn = db.startTransaction(false);
try {
for (Client c : clients) {
start = System.currentTimeMillis();
start = now();
c.createLocalState(txn);
duration = System.currentTimeMillis() - start;
if (LOG.isLoggable(INFO)) {
LOG.info("Starting client "
+ c.getClass().getSimpleName()
+ " took " + duration + " ms");
if (LOG.isLoggable(FINE)) {
logDuration(LOG, "Starting client "
+ c.getClass().getSimpleName(), start);
}
}
db.commitTransaction(txn);
@@ -164,12 +158,11 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
db.endTransaction(txn);
}
for (Service s : services) {
start = System.currentTimeMillis();
start = now();
s.startService();
duration = System.currentTimeMillis() - start;
if (LOG.isLoggable(INFO)) {
LOG.info("Starting service " + s.getClass().getSimpleName()
+ " took " + duration + " ms");
if (LOG.isLoggable(FINE)) {
logDuration(LOG, "Starting service "
+ s.getClass().getSimpleName(), start);
}
}
@@ -178,16 +171,16 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
eventBus.broadcast(new LifecycleEvent(RUNNING));
return SUCCESS;
} catch (DataTooOldException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return DATA_TOO_OLD_ERROR;
} catch (DataTooNewException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return DATA_TOO_NEW_ERROR;
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return DB_ERROR;
} catch (ServiceException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return SERVICE_ERROR;
} finally {
startStopSemaphore.release();
@@ -213,29 +206,26 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
state = STOPPING;
eventBus.broadcast(new LifecycleEvent(STOPPING));
for (Service s : services) {
long start = System.currentTimeMillis();
long start = now();
s.stopService();
long duration = System.currentTimeMillis() - start;
if (LOG.isLoggable(INFO)) {
LOG.info("Stopping service " + s.getClass().getSimpleName()
+ " took " + duration + " ms");
if (LOG.isLoggable(FINE)) {
logDuration(LOG, "Stopping service "
+ s.getClass().getSimpleName(), start);
}
}
for (ExecutorService e : executors) {
if (LOG.isLoggable(INFO)) {
LOG.info("Stopping executor "
if (LOG.isLoggable(FINE)) {
LOG.fine("Stopping executor "
+ e.getClass().getSimpleName());
}
e.shutdownNow();
}
long start = System.currentTimeMillis();
long start = now();
db.close();
long duration = System.currentTimeMillis() - start;
if (LOG.isLoggable(INFO))
LOG.info("Closing database took " + duration + " ms");
logDuration(LOG, "Closing database", start);
shutdownLatch.countDown();
} catch (DbException | ServiceException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
} finally {
startStopSemaphore.release();
}

View File

@@ -27,6 +27,7 @@ import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
import static org.briarproject.bramble.util.LogUtils.logException;
class ConnectionManagerImpl implements ConnectionManager {
@@ -135,7 +136,7 @@ class ConnectionManagerImpl implements ConnectionManager {
byte[] tag = readTag(reader);
ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException | DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
disposeReader(true, false);
return;
}
@@ -151,7 +152,7 @@ class ConnectionManagerImpl implements ConnectionManager {
createIncomingSession(ctx, reader).run();
disposeReader(false, true);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
disposeReader(true, true);
} finally {
connectionRegistry.unregisterConnection(contactId, transportId,
@@ -163,7 +164,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try {
reader.dispose(exception, recognised);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
}
@@ -188,7 +189,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try {
ctx = keyManager.getStreamContext(contactId, transportId);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
disposeWriter(true);
return;
}
@@ -204,7 +205,7 @@ class ConnectionManagerImpl implements ConnectionManager {
createSimplexOutgoingSession(ctx, writer).run();
disposeWriter(false);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
disposeWriter(true);
} finally {
connectionRegistry.unregisterConnection(contactId, transportId,
@@ -216,7 +217,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try {
writer.dispose(exception);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
}
@@ -246,7 +247,7 @@ class ConnectionManagerImpl implements ConnectionManager {
byte[] tag = readTag(reader);
ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException | DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
disposeReader(true, false);
return;
}
@@ -265,7 +266,7 @@ class ConnectionManagerImpl implements ConnectionManager {
incomingSession.run();
disposeReader(false, true);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
disposeReader(true, true);
} finally {
connectionRegistry.unregisterConnection(contactId, transportId,
@@ -279,7 +280,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try {
ctx = keyManager.getStreamContext(contactId, transportId);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
disposeWriter(true);
return;
}
@@ -294,7 +295,7 @@ class ConnectionManagerImpl implements ConnectionManager {
outgoingSession.run();
disposeWriter(false);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
disposeWriter(true);
}
}
@@ -305,7 +306,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try {
reader.dispose(exception, recognised);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -317,7 +318,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try {
writer.dispose(exception);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
}
@@ -347,7 +348,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try {
ctx = keyManager.getStreamContext(contactId, transportId);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
disposeWriter(true);
return;
}
@@ -364,7 +365,7 @@ class ConnectionManagerImpl implements ConnectionManager {
outgoingSession.run();
disposeWriter(false);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
disposeWriter(true);
}
}
@@ -376,7 +377,7 @@ class ConnectionManagerImpl implements ConnectionManager {
byte[] tag = readTag(reader);
ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException | DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
disposeReader(true, false);
return;
}
@@ -400,7 +401,7 @@ class ConnectionManagerImpl implements ConnectionManager {
incomingSession.run();
disposeReader(false, true);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
disposeReader(true, true);
} finally {
connectionRegistry.unregisterConnection(contactId, transportId,
@@ -414,7 +415,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try {
reader.dispose(exception, recognised);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -426,7 +427,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try {
writer.dispose(exception);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
}

View File

@@ -49,8 +49,12 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
@ThreadSafe
@NotNullByDefault
@@ -205,17 +209,16 @@ class PluginManagerImpl implements PluginManager, Service {
@Override
public void run() {
try {
long start = System.currentTimeMillis();
long start = now();
plugin.start();
long duration = System.currentTimeMillis() - start;
if (LOG.isLoggable(INFO)) {
LOG.info("Starting plugin " + plugin.getId() + " took " +
duration + " ms");
if (LOG.isLoggable(FINE)) {
logDuration(LOG, "Starting plugin " + plugin.getId(),
start);
}
} catch (PluginException e) {
if (LOG.isLoggable(WARNING)) {
LOG.warning("Plugin " + plugin.getId() + " did not start");
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
} finally {
startLatch.countDown();
@@ -243,12 +246,11 @@ class PluginManagerImpl implements PluginManager, Service {
// Wait for the plugin to finish starting
startLatch.await();
// Stop the plugin
long start = System.currentTimeMillis();
long start = now();
plugin.stop();
long duration = System.currentTimeMillis() - start;
if (LOG.isLoggable(INFO)) {
LOG.info("Stopping plugin " + plugin.getId()
+ " took " + duration + " ms");
if (LOG.isLoggable(FINE)) {
logDuration(LOG, "Stopping plugin " + plugin.getId(),
start);
}
} catch (InterruptedException e) {
LOG.warning("Interrupted while waiting for plugin to stop");
@@ -256,7 +258,7 @@ class PluginManagerImpl implements PluginManager, Service {
} catch (PluginException e) {
if (LOG.isLoggable(WARNING)) {
LOG.warning("Plugin " + plugin.getId() + " did not stop");
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
} finally {
stopLatch.countDown();
@@ -278,7 +280,7 @@ class PluginManagerImpl implements PluginManager, Service {
try {
return settingsManager.getSettings(id.getString());
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return new Settings();
}
}
@@ -288,7 +290,7 @@ class PluginManagerImpl implements PluginManager, Service {
try {
return transportPropertyManager.getLocalProperties(id);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return new TransportProperties();
}
}
@@ -298,7 +300,7 @@ class PluginManagerImpl implements PluginManager, Service {
try {
settingsManager.mergeSettings(s, id.getString());
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -307,7 +309,7 @@ class PluginManagerImpl implements PluginManager, Service {
try {
transportPropertyManager.mergeLocalProperties(id, p);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}

View File

@@ -41,6 +41,7 @@ import javax.annotation.concurrent.ThreadSafe;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@ThreadSafe
@NotNullByDefault
@@ -134,7 +135,7 @@ class Poller implements EventListener {
if (w != null)
connectionManager.manageOutgoingConnection(c, t, w);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -150,7 +151,7 @@ class Poller implements EventListener {
if (d != null)
connectionManager.manageOutgoingConnection(c, t, d);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -211,7 +212,7 @@ class Poller implements EventListener {
remote.keySet().removeAll(connected);
if (!remote.isEmpty()) p.poll(remote);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}

View File

@@ -13,6 +13,7 @@ import javax.annotation.concurrent.ThreadSafe;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
@ThreadSafe
@@ -92,7 +93,7 @@ class BluetoothConnectionLimiterImpl implements BluetoothConnectionLimiter {
conn.getWriter().dispose(false);
conn.getReader().dispose(false, false);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}

View File

@@ -43,6 +43,7 @@ import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENA
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_ADDRESS;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_UUID;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
@MethodsNotNullByDefault
@@ -169,7 +170,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
try {
ss = openServerSocket(contactConnectionsUuid);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return;
}
if (!isRunning() || !shouldAllowContactConnections()) {
@@ -336,7 +337,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
try {
ss = openServerSocket(uuid);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return null;
}
if (!isRunning()) {

View File

@@ -15,6 +15,7 @@ import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.plugin.FileConstants.PROP_PATH;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@NotNullByDefault
@@ -51,7 +52,7 @@ abstract class FilePlugin implements SimplexPlugin {
FileInputStream in = new FileInputStream(file);
return new FileTransportReader(file, in, this);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return null;
}
}
@@ -70,7 +71,7 @@ abstract class FilePlugin implements SimplexPlugin {
FileOutputStream out = new FileOutputStream(file);
return new FileTransportWriter(file, out, this);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return null;
}
}

View File

@@ -9,6 +9,7 @@ import java.io.InputStream;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
class FileTransportReader implements TransportConnectionReader {
@@ -36,7 +37,7 @@ class FileTransportReader implements TransportConnectionReader {
try {
in.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
plugin.readerFinished(file, exception, recognised);
}

View File

@@ -9,6 +9,7 @@ import java.io.OutputStream;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
class FileTransportWriter implements TransportConnectionWriter {
@@ -46,7 +47,7 @@ class FileTransportWriter implements TransportConnectionWriter {
try {
out.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
plugin.writerFinished(file, exception);
}

View File

@@ -35,6 +35,7 @@ import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_LAN_IP_PORTS;
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PROP_IP_PORTS;
import static org.briarproject.bramble.util.ByteUtils.MAX_16_BIT_UNSIGNED;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
@NotNullByDefault
@@ -295,7 +296,7 @@ class LanTcpPlugin extends TcpPlugin {
try {
ss.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
}

View File

@@ -17,6 +17,7 @@ import javax.xml.parsers.ParserConfigurationException;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubInetAddress;
@ThreadSafe
@@ -59,7 +60,7 @@ class PortMapperImpl implements PortMapper {
if (externalString != null)
external = InetAddress.getByName(externalString);
} catch (IOException | SAXException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
return new MappingResult(internal, external, port, succeeded);
}
@@ -76,7 +77,7 @@ class PortMapperImpl implements PortMapper {
try {
d.discover();
} catch (IOException | SAXException | ParserConfigurationException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
gateway = d.getValidGateway();
}
@@ -87,7 +88,7 @@ class PortMapperImpl implements PortMapper {
if (LOG.isLoggable(INFO))
LOG.info("Deleted mapping for port " + port);
} catch (IOException | SAXException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
}

View File

@@ -37,6 +37,7 @@ import javax.annotation.Nullable;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
@MethodsNotNullByDefault
@@ -152,7 +153,7 @@ abstract class TcpPlugin implements DuplexPlugin {
try {
if (ss != null) ss.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
} finally {
callback.transportDisabled();
}
@@ -306,7 +307,7 @@ abstract class TcpPlugin implements DuplexPlugin {
try {
ifaces = Collections.list(NetworkInterface.getNetworkInterfaces());
} catch (SocketException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return Collections.emptyList();
}
List<InetAddress> addrs = new ArrayList<>();

View File

@@ -16,6 +16,7 @@ import java.util.logging.Logger;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@@ -78,7 +79,7 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
Thread.currentThread().interrupt();
running = false;
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
running = false;
}
});

View File

@@ -32,6 +32,7 @@ import javax.inject.Inject;
import javax.net.SocketFactory;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@Immutable
@NotNullByDefault
@@ -132,7 +133,7 @@ class DevReporterImpl implements DevReporter, EventListener {
try {
if (c != null) c.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -140,7 +141,7 @@ class DevReporterImpl implements DevReporter, EventListener {
try {
if (s != null) s.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
}

View File

@@ -42,6 +42,7 @@ import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING;
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
import static org.briarproject.bramble.util.LogUtils.logException;
/**
* An outgoing {@link SyncSession} suitable for duplex transports. The session
@@ -240,7 +241,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
LOG.info("Generated ack: " + (a != null));
if (a != null) writerTasks.add(new WriteAck(a));
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
interrupt();
}
}
@@ -287,7 +288,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
LOG.info("Generated batch: " + (b != null));
if (b != null) writerTasks.add(new WriteBatch(b));
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
interrupt();
}
}
@@ -334,7 +335,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
LOG.info("Generated offer: " + (o != null));
if (o != null) writerTasks.add(new WriteOffer(o));
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
interrupt();
}
}
@@ -379,7 +380,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
LOG.info("Generated request: " + (r != null));
if (r != null) writerTasks.add(new WriteRequest(r));
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
interrupt();
}
}

View File

@@ -28,6 +28,7 @@ import javax.annotation.concurrent.ThreadSafe;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING;
import static org.briarproject.bramble.util.LogUtils.logException;
/**
* An incoming {@link SyncSession}.
@@ -127,7 +128,7 @@ class IncomingSession implements SyncSession, EventListener {
db.endTransaction(txn);
}
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
interrupt();
}
}
@@ -153,7 +154,7 @@ class IncomingSession implements SyncSession, EventListener {
db.endTransaction(txn);
}
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
interrupt();
}
}
@@ -179,7 +180,7 @@ class IncomingSession implements SyncSession, EventListener {
db.endTransaction(txn);
}
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
interrupt();
}
}
@@ -205,7 +206,7 @@ class IncomingSession implements SyncSession, EventListener {
db.endTransaction(txn);
}
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
interrupt();
}
}

View File

@@ -32,6 +32,7 @@ import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING;
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
import static org.briarproject.bramble.util.LogUtils.logException;
/**
* An outgoing {@link SyncSession} suitable for simplex transports. The session
@@ -139,7 +140,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
if (a == null) decrementOutstandingQueries();
else writerTasks.add(new WriteAck(a));
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
interrupt();
}
}
@@ -184,7 +185,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
if (b == null) decrementOutstandingQueries();
else writerTasks.add(new WriteBatch(b));
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
interrupt();
}
}

View File

@@ -40,6 +40,7 @@ import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
import static org.briarproject.bramble.util.LogUtils.logException;
@ThreadSafe
@NotNullByDefault
@@ -110,7 +111,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
}
validateNextMessageAsync(unvalidated);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -144,7 +145,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
LOG.info("Group removed before validation");
validateNextMessageAsync(unvalidated);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -165,7 +166,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
}
deliverNextPendingMessageAsync(pending);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -231,7 +232,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
LOG.info("Group removed before delivery");
deliverNextPendingMessageAsync(pending);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -252,8 +253,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
storeMessageContextAsync(m, g.getClientId(),
g.getMajorVersion(), context);
} catch (InvalidMessageException e) {
if (LOG.isLoggable(INFO))
LOG.log(INFO, e.toString(), e);
logException(LOG, INFO, e);
Queue<MessageId> invalidate = new LinkedList<>();
invalidate.add(m.getId());
invalidateNextMessageAsync(invalidate);
@@ -326,7 +326,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
} catch (NoSuchGroupException e) {
LOG.info("Group removed during validation");
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -377,7 +377,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
}
shareNextMessageAsync(toShare);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -412,7 +412,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
LOG.info("Group removed before sharing");
shareNextMessageAsync(toShare);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -440,7 +440,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
LOG.info("Message removed before invalidation");
invalidateNextMessageAsync(invalidate);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -492,7 +492,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
} catch (NoSuchGroupException e) {
LOG.info("Group removed before validation");
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}

View File

@@ -13,6 +13,7 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@Immutable
@NotNullByDefault
@@ -49,7 +50,7 @@ class LinuxSecureRandomProvider extends AbstractSecureRandomProvider {
out.close();
} catch (IOException e) {
// On some devices /dev/urandom isn't writable - this isn't fatal
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}

View File

@@ -10,6 +10,7 @@ import java.security.SecureRandomSpi;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
public class LinuxSecureRandomSpi extends SecureRandomSpi {
@@ -39,7 +40,7 @@ public class LinuxSecureRandomSpi extends SecureRandomSpi {
out.close();
} catch (IOException e) {
// On some devices /dev/urandom isn't writable - this isn't fatal
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}

View File

@@ -36,6 +36,7 @@ import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOC
import static org.briarproject.bramble.api.transport.TransportConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
import static org.briarproject.bramble.util.ByteUtils.MAX_32_BIT_UNSIGNED;
import static org.briarproject.bramble.util.LogUtils.logException;
@ThreadSafe
@NotNullByDefault
@@ -169,7 +170,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
db.endTransaction(txn);
}
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}

View File

@@ -28,6 +28,7 @@ import javax.annotation.concurrent.ThreadSafe;
import static com.sun.jna.Library.OPTION_FUNCTION_MAPPER;
import static com.sun.jna.Library.OPTION_TYPE_MAPPER;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@ThreadSafe
@NotNullByDefault
@@ -141,7 +142,7 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl {
user32.DispatchMessage(msg);
}
} catch (UnsatisfiedLinkError e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
}

View File

@@ -19,6 +19,7 @@ import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.isValidMac;
@MethodsNotNullByDefault
@@ -85,7 +86,7 @@ class JavaBluetoothPlugin extends BluetoothPlugin<StreamConnectionNotifier> {
try {
if (ss != null) ss.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}

View File

@@ -27,6 +27,7 @@ import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static jssc.SerialPort.PURGE_RXCLEAR;
import static jssc.SerialPort.PURGE_TXCLEAR;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@@ -136,7 +137,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
try {
if (port != null) port.closePort();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -327,7 +328,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
}
}
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
@@ -394,8 +395,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
try {
answer();
} catch (IOException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}

View File

@@ -23,6 +23,7 @@ import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@@ -81,7 +82,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
running = true;
return;
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
throw new PluginException();
@@ -94,7 +95,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
try {
modem.stop();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
}
@@ -131,7 +132,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
LOG.info("Initialised modem on " + portName);
return true;
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
running = false;
@@ -157,7 +158,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
try {
if (!modem.dial(number)) return null;
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
resetModem();
return null;
}
@@ -209,7 +210,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
try {
modem.hangUp();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
exception = true;
}
if (exception) resetModem();

View File

@@ -4,3 +4,4 @@ build
local.properties
.settings
src/main/assets/*.zip
src/main/res/values-iw

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Ebene_1"
x="0px"
y="0px"
viewBox="0 0 24 24"
xml:space="preserve"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="notification_ongoing.svg"
width="24"
height="24"><metadata
id="metadata61"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs59" /><sodipodi:namedview
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1020"
id="namedview57"
showgrid="false"
inkscape:zoom="11.466748"
inkscape:cx="-4.790356"
inkscape:cy="17.536496"
inkscape:window-x="1442"
inkscape:window-y="24"
inkscape:window-maximized="0"
inkscape:current-layer="Ebene_1"
units="px" /><style
type="text/css"
id="style3">
.st0{fill:#FFFFFF;}
.st1{display:none;fill:#87C214;}
.st2{fill:#87C214;}
.st3{display:none;fill:#FFFFFF;}
.st4{fill:#95D220;}
.st5{display:none;fill:#95D220;}
</style><path
style="fill:#ffffff;stroke-width:0.07272727"
d="M 12,0 A 12,12 0 0 0 0,12 12,12 0 0 0 12,24 12,12 0 0 0 24,12 12,12 0 0 0 12,0 Z M 8.1454545,3.4764204 h 0.6036931 c 0.7054546,0 1.2872164,0.5817614 1.2872164,1.287216 V 6.4 H 6.8582386 V 4.7636364 c 0,-0.7054546 0.5817614,-1.287216 1.2872159,-1.287216 z m 7.0545455,0 h 0.603693 c 0.712727,0 1.287216,0.5817614 1.287216,1.287216 V 13.454545 H 13.912784 V 4.7636364 c 0,-0.7054546 0.581761,-1.287216 1.287216,-1.287216 z M 4.7127841,6.9090909 H 13.403693 V 10.087216 H 4.7127841 c -0.7127273,0 -1.287358,-0.5817618 -1.287358,-1.2872156 V 8.1963069 c 0,-0.7127273 0.5819034,-1.287216 1.287358,-1.287216 z m 12.8872159,0 h 1.636364 c 0.705454,0 1.279943,0.5817615 1.287216,1.287216 v 0.6036935 c 0,0.7127269 -0.581762,1.2872156 -1.287216,1.2872156 H 17.6 Z M 6.8582386,10.596307 h 3.1781254 v 8.690909 c 0,0.705454 -0.5817618,1.287358 -1.2872164,1.287358 H 8.1454545 c -0.7127272,0 -1.2872159,-0.581904 -1.2872159,-1.287358 z m -2.1454545,3.367329 h 1.6363636 v 3.178125 H 4.7127841 c -0.7127273,0 -1.287358,-0.581761 -1.287358,-1.287216 v -0.603693 c 0,-0.712727 0.5819034,-1.287216 1.287358,-1.287216 z m 5.8326709,0 h 8.690909 c 0.705454,0 1.279943,0.581761 1.287216,1.287216 v 0.603693 c 0,0.705455 -0.581762,1.287216 -1.287216,1.287216 h -8.690909 z m 3.367329,3.687216 h 3.178125 v 1.636364 c 0,0.705454 -0.581761,1.287358 -1.287216,1.287358 H 15.2 c -0.705455,0 -1.287216,-0.581904 -1.287216,-1.287358 z"
id="circle7"
inkscape:connector-curvature="0" /></svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Ebene_1"
x="0px"
y="0px"
viewBox="0 0 24 24"
xml:space="preserve"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="notification_reminder.svg"
width="24"
height="24"><metadata
id="metadata61"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs59" /><sodipodi:namedview
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1020"
id="namedview57"
showgrid="false"
inkscape:zoom="32.43286"
inkscape:cx="6.4172501"
inkscape:cy="12.231457"
inkscape:window-x="1442"
inkscape:window-y="24"
inkscape:window-maximized="0"
inkscape:current-layer="Ebene_1"
units="px" /><style
type="text/css"
id="style3">
.st0{fill:#FFFFFF;}
.st1{display:none;fill:#87C214;}
.st2{fill:#87C214;}
.st3{display:none;fill:#FFFFFF;}
.st4{fill:#95D220;}
.st5{display:none;fill:#95D220;}
</style><path
style="display:inline;fill:#ffffff;stroke-width:0.07272727"
d="M 12 0 A 12 12 0 0 0 4.875 2.3613281 L 6.9316406 4.4160156 C 7.0875805 3.8805807 7.5639651 3.4765625 8.1464844 3.4765625 L 8.7480469 3.4765625 C 9.4535014 3.4765625 10.035156 4.0582174 10.035156 4.7636719 L 10.035156 6.4003906 L 8.9140625 6.4003906 L 9.4238281 6.9101562 L 13.404297 6.9101562 L 13.404297 10.085938 L 12.601562 10.085938 L 13.914062 11.398438 L 13.914062 4.7636719 C 13.914062 4.0582174 14.495717 3.4765625 15.201172 3.4765625 L 15.802734 3.4765625 C 16.515461 3.4765625 17.089844 4.0582174 17.089844 4.7636719 L 17.089844 13.455078 L 15.96875 13.455078 L 16.478516 13.964844 L 19.236328 13.964844 C 19.941782 13.964844 20.516165 14.546498 20.523438 15.251953 L 20.523438 15.853516 C 20.523438 16.436036 20.119418 16.91242 19.583984 17.068359 L 21.638672 19.125 A 12 12 0 0 0 24 12 A 12 12 0 0 0 12 0 z M 1.2617188 1.3632812 L 0 2.6269531 L 2.3125 4.9472656 A 12 12 0 0 0 0 12 A 12 12 0 0 0 12 24 A 12 12 0 0 0 19.027344 21.707031 L 21.314453 24 L 22.576172 22.734375 L 2.7519531 2.8554688 L 1.9863281 2.0898438 L 1.2617188 1.3632812 z M 17.599609 6.9101562 L 19.236328 6.9101562 C 19.941782 6.9101562 20.516165 7.4918111 20.523438 8.1972656 L 20.523438 8.7988281 C 20.523438 9.511555 19.941782 10.085937 19.236328 10.085938 L 17.599609 10.085938 L 17.599609 6.9101562 z M 4.359375 6.9980469 L 7.4394531 10.085938 L 4.7128906 10.085938 C 4.0001632 10.085938 3.4257813 9.504282 3.4257812 8.7988281 L 3.4257812 8.1972656 C 3.4257812 7.6133228 3.8294199 7.1540656 4.359375 6.9980469 z M 6.859375 10.595703 L 7.9472656 10.595703 L 10.035156 12.689453 L 10.035156 19.287109 C 10.035156 19.992562 9.4535014 20.574219 8.7480469 20.574219 L 8.1464844 20.574219 C 7.4337573 20.574219 6.859375 19.992563 6.859375 19.287109 L 6.859375 10.595703 z M 4.7128906 13.964844 L 6.3496094 13.964844 L 6.3496094 17.140625 L 4.7128906 17.140625 C 4.0001632 17.140625 3.4257813 16.558971 3.4257812 15.853516 L 3.4257812 15.251953 C 3.4257812 14.539226 4.007436 13.964844 4.7128906 13.964844 z M 10.544922 13.964844 L 11.306641 13.964844 L 14.474609 17.140625 L 10.544922 17.140625 L 10.544922 13.964844 z M 13.914062 17.650391 L 14.982422 17.650391 L 16.992188 19.666016 C 16.827053 20.182975 16.371277 20.574219 15.802734 20.574219 L 15.201172 20.574219 C 14.495717 20.574219 13.914063 19.992563 13.914062 19.287109 L 13.914062 17.650391 z "
id="circle7" /></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -22,7 +22,7 @@ dependencies {
implementation "com.android.support:support-annotations:$supportVersion"
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation('ch.acra:acra:4.8.5') {
implementation('ch.acra:acra:4.9.1') {
exclude module: 'support-v4'
exclude module: 'support-annotations'
}
@@ -61,7 +61,7 @@ dependencyVerification {
'android.arch.lifecycle:viewmodel:1.1.0:viewmodel-1.1.0.aar:6407c93a5ea9850661dca42a0068d6f3deccefd7228ee69bae1c35d70cbc2557',
'backport-util-concurrent:backport-util-concurrent:3.1:backport-util-concurrent-3.1.jar:f5759b7fcdfc83a525a036deedcbd32e5b536b625ebc282426f16ca137eb5902',
'cglib:cglib:3.2.0:cglib-3.2.0.jar:adb13bab79712ad6bdf1bd59f2a3918018a8016e722e8a357065afb9e6690861',
'ch.acra:acra:4.8.5:acra-4.8.5.aar:afd5b28934d5166b55f261c85685ad59e8a4ebe9ca1960906afaa8c76d8dc9eb',
'ch.acra:acra:4.9.1:acra-4.9.1.aar:d2762968c448757a7d6acc9f141881d9632f664988e9723ece33b5f7c79f3bc9',
'classworlds:classworlds:1.1-alpha-2:classworlds-1.1-alpha-2.jar:2bf4e59f3acd106fea6145a9a88fe8956509f8b9c0fdd11eb96fee757269e3f3',
'com.almworks.sqlite4java:sqlite4java:0.282:sqlite4java-0.282.jar:9e1d8dd83ca6003f841e3af878ce2dc7c22497493a7bb6d1b62ec1b0d0a83c05',
'com.android.support.constraint:constraint-layout-solver:1.1.0:constraint-layout-solver-1.1.0.jar:fcb4c7d705754ca3d69b1b2c3caf445a425599fda8caabbcf855d98ea0663e4e',
@@ -82,32 +82,32 @@ dependencyVerification {
'com.android.support:support-v4:27.1.1:support-v4-27.1.1.aar:4f41dfc3e89f2738e45c86264a85c0934d055ee8ebe2020e23c97f303b80a48b',
'com.android.support:support-vector-drawable:27.1.1:support-vector-drawable-27.1.1.aar:1c0f421114cf4627cf208776d6eb4f76340c78b7e96fe6e12b3e6eb950caf1b9',
'com.android.support:transition:27.1.1:transition-27.1.1.aar:c0765b2f3c78696567ec5b3f519d22da1e3df11ac994625adf4bb4dc571caacc',
'com.android.tools.analytics-library:protos:26.1.2:protos-26.1.2.jar:52672a0b42b572a06aecc3535d5068eb46c0e15d129b9f1085d3c16a1da5cdbb',
'com.android.tools.analytics-library:shared:26.1.2:shared-26.1.2.jar:5c7e0eda18c6f87feeb83628c707e8aaa3298b41fb72e38efe31ad1675f9e8e9',
'com.android.tools.analytics-library:tracker:26.1.2:tracker-26.1.2.jar:06f97aa0adf44ffb06f8681c6a79d9be153a08f61d21eddc42b8d3db96df4282',
'com.android.tools.build:apksig:3.1.2:apksig-3.1.2.jar:40696a4559124d1d57873d208857eee059d48859239d569c7d18374ac644a8be',
'com.android.tools.build:builder-model:3.1.2:builder-model-3.1.2.jar:d49bfa2a135c9562b6ca7aa4342036cfa1582c7074c2d1d93d1dae8b3a134e17',
'com.android.tools.build:builder-test-api:3.1.2:builder-test-api-3.1.2.jar:dfe2a50b740d41b11189101062434d4283d18647e89a492ad51710c719363e9f',
'com.android.tools.build:builder:3.1.2:builder-3.1.2.jar:b60f825a42e2efe8433619fbc759f3d9effecab718279048d36881188ceb1d14',
'com.android.tools.build:gradle-api:3.1.2:gradle-api-3.1.2.jar:e58bcc5b893e4583ab0f5c8ef89c4dbcce202b405a9d7fcc116d21e5357d4893',
'com.android.tools.build:manifest-merger:26.1.2:manifest-merger-26.1.2.jar:9c61c27ea5266573107b954acf1216d398f4d7e7ae6fad6409d6b2b767eb091c',
'com.android.tools.ddms:ddmlib:26.1.2:ddmlib-26.1.2.jar:18a2a5fbef36882f07d03c2b9e59eba05cf8248177bf5cbff736e4b582804c44',
'com.android.tools.external.com-intellij:intellij-core:26.1.2:intellij-core-26.1.2.jar:37c5acf279f1ae3e85b1a5be3c9f15f43bde7b08f978eefefffb9c4035760c52',
'com.android.tools.external.com-intellij:kotlin-compiler:26.1.2:kotlin-compiler-26.1.2.jar:152df0bee7580326c77316b669a9d96e3b09efb1d45f545dce4147271b0b8944',
'com.android.tools.external.org-jetbrains:uast:26.1.2:uast-26.1.2.jar:02d39582206d3f5fc0a6cb18bfd9e8b9f9c1acb805ec6dac08b4e3a56849d279',
'com.android.tools.layoutlib:layoutlib-api:26.1.2:layoutlib-api-26.1.2.jar:20220039fcc7d799f928153beff862e704457c0f55ab44258f3745ebeb662b4f',
'com.android.tools.lint:lint-api:26.1.2:lint-api-26.1.2.jar:e1d5b62b870a7c566e9877a6b96b27784a4d713f8caa07fdcb4705d47a40a1d9',
'com.android.tools.lint:lint-checks:26.1.2:lint-checks-26.1.2.jar:211e2afd58504372385d71b1e5be982c2b5121ab6fee1c04ddabeb75a8729e07',
'com.android.tools.lint:lint-gradle-api:26.1.2:lint-gradle-api-26.1.2.jar:71284f2a8b03c3e55c94511c9eb36f8184fbb85324325fc6b78abf5183f03d90',
'com.android.tools.lint:lint-gradle:26.1.2:lint-gradle-26.1.2.jar:855f0c82b7fc690df1b7319c0774f7517f7f8f5dd4eee1f6077dcf50e07c6240',
'com.android.tools.lint:lint-kotlin:26.1.2:lint-kotlin-26.1.2.jar:1e591f70bcbbc11569720a9bbcca2bc1f3d4f789f01f40f642848d920643d484',
'com.android.tools.lint:lint:26.1.2:lint-26.1.2.jar:93736c62e9f1976998c2b4aa716aea0734cdb162d05502f4af7292654aedb182',
'com.android.tools:annotations:26.1.2:annotations-26.1.2.jar:72773dcaf5c4ccca828e3c8467f1b78a8a00b3cc5f8ad1aab88fcf9379928018',
'com.android.tools:common:26.1.2:common-26.1.2.jar:ea4320f0c17dcbc4491896bb705c4d25ec08bd62ef02ab0579fe154e75e788e6',
'com.android.tools:dvlib:26.1.2:dvlib-26.1.2.jar:1187aa4fb666595c96c4deb6bc0e0f4b7e396bde9f6243330b49a232946130ea',
'com.android.tools:repository:26.1.2:repository-26.1.2.jar:8b86e512ad6d32bd76989451eefe2b271f5efce6d4d65ecb173afaf14606e01a',
'com.android.tools:sdk-common:26.1.2:sdk-common-26.1.2.jar:23584720a60a21cdcb5b1ec10269e3013789d6805d153cc696c39ec7ce251896',
'com.android.tools:sdklib:26.1.2:sdklib-26.1.2.jar:d3870fafc59ab8efa70d3f9649f40ee299c8ec5b58377b06e8853d7272a5bf4e',
'com.android.tools.analytics-library:protos:26.1.3:protos-26.1.3.jar:818c9f256f141d9dafec03a1aa2b94d240b2c140acfd7ee31a8b3e6c2b9479e3',
'com.android.tools.analytics-library:shared:26.1.3:shared-26.1.3.jar:7110706c7ada96c8b6f5ca80c478291bc7899d46277de2c48527e045442401a3',
'com.android.tools.analytics-library:tracker:26.1.3:tracker-26.1.3.jar:4155424bf2ce4872da83332579a1707252bc66cbd77c5144fdc4483d0f2e1418',
'com.android.tools.build:apksig:3.1.3:apksig-3.1.3.jar:7e1f8e675a6e768e5b56405e41d6c3cc05befe62e601b04177de1029902c9c89',
'com.android.tools.build:builder-model:3.1.3:builder-model-3.1.3.jar:06ad1c422d679fc698451479cb40ba863849d67bfd1de23f6d2c16d78b024b0b',
'com.android.tools.build:builder-test-api:3.1.3:builder-test-api-3.1.3.jar:4d989f780436794f0f8b2f50e9e079b786571eac90f26c208ab2ae6d4012f389',
'com.android.tools.build:builder:3.1.3:builder-3.1.3.jar:8a1092012c89d0ec1ee2eff09c5708c71ef4482a6862df8d3a44a67fccace01c',
'com.android.tools.build:gradle-api:3.1.3:gradle-api-3.1.3.jar:01e4df521456aef66514336f1d492346730dd1fb8f6433a89f62da834941ed72',
'com.android.tools.build:manifest-merger:26.1.3:manifest-merger-26.1.3.jar:1e4fc7e932adb4607082409800e5e6fccb42e6c5360ae5990094bf522f3ada55',
'com.android.tools.ddms:ddmlib:26.1.3:ddmlib-26.1.3.jar:c54931cd68df5d1ea2923b3b320eae47cd2307a5a916bb8674c0acf93cd1d3cd',
'com.android.tools.external.com-intellij:intellij-core:26.1.3:intellij-core-26.1.3.jar:af67f5535fef2e1a28b1007a4acb8c5deb6a1e33b8afe7b11d012c9e778ebcec',
'com.android.tools.external.com-intellij:kotlin-compiler:26.1.3:kotlin-compiler-26.1.3.jar:c746d2859dc11cc05c84b692b3498d3a621e0929511f8440ee009c6557838fd4',
'com.android.tools.external.org-jetbrains:uast:26.1.3:uast-26.1.3.jar:3f3f6651d0c7685a77ecb22e9c82d6b49fdf24322c17360768dc530678f43265',
'com.android.tools.layoutlib:layoutlib-api:26.1.3:layoutlib-api-26.1.3.jar:10bc73ce706c45629872d6a999dbe12116df64e24f47ff93b7b13121ff57b4b0',
'com.android.tools.lint:lint-api:26.1.3:lint-api-26.1.3.jar:6f97323f9af8deda86278717885b5c927f3766757db89709f52d11d42b6fb751',
'com.android.tools.lint:lint-checks:26.1.3:lint-checks-26.1.3.jar:73c3d53784c9ce3e6d5968506581918e0179645d20809927ca4a001dd766b001',
'com.android.tools.lint:lint-gradle-api:26.1.3:lint-gradle-api-26.1.3.jar:7ca3c4866ec21dc21d53a9d86f752b77ace6f6c610a0c9dc877313856c733d9d',
'com.android.tools.lint:lint-gradle:26.1.3:lint-gradle-26.1.3.jar:db0c354b8f4b6f6637e31f91c564785a59ff896325331fcbc3de7458e0b6c067',
'com.android.tools.lint:lint-kotlin:26.1.3:lint-kotlin-26.1.3.jar:94e2b0f4565a241561cfb8fc1222bb3f132a3b98d2a90421dbb72ee8358e7d68',
'com.android.tools.lint:lint:26.1.3:lint-26.1.3.jar:8d5f32c989c6d191d712e90ad3ca2d1c409313599551d04d834caa44d26c78df',
'com.android.tools:annotations:26.1.3:annotations-26.1.3.jar:c950430b24ac5d58fc97e7283b8f0115f99587e76e08b4e1e2aaa780f2d77323',
'com.android.tools:common:26.1.3:common-26.1.3.jar:7c31a90581a148ab219f615a59667f0dded7fa39b248529784474da3c2274ef2',
'com.android.tools:dvlib:26.1.3:dvlib-26.1.3.jar:0cae87906f53d3f1088366a916ed180a7312b6d9919b90797f238875c8492855',
'com.android.tools:repository:26.1.3:repository-26.1.3.jar:52d4539cc68db91b261e2a33b2c8206b26e05539078758dc28cfb3854adb4f59',
'com.android.tools:sdk-common:26.1.3:sdk-common-26.1.3.jar:1948603ca9ff22c7ebb3178000bffa3a9dd2ca1cc5cb0c793cae08468b8fcfc1',
'com.android.tools:sdklib:26.1.3:sdklib-26.1.3.jar:4adcfaad9514607098d2c51503c39811112d3050f4d1e744c01c7f08f591032b',
'com.github.bumptech.glide:glide:3.8.0:glide-3.8.0.jar:750d9e7b940dc0ee48f8680623b55d46e14e8727acc922d7b156e57e7c549655',
'com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.1:accessibility-test-framework-2.1.jar:7b0aa6ed7553597ce0610684a9f7eca8021eee218f2e2f427c04a7fbf5f920bd',
'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed',
@@ -238,8 +238,8 @@ android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 26
versionCode 10007
versionName "1.0.7"
versionCode 10011
versionName "1.0.11"
applicationId "org.briarproject.briar.android"
resValue "string", "app_package", "org.briarproject.briar.android"
resValue "string", "app_name", "Briar"
@@ -285,3 +285,46 @@ android {
warning 'ExtraTranslation'
}
}
task verifyTranslations {
doLast {
def file = project.file("src/main/res/values/arrays.xml")
def arrays = new XmlParser().parse(file)
def lc = arrays.children().find { it.@name == "pref_language_values" }
def translations = []
lc.children().each { value -> translations.add(value.text()) }
def folders = ["default", "en-US"]
project.file("src/main/res").eachDir { dir ->
if (dir.name.startsWith("values-") && !dir.name.endsWith("night")) {
folders.add(dir.name.substring(7).replace("-r", "-"))
}
}
folders.each { n ->
if (!translations.remove(n) && n != 'iw') {
throw new GradleException("Translation " + n + " is missing in $file")
}
}
if (translations.size() != 0)
throw new GradleException("Translations\n" + translations.join("\n")
+ "\nhave no matching value folder")
// Some devices use iw instead of he for hebrew
def hebrew_legacy = project.file("src/main/res/values-iw")
def hebrew = project.file("src/main/res/values-he")
// Copy values-he to values-iw
if (hebrew.exists()) {
hebrew_legacy.mkdir()
copy {
from hebrew.getAbsolutePath()
into hebrew_legacy.getAbsolutePath()
}
}
}
}
project.afterEvaluate {
preBuild.dependsOn.add(verifyTranslations)
}

View File

@@ -14,6 +14,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<application
@@ -24,6 +25,14 @@
android:logo="@mipmap/ic_launcher_round"
android:theme="@style/BriarTheme">
<receiver
android:name="org.briarproject.briar.android.BootReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service
android:name="org.briarproject.briar.android.BriarService"
android:exported="false">
@@ -44,7 +53,6 @@
android:finishOnTaskLaunch="true"
android:label="@string/crash_report_title"
android:launchMode="singleInstance"
android:process=":briar_error_handler"
android:theme="@style/BriarTheme.NoActionBar"
android:windowSoftInputMode="stateHidden">
</activity>
@@ -301,7 +309,7 @@
</activity>
<activity
android:name="org.briarproject.briar.android.keyagreement.KeyAgreementActivity"
android:name="org.briarproject.briar.android.keyagreement.ContactExchangeActivity"
android:label="@string/add_contact_title"
android:theme="@style/BriarTheme.NoActionBar"
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity">

View File

@@ -150,6 +150,8 @@ public interface AndroidComponent
@IoExecutor
Executor ioExecutor();
void inject(BootReceiver briarService);
void inject(BriarService briarService);
void inject(BriarReportSender briarReportSender);

View File

@@ -70,6 +70,7 @@ import static android.os.Build.VERSION.SDK_INT;
import static android.support.v4.app.NotificationCompat.CATEGORY_MESSAGE;
import static android.support.v4.app.NotificationCompat.CATEGORY_SOCIAL;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID;
import static org.briarproject.briar.android.contact.ConversationActivity.CONTACT_ID;
import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.INTENT_BLOGS;
@@ -84,13 +85,6 @@ import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_
class AndroidNotificationManagerImpl implements AndroidNotificationManager,
Service, EventListener {
// Notification IDs
private static final int PRIVATE_MESSAGE_NOTIFICATION_ID = 3;
private static final int GROUP_MESSAGE_NOTIFICATION_ID = 4;
private static final int FORUM_POST_NOTIFICATION_ID = 5;
private static final int BLOG_POST_NOTIFICATION_ID = 6;
private static final int INTRODUCTION_SUCCESS_NOTIFICATION_ID = 7;
private static final long SOUND_DELAY = TimeUnit.SECONDS.toMillis(2);
private static final Logger LOG =
@@ -265,8 +259,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
try {
settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}

View File

@@ -20,6 +20,7 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory;
import org.briarproject.bramble.api.reporting.DevConfig;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.Scheduler;
import org.briarproject.bramble.plugin.bluetooth.AndroidBluetoothPluginFactory;
@@ -97,14 +98,15 @@ public class AppModule {
@Scheduler ScheduledExecutorService scheduler,
AndroidExecutor androidExecutor, SecureRandom random,
SocketFactory torSocketFactory, BackoffFactory backoffFactory,
Application app, LocationUtils locationUtils, EventBus eventBus) {
Application app, LocationUtils locationUtils, EventBus eventBus,
Clock clock) {
Context appContext = app.getApplicationContext();
DuplexPluginFactory bluetooth =
new AndroidBluetoothPluginFactory(ioExecutor, androidExecutor,
appContext, random, eventBus, backoffFactory);
DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, scheduler,
appContext, locationUtils, eventBus,
torSocketFactory, backoffFactory);
appContext, locationUtils, eventBus, torSocketFactory,
backoffFactory, clock);
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
scheduler, backoffFactory, appContext);
Collection<DuplexPluginFactory> duplex = asList(bluetooth, tor, lan);

View File

@@ -0,0 +1,83 @@
package org.briarproject.briar.android;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.briar.R;
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
import javax.inject.Inject;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.content.Context.NOTIFICATION_SERVICE;
import static android.content.Intent.ACTION_BOOT_COMPLETED;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.os.Build.VERSION.SDK_INT;
import static android.support.v4.app.NotificationCompat.PRIORITY_LOW;
import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_SIGN_IN_REMINDER;
import static org.briarproject.briar.api.android.AndroidNotificationManager.REMINDER_CHANNEL_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.REMINDER_NOTIFICATION_ID;
public class BootReceiver extends BroadcastReceiver {
@Inject
DatabaseConfig databaseConfig;
@Override
public void onReceive(Context ctx, Intent intent) {
if (!FEATURE_FLAG_SIGN_IN_REMINDER) return;
AndroidComponent applicationComponent =
((BriarApplication) ctx.getApplicationContext())
.getApplicationComponent();
applicationComponent.inject(this);
String action = intent.getAction();
if (action != null && action.equals(ACTION_BOOT_COMPLETED)) {
if (databaseConfig.databaseExists()) {
showSignInNotification(ctx);
}
}
}
private void showSignInNotification(Context ctx) {
NotificationManager nm = (NotificationManager)
ctx.getSystemService(NOTIFICATION_SERVICE);
if (nm == null) return;
if (SDK_INT >= 26) {
NotificationChannel channel =
new NotificationChannel(REMINDER_CHANNEL_ID, ctx.getString(
R.string.reminder_notification_channel_title),
IMPORTANCE_LOW);
channel.setLockscreenVisibility(VISIBILITY_SECRET);
nm.createNotificationChannel(channel);
}
NotificationCompat.Builder b =
new NotificationCompat.Builder(ctx, REMINDER_CHANNEL_ID);
b.setSmallIcon(R.drawable.notification_reminder);
b.setColor(ContextCompat.getColor(ctx, R.color.briar_primary));
b.setContentTitle(ctx.getText(R.string.reminder_notification_title));
b.setContentText(ctx.getText(R.string.reminder_notification_text));
b.setAutoCancel(true);
b.setWhen(0); // Don't show the time
b.setPriority(PRIORITY_LOW);
Intent i = new Intent(ctx, NavDrawerActivity.class);
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
b.setContentIntent(PendingIntent.getActivity(ctx, 0, i, 0));
nm.notify(REMINDER_NOTIFICATION_ID, b.build());
}
}

View File

@@ -2,9 +2,12 @@ package org.briarproject.briar.android;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.StrictMode;
import android.os.StrictMode.ThreadPolicy;
import android.os.StrictMode.VmPolicy;
import android.preference.PreferenceManager;
import org.acra.ACRA;
import org.acra.ReportingInteractionMode;
@@ -16,12 +19,14 @@ import org.briarproject.briar.android.logging.CachingLogHandler;
import org.briarproject.briar.android.reporting.BriarReportPrimer;
import org.briarproject.briar.android.reporting.BriarReportSenderFactory;
import org.briarproject.briar.android.reporting.DevReportActivity;
import org.briarproject.briar.android.util.UiUtils;
import java.util.Collection;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
import static org.acra.ReportField.ANDROID_VERSION;
import static org.acra.ReportField.APP_VERSION_CODE;
@@ -75,7 +80,13 @@ public class BriarApplicationImpl extends Application
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(base);
// Loading the language needs to be done here.
Localizer.initialize(prefs);
super.attachBaseContext(
Localizer.getInstance().setLocale(base));
setTheme(base, prefs);
ACRA.init(this);
}
@@ -93,7 +104,7 @@ public class BriarApplicationImpl extends Application
}
}
rootLogger.addHandler(logHandler);
rootLogger.setLevel(INFO);
rootLogger.setLevel(IS_DEBUG_BUILD || IS_BETA_BUILD ? FINE : INFO);
LOG.info("Created");
@@ -108,6 +119,23 @@ public class BriarApplicationImpl extends Application
AndroidEagerSingletons.initEagerSingletons(applicationComponent);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Localizer.getInstance().setLocale(this);
}
private void setTheme(Context ctx, SharedPreferences prefs) {
String theme = prefs.getString("pref_key_theme", null);
if (theme == null) {
// set default value
theme = getString(R.string.pref_theme_light_value);
prefs.edit().putString("pref_key_theme", theme).apply();
}
// set theme
UiUtils.setTheme(ctx, theme);
}
private void enableStrictMode() {
ThreadPolicy.Builder threadPolicy = new ThreadPolicy.Builder();
threadPolicy.detectAll();

View File

@@ -1,5 +1,7 @@
package org.briarproject.briar.android;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -30,6 +32,7 @@ import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.inject.Inject;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
@@ -47,6 +50,11 @@ import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.ALREADY_RUNNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS;
import static org.briarproject.briar.api.android.AndroidNotificationManager.FAILURE_CHANNEL_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.FAILURE_NOTIFICATION_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.ONGOING_CHANNEL_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.ONGOING_NOTIFICATION_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.REMINDER_NOTIFICATION_ID;
public class BriarService extends Service {
@@ -57,14 +65,6 @@ public class BriarService extends Service {
public static String EXTRA_STARTUP_FAILED =
"org.briarproject.briar.STARTUP_FAILED";
private static final int ONGOING_NOTIFICATION_ID = 1;
private static final int FAILURE_NOTIFICATION_ID = 2;
// Channels are sorted by channel ID in the Settings app, so use IDs
// that will sort below the main channels such as contacts
private static final String ONGOING_CHANNEL_ID = "zForegroundService";
private static final String FAILURE_CHANNEL_ID = "zStartupFailure";
private static final Logger LOG =
Logger.getLogger(BriarService.class.getName());
@@ -103,9 +103,9 @@ public class BriarService extends Service {
}
// Create notification channels
NotificationManager nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
if (SDK_INT >= 26) {
NotificationManager nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
NotificationChannel ongoingChannel = new NotificationChannel(
ONGOING_CHANNEL_ID,
getString(R.string.ongoing_notification_title),
@@ -137,6 +137,8 @@ public class BriarService extends Service {
}
b.setPriority(PRIORITY_MIN);
startForeground(ONGOING_NOTIFICATION_ID, b.build());
// Remove sign-in reminder notification
nm.cancel(REMINDER_NOTIFICATION_ID);
// Start the services in a background thread
new Thread(() -> {
String nickname = databaseConfig.getLocalAuthorName();
@@ -168,6 +170,11 @@ public class BriarService extends Service {
registerReceiver(receiver, filter);
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(Localizer.getInstance().setLocale(base));
}
private void showStartupFailureNotification(StartResult result) {
androidExecutor.runOnUiThread(() -> {
NotificationCompat.Builder b = new NotificationCompat.Builder(
@@ -243,8 +250,10 @@ public class BriarService extends Service {
LOG.info("Trim memory: running low");
} else if (level == TRIM_MEMORY_RUNNING_CRITICAL) {
LOG.info("Trim memory: running critically low");
// Clear the UI to save some memory
hideUi();
// If we're not in the foreground, clear the UI to save memory
RunningAppProcessInfo info = new RunningAppProcessInfo();
ActivityManager.getMyMemoryState(info);
if (info.importance != IMPORTANCE_FOREGROUND) hideUi();
} else if (LOG.isLoggable(INFO)) {
LOG.info("Trim memory: unknown level " + level);
}

View File

@@ -0,0 +1,92 @@
package org.briarproject.briar.android;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.Locale;
import javax.annotation.Nullable;
import static android.os.Build.VERSION.SDK_INT;
import static org.briarproject.briar.android.settings.SettingsFragment.LANGUAGE;
@NotNullByDefault
public class Localizer {
// Locking: class
@Nullable
private static Localizer INSTANCE;
private final Locale systemLocale;
private final Locale locale;
private Localizer(SharedPreferences sharedPreferences) {
this(Locale.getDefault(), getLocaleFromTag(
sharedPreferences.getString(LANGUAGE, "default")));
}
private Localizer(Locale systemLocale, @Nullable Locale userLocale) {
this.systemLocale = systemLocale;
if (userLocale == null) locale = systemLocale;
else locale = userLocale;
}
// Instantiate the Localizer.
public static synchronized void initialize(SharedPreferences prefs) {
if (INSTANCE == null)
INSTANCE = new Localizer(prefs);
}
// Reinstantiate the Localizer with the system locale
public static synchronized void reinitialize() {
if (INSTANCE != null)
INSTANCE = new Localizer(INSTANCE.systemLocale, null);
}
// Get the current instance.
public static synchronized Localizer getInstance() {
if (INSTANCE == null)
throw new IllegalStateException("Localizer not initialized");
return INSTANCE;
}
// Get Locale from BCP-47 tag
@Nullable
public static Locale getLocaleFromTag(String tag) {
if (tag.equals("default"))
return null;
if (SDK_INT >= 21) {
return Locale.forLanguageTag(tag);
}
if (tag.contains("-")) {
String[] langArray = tag.split("-");
return new Locale(langArray[0], langArray[1]);
} else
return new Locale(tag);
}
// Returns the localized version of context
public Context setLocale(Context context) {
Resources res = context.getResources();
Configuration conf = res.getConfiguration();
Locale currentLocale;
if (SDK_INT >= 24) {
currentLocale = conf.getLocales().get(0);
} else
currentLocale = conf.locale;
if (locale.equals(currentLocale))
return context;
Locale.setDefault(locale);
if (SDK_INT >= 17) {
conf.setLocale(locale);
context.createConfigurationContext(conf);
} else
conf.locale = locale;
//noinspection deprecation
res.updateConfiguration(conf, res.getDisplayMetrics());
return context;
}
}

View File

@@ -4,11 +4,11 @@ import android.net.TrafficStats;
import android.os.Process;
import org.briarproject.bramble.api.lifecycle.Service;
import org.briarproject.bramble.api.lifecycle.ServiceException;
import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
import static org.briarproject.bramble.util.LogUtils.now;
class NetworkUsageLogger implements Service {
@@ -18,17 +18,17 @@ class NetworkUsageLogger implements Service {
private volatile long startTime, rxBytes, txBytes;
@Override
public void startService() throws ServiceException {
startTime = System.currentTimeMillis();
public void startService() {
startTime = now();
int uid = Process.myUid();
rxBytes = TrafficStats.getUidRxBytes(uid);
txBytes = TrafficStats.getUidTxBytes(uid);
}
@Override
public void stopService() throws ServiceException {
public void stopService() {
if (LOG.isLoggable(INFO)) {
long sessionDuration = System.currentTimeMillis() - startTime;
long sessionDuration = now() - startTime;
int uid = Process.myUid();
long rx = TrafficStats.getUidRxBytes(uid) - rxBytes;
long tx = TrafficStats.getUidTxBytes(uid) - txBytes;

View File

@@ -48,6 +48,7 @@ import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.GET_SIGNATURES;
import static android.os.Build.VERSION.SDK_INT;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
class ScreenFilterMonitorImpl implements ScreenFilterMonitor, Service {
@@ -189,7 +190,7 @@ class ScreenFilterMonitorImpl implements ScreenFilterMonitor, Service {
String publicKey = StringUtils.toHexString(publicKeyBytes);
return PLAY_SERVICES_PUBLIC_KEY.equals(publicKey);
} catch (NameNotFoundException | CertificateException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return false;
}
}

View File

@@ -30,4 +30,14 @@ public interface TestingConstants {
long EXPIRY_DATE = IS_DEBUG_BUILD || IS_BETA_BUILD ?
BuildConfig.BuildTimestamp + 90 * 24 * 60 * 60 * 1000L :
Long.MAX_VALUE;
/**
* Feature flag for enabling the dark UI theme in release builds.
*/
boolean FEATURE_FLAG_DARK_THEME = false;
/**
* Feature flag for enabling the sign-in reminder in release builds.
*/
boolean FEATURE_FLAG_SIGN_IN_REMINDER = IS_DEBUG_BUILD;
}

View File

@@ -26,9 +26,10 @@ import org.briarproject.briar.android.fragment.ScreenFilterDialogFragment;
import org.briarproject.briar.android.introduction.ContactChooserFragment;
import org.briarproject.briar.android.introduction.IntroductionActivity;
import org.briarproject.briar.android.introduction.IntroductionMessageFragment;
import org.briarproject.briar.android.keyagreement.ContactExchangeActivity;
import org.briarproject.briar.android.keyagreement.IntroFragment;
import org.briarproject.briar.android.keyagreement.KeyAgreementActivity;
import org.briarproject.briar.android.keyagreement.ShowQrCodeFragment;
import org.briarproject.briar.android.keyagreement.KeyAgreementFragment;
import org.briarproject.briar.android.login.AuthorNameFragment;
import org.briarproject.briar.android.login.ChangePasswordActivity;
import org.briarproject.briar.android.login.DozeFragment;
@@ -100,6 +101,8 @@ public interface ActivityComponent {
void inject(PanicPreferencesActivity activity);
void inject(ContactExchangeActivity activity);
void inject(KeyAgreementActivity activity);
void inject(ConversationActivity activity);
@@ -185,7 +188,7 @@ public interface ActivityComponent {
void inject(IntroFragment fragment);
void inject(ShowQrCodeFragment fragment);
void inject(KeyAgreementFragment fragment);
void inject(ContactChooserFragment fragment);

View File

@@ -1,5 +1,6 @@
package org.briarproject.briar.android.activity;
import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.LayoutRes;
@@ -18,6 +19,7 @@ import org.briarproject.briar.R;
import org.briarproject.briar.android.AndroidComponent;
import org.briarproject.briar.android.BriarApplication;
import org.briarproject.briar.android.DestroyableContext;
import org.briarproject.briar.android.Localizer;
import org.briarproject.briar.android.controller.ActivityLifecycleController;
import org.briarproject.briar.android.forum.ForumModule;
import org.briarproject.briar.android.fragment.BaseFragment;
@@ -84,6 +86,12 @@ public abstract class BaseActivity extends AppCompatActivity
}
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(
Localizer.getInstance().setLocale(base));
}
public ActivityComponent getActivityComponent() {
return activityComponent;
}

View File

@@ -92,7 +92,6 @@ public abstract class BriarActivity extends BaseActivity {
window.setEnterTransition(slide);
window.setTransitionBackgroundFadeDuration(getResources()
.getInteger(android.R.integer.config_longAnimTime));
window.setBackgroundDrawableResource(android.R.color.transparent);
}
/**

View File

@@ -32,8 +32,10 @@ import java.util.logging.Logger;
import javax.annotation.Nullable;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.util.HtmlUtils.ARTICLE;
@MethodsNotNullByDefault
@@ -101,30 +103,25 @@ abstract class BaseControllerImpl extends DbControllerImpl
Collection<BlogPostItem> items = loadItems(groupId);
handler.onResult(items);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
}
Collection<BlogPostItem> loadItems(GroupId groupId) throws DbException {
long now = System.currentTimeMillis();
long start = now();
Collection<BlogPostHeader> headers =
blogManager.getPostHeaders(groupId);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading headers took " + duration + " ms");
logDuration(LOG, "Loading headers", start);
Collection<BlogPostItem> items = new ArrayList<>(headers.size());
now = System.currentTimeMillis();
start = now();
for (BlogPostHeader h : headers) {
headerCache.put(h.getId(), h);
BlogPostItem item = getItem(h);
items.add(item);
}
duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading bodies took " + duration + " ms");
logDuration(LOG, "Loading bodies", start);
return items;
}
@@ -140,15 +137,12 @@ abstract class BaseControllerImpl extends DbControllerImpl
}
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
BlogPostItem item = getItem(header);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading body took " + duration + " ms");
logDuration(LOG, "Loading body", start);
handler.onResult(item);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -166,16 +160,13 @@ abstract class BaseControllerImpl extends DbControllerImpl
}
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
BlogPostHeader header1 = getPostHeader(g, m);
BlogPostItem item = getItem(header1);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading post took " + duration + " ms");
logDuration(LOG, "Loading post", start);
handler.onResult(item);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -191,8 +182,7 @@ abstract class BaseControllerImpl extends DbControllerImpl
BlogPostHeader h = item.getHeader();
blogManager.addLocalComment(a, b.getId(), comment, h);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});

View File

@@ -35,8 +35,10 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@@ -154,19 +156,16 @@ class BlogControllerImpl extends BaseControllerImpl
if (groupId == null) throw new IllegalStateException();
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
LocalAuthor a = identityManager.getLocalAuthor();
Blog b = blogManager.getBlog(groupId);
boolean ours = a.getId().equals(b.getAuthor().getId());
boolean removable = blogManager.canBeRemoved(b);
BlogItem blog = new BlogItem(b, ours, removable);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading blog took " + duration + " ms");
logDuration(LOG, "Loading blog", start);
handler.onResult(blog);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -177,16 +176,13 @@ class BlogControllerImpl extends BaseControllerImpl
if (groupId == null) throw new IllegalStateException();
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
Blog b = blogManager.getBlog(groupId);
blogManager.removeBlog(b);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Removing blog took " + duration + " ms");
logDuration(LOG, "Removing blog", start);
handler.onResult(null);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -205,8 +201,7 @@ class BlogControllerImpl extends BaseControllerImpl
for (Contact c : contacts) contactIds.add(c.getId());
handler.onResult(contactIds);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});

View File

@@ -11,7 +11,7 @@ import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ImageButton;
import android.widget.TextView;
import org.briarproject.bramble.api.identity.Author;
@@ -40,7 +40,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
private final ViewGroup layout;
private final AuthorView reblogger;
private final AuthorView author;
private final ImageView reblogButton;
private final ImageButton reblogButton;
private final TextView body;
private final ViewGroup commentContainer;
private final boolean fullText;

View File

@@ -26,8 +26,10 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.api.blog.BlogManager.CLIENT_ID;
@MethodsNotNullByDefault
@@ -99,22 +101,19 @@ class FeedControllerImpl extends BaseControllerImpl
ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
Collection<BlogPostItem> posts = new ArrayList<>();
for (Blog b : blogManager.getBlogs()) {
try {
posts.addAll(loadItems(b.getId()));
} catch (NoSuchGroupException | NoSuchMessageException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading all posts took " + duration + " ms");
logDuration(LOG, "Loading all posts", start);
handler.onResult(posts);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -125,15 +124,13 @@ class FeedControllerImpl extends BaseControllerImpl
ResultExceptionHandler<Blog, DbException> handler) {
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
Author a = identityManager.getLocalAuthor();
Blog b = blogManager.getPersonalBlog(a);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading blog took " + duration + " ms");
logDuration(LOG, "Loading personal blog", start);
handler.onResult(b);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});

View File

@@ -30,6 +30,7 @@ import javax.inject.Inject;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
public class RssFeedImportActivity extends BriarActivity {
@@ -124,7 +125,7 @@ public class RssFeedImportActivity extends BriarActivity {
feedManager.addFeed(url);
feedImported();
} catch (DbException | IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
importFailed();
}
});

View File

@@ -27,6 +27,7 @@ import javax.inject.Inject;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.support.design.widget.Snackbar.LENGTH_LONG;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
public class RssFeedManageActivity extends BriarActivity
implements RssFeedListener {
@@ -123,7 +124,7 @@ public class RssFeedManageActivity extends BriarActivity
try {
displayFeeds(revision, feedManager.getFeeds());
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
onLoadError();
}
});
@@ -148,7 +149,7 @@ public class RssFeedManageActivity extends BriarActivity
feedManager.removeFeed(feed);
onFeedDeleted(feed);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
onDeleteError();
}
});

View File

@@ -34,6 +34,7 @@ import javax.inject.Inject;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.api.blog.BlogConstants.MAX_BLOG_POST_BODY_LENGTH;
public class WriteBlogPostActivity extends BriarActivity
@@ -142,16 +143,16 @@ public class WriteBlogPostActivity extends BriarActivity
private void storePost(String body) {
runOnDbThread(() -> {
long now = System.currentTimeMillis();
long timestamp = System.currentTimeMillis();
try {
LocalAuthor author = identityManager.getLocalAuthor();
BlogPost p = blogPostFactory
.createBlogPost(groupId, now, null, author, body);
.createBlogPost(groupId, timestamp, null, author, body);
blogManager.addLocalPost(p);
postPublished();
} catch (DbException | GeneralSecurityException
| FormatException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
postFailedToPublish();
}
});

View File

@@ -33,7 +33,7 @@ import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.contact.BaseContactListAdapter.OnContactClickListener;
import org.briarproject.briar.android.fragment.BaseFragment;
import org.briarproject.briar.android.keyagreement.KeyAgreementActivity;
import org.briarproject.briar.android.keyagreement.ContactExchangeActivity;
import org.briarproject.briar.android.view.BriarRecyclerView;
import org.briarproject.briar.api.android.AndroidNotificationManager;
import org.briarproject.briar.api.client.BaseMessageHeader;
@@ -59,8 +59,10 @@ import javax.inject.Inject;
import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAnimation;
import static android.support.v4.view.ViewCompat.getTransitionName;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.android.contact.ConversationActivity.CONTACT_ID;
@MethodsNotNullByDefault
@@ -163,7 +165,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
switch (item.getItemId()) {
case R.id.action_add_contact:
Intent intent =
new Intent(getContext(), KeyAgreementActivity.class);
new Intent(getContext(), ContactExchangeActivity.class);
startActivity(intent);
return true;
default:
@@ -194,7 +196,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
int revision = adapter.getRevision();
listener.runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
List<ContactListItem> contacts = new ArrayList<>();
for (Contact c : contactManager.getActiveContacts()) {
try {
@@ -208,12 +210,10 @@ public class ContactListFragment extends BaseFragment implements EventListener {
// Continue
}
}
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Full load took " + duration + " ms");
logDuration(LOG, "Full load", start);
displayContacts(revision, contacts);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}

View File

@@ -106,6 +106,9 @@ import static android.support.v7.util.SortedList.INVALID_POSITION;
import static android.widget.Toast.LENGTH_SHORT;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_INTRODUCTION;
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
import static org.briarproject.briar.android.util.UiUtils.getAvatarTransitionName;
@@ -290,21 +293,19 @@ public class ConversationActivity extends BriarActivity
private void loadContactDetailsAndMessages() {
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
if (contactName == null || contactAuthorId == null) {
Contact contact = contactManager.getContact(contactId);
contactName = contact.getAuthor().getName();
contactAuthorId = contact.getAuthor().getId();
}
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading contact took " + duration + " ms");
logDuration(LOG, "Loading contact", start);
loadMessages();
displayContactDetails();
} catch (NoSuchContactException e) {
finishOnUiThread();
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -340,7 +341,7 @@ public class ConversationActivity extends BriarActivity
int revision = adapter.getRevision();
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
Collection<PrivateMessageHeader> headers =
messagingManager.getMessageHeaders(contactId);
Collection<IntroductionMessage> introductions =
@@ -357,14 +358,12 @@ public class ConversationActivity extends BriarActivity
invitations.addAll(forumInvitations);
invitations.addAll(blogInvitations);
invitations.addAll(groupInvitations);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading messages took " + duration + " ms");
logDuration(LOG, "Loading messages", start);
displayMessages(revision, headers, introductions, invitations);
} catch (NoSuchContactException e) {
finishOnUiThread();
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -438,14 +437,12 @@ public class ConversationActivity extends BriarActivity
private void loadMessageBody(MessageId m) {
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
String body = messagingManager.getMessageBody(m);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading body took " + duration + " ms");
logDuration(LOG, "Loading body", start);
displayMessageBody(m, body);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -669,7 +666,7 @@ public class ConversationActivity extends BriarActivity
messagingManager.getConversationId(contactId);
createMessage(body, timestamp);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
@@ -689,11 +686,9 @@ public class ConversationActivity extends BriarActivity
private void storeMessage(PrivateMessage m, String body) {
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
messagingManager.addLocalMessage(m);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Storing message took " + duration + " ms");
logDuration(LOG, "Storing message", start);
Message message = m.getMessage();
PrivateMessageHeader h = new PrivateMessageHeader(
message.getId(), message.getGroupId(),
@@ -703,7 +698,7 @@ public class ConversationActivity extends BriarActivity
bodyCache.put(message.getId(), body);
addConversationItem(item);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -726,7 +721,7 @@ public class ConversationActivity extends BriarActivity
try {
contactManager.removeContact(contactId);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
} finally {
finishAfterContactRemoved();
}
@@ -755,7 +750,7 @@ public class ConversationActivity extends BriarActivity
}
}
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -803,7 +798,7 @@ public class ConversationActivity extends BriarActivity
settings.putBoolean(SHOW_ONBOARDING_INTRODUCTION, false);
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -816,13 +811,11 @@ public class ConversationActivity extends BriarActivity
private void markMessageRead(GroupId g, MessageId m) {
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
messagingManager.setReadFlag(g, m, true);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Marking read took " + duration + " ms");
logDuration(LOG, "Marking read", start);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -860,10 +853,10 @@ public class ConversationActivity extends BriarActivity
loadMessages();
} catch (ProtocolStateException e) {
// Action is no longer valid - reloading should solve the issue
if (LOG.isLoggable(INFO)) LOG.log(INFO, e.toString(), e);
logException(LOG, INFO, e);
} catch (DbException e) {
// TODO show an error message
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}

View File

@@ -19,6 +19,7 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@Immutable
@NotNullByDefault
@@ -53,7 +54,7 @@ public abstract class ContactSelectorControllerImpl
}
handler.onResult(contacts);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});

View File

@@ -21,6 +21,7 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting;
@@ -101,8 +102,7 @@ public class BriarControllerImpl implements BriarController {
boolean ask = settings.getBoolean(DOZE_ASK_AGAIN, true);
handler.onResult(ask);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -115,8 +115,7 @@ public class BriarControllerImpl implements BriarController {
settings.putBoolean(DOZE_ASK_AGAIN, false);
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}

View File

@@ -20,6 +20,7 @@ import javax.annotation.Nullable;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
public class ConfigControllerImpl implements ConfigController {
@@ -89,7 +90,7 @@ public class ConfigControllerImpl implements ConfigController {
reader.close();
return key;
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return null;
}
}
@@ -137,7 +138,7 @@ public class ConfigControllerImpl implements ConfigController {
LOG.info("Stored second copy of database key in backup file");
return true;
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return false;
}
}

View File

@@ -28,8 +28,10 @@ import javax.inject.Inject;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static android.widget.Toast.LENGTH_LONG;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH;
@MethodsNotNullByDefault
@@ -122,14 +124,12 @@ public class CreateForumActivity extends BriarActivity {
private void storeForum(String name) {
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
Forum f = forumManager.addForum(name);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Storing forum took " + duration + " ms");
logDuration(LOG, "Storing forum", start);
displayForum(f);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
finishOnUiThread();
}
});

View File

@@ -39,6 +39,7 @@ import javax.inject.Inject;
import static java.lang.Math.max;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
class ForumControllerImpl extends
@@ -130,7 +131,7 @@ class ForumControllerImpl extends
for (Contact c : contacts) contactIds.add(c.getId());
handler.onResult(contactIds);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -150,7 +151,7 @@ class ForumControllerImpl extends
parentItem.getId() : null;
createMessage(body, timestamp, parentId, author, handler);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});

View File

@@ -2,7 +2,6 @@ package org.briarproject.briar.android.forum;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
@@ -55,12 +54,8 @@ class ForumListAdapter
ui.postCount.setText(ctx.getResources()
.getQuantityString(R.plurals.posts, postCount,
postCount));
ui.postCount.setTextColor(
ContextCompat.getColor(ctx, R.color.briar_text_secondary));
} else {
ui.postCount.setText(ctx.getString(R.string.no_posts));
ui.postCount.setTextColor(
ContextCompat.getColor(ctx, R.color.briar_text_tertiary));
}
// Date

View File

@@ -44,8 +44,10 @@ import javax.annotation.Nullable;
import javax.inject.Inject;
import static android.support.design.widget.Snackbar.LENGTH_INDEFINITE;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.api.forum.ForumManager.CLIENT_ID;
@MethodsNotNullByDefault
@@ -157,7 +159,7 @@ public class ForumListFragment extends BaseEventFragment implements
int revision = adapter.getRevision();
listener.runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
Collection<ForumListItem> forums = new ArrayList<>();
for (Forum f : forumManager.getForums()) {
try {
@@ -168,12 +170,10 @@ public class ForumListFragment extends BaseEventFragment implements
// Continue
}
}
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Full load took " + duration + " ms");
logDuration(LOG, "Full load", start);
displayForums(revision, forums);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -194,14 +194,12 @@ public class ForumListFragment extends BaseEventFragment implements
private void loadAvailableForums() {
listener.runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
int available = forumSharingManager.getInvitations().size();
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading available took " + duration + " ms");
logDuration(LOG, "Loading available", start);
displayAvailableForums(available);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}

View File

@@ -29,6 +29,7 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.contact.ConversationActivity.CONTACT_ID;
public class ContactChooserFragment extends BaseFragment {
@@ -129,7 +130,7 @@ public class ContactChooserFragment extends BaseFragment {
}
displayContacts(contacts);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}

View File

@@ -36,6 +36,7 @@ import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static android.widget.Toast.LENGTH_SHORT;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_REQUEST_MESSAGE_LENGTH;
public class IntroductionMessageFragment extends BaseFragment
@@ -129,7 +130,7 @@ public class IntroductionMessageFragment extends BaseFragment
boolean possible = introductionManager.canIntroduce(c1, c2);
setUpViews(c1, c2, possible);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -204,7 +205,7 @@ public class IntroductionMessageFragment extends BaseFragment
long timestamp = System.currentTimeMillis();
introductionManager.makeIntroduction(c1, c2, msg, timestamp);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
introductionError();
}
});

View File

@@ -9,10 +9,12 @@ import android.hardware.Camera.Size;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.util.AttributeSet;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
@@ -21,6 +23,7 @@ import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;
import static android.content.Context.WINDOW_SERVICE;
import static android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK;
import static android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT;
import static android.hardware.Camera.Parameters.FLASH_MODE_OFF;
@@ -35,6 +38,7 @@ import static android.hardware.Camera.Parameters.SCENE_MODE_BARCODE;
import static android.os.Build.VERSION.SDK_INT;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@SuppressWarnings("deprecation")
@MethodsNotNullByDefault
@@ -96,7 +100,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
}
@UiThread
public void start(int rotationDegrees) throws CameraException {
public void start() throws CameraException {
LOG.info("Opening camera");
try {
int cameras = Camera.getNumberOfCameras();
@@ -121,7 +125,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
} catch (RuntimeException e) {
throw new CameraException(e);
}
setDisplayOrientation(rotationDegrees);
setDisplayOrientation(getScreenRotationDegrees());
// Use barcode scene mode if it's available
Parameters params = camera.getParameters();
params = setSceneMode(camera, params);
@@ -156,6 +160,27 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
camera = null;
}
/**
* See {@link Camera#setDisplayOrientation(int)}.
*/
private int getScreenRotationDegrees() {
WindowManager wm =
(WindowManager) getContext().getSystemService(WINDOW_SERVICE);
Display d = wm.getDefaultDisplay();
switch (d.getRotation()) {
case Surface.ROTATION_0:
return 0;
case Surface.ROTATION_90:
return 90;
case Surface.ROTATION_180:
return 180;
case Surface.ROTATION_270:
return 270;
default:
throw new AssertionError();
}
}
@UiThread
private void startPreview(SurfaceHolder holder) throws CameraException {
LOG.info("Starting preview");
@@ -408,7 +433,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
try {
surfaceCreatedUi(holder);
} catch (CameraException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -430,7 +455,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
try {
surfaceChangedUi(holder, w, h);
} catch (CameraException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -488,7 +513,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
try {
startAutoFocus();
} catch (CameraException e) {
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
}

View File

@@ -0,0 +1,144 @@
package org.briarproject.briar.android.keyagreement;
import android.os.Bundle;
import android.support.annotation.UiThread;
import android.widget.Toast;
import org.briarproject.bramble.api.contact.ContactExchangeListener;
import org.briarproject.bramble.api.contact.ContactExchangeTask;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.keyagreement.KeyAgreementResult;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.R.string;
import org.briarproject.briar.android.activity.ActivityComponent;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.inject.Inject;
import static android.widget.Toast.LENGTH_LONG;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class ContactExchangeActivity extends KeyAgreementActivity implements
ContactExchangeListener {
private static final Logger LOG =
Logger.getLogger(ContactExchangeActivity.class.getName());
// Fields that are accessed from background threads must be volatile
@Inject
volatile ContactExchangeTask contactExchangeTask;
@Inject
volatile IdentityManager identityManager;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
}
@Override
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
getSupportActionBar().setTitle(string.add_contact_title);
}
private void startContactExchange(KeyAgreementResult result) {
runOnDbThread(() -> {
LocalAuthor localAuthor;
// Load the local pseudonym
try {
localAuthor = identityManager.getLocalAuthor();
} catch (DbException e) {
logException(LOG, WARNING, e);
contactExchangeFailed();
return;
}
// Exchange contact details
contactExchangeTask.startExchange(ContactExchangeActivity.this,
localAuthor, result.getMasterKey(),
result.getConnection(), result.getTransportId(),
result.wasAlice());
});
}
@Override
public void contactExchangeSucceeded(Author remoteAuthor) {
runOnUiThreadUnlessDestroyed(() -> {
String contactName = remoteAuthor.getName();
String format = getString(string.contact_added_toast);
String text = String.format(format, contactName);
Toast.makeText(ContactExchangeActivity.this, text, LENGTH_LONG)
.show();
supportFinishAfterTransition();
});
}
@Override
public void duplicateContact(Author remoteAuthor) {
runOnUiThreadUnlessDestroyed(() -> {
String contactName = remoteAuthor.getName();
String format = getString(string.contact_already_exists);
String text = String.format(format, contactName);
Toast.makeText(ContactExchangeActivity.this, text, LENGTH_LONG)
.show();
finish();
});
}
@Override
public void contactExchangeFailed() {
runOnUiThreadUnlessDestroyed(() -> {
Toast.makeText(ContactExchangeActivity.this,
string.contact_exchange_failed, LENGTH_LONG).show();
finish();
});
}
@UiThread
@Override
public void keyAgreementFailed() {
// TODO show failure somewhere persistent?
Toast.makeText(this, R.string.connection_failed,
LENGTH_LONG).show();
}
@UiThread
@Override
public String keyAgreementWaiting() {
return getString(R.string.waiting_for_contact_to_scan);
}
@UiThread
@Override
public String keyAgreementStarted() {
return getString(R.string.authenticating_with_device);
}
@UiThread
@Override
public String keyAgreementAborted(boolean remoteAborted) {
// TODO show abort somewhere persistent?
Toast.makeText(this,
remoteAborted ? R.string.connection_aborted_remote :
R.string.connection_aborted_local, LENGTH_LONG)
.show();
return null;
}
@UiThread
@Override
public String keyAgreementFinished(KeyAgreementResult result) {
startContactExchange(result);
return getString(string.exchanging_contact_details);
}
}

View File

@@ -16,17 +16,7 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.widget.Toast;
import org.briarproject.bramble.api.contact.ContactExchangeListener;
import org.briarproject.bramble.api.contact.ContactExchangeTask;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.keyagreement.KeyAgreementResult;
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementFinishedEvent;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent;
@@ -53,15 +43,14 @@ import static android.bluetooth.BluetoothAdapter.STATE_ON;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Build.VERSION.SDK_INT;
import static android.widget.Toast.LENGTH_LONG;
import static java.util.logging.Level.WARNING;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_ENABLE_BLUETOOTH;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class KeyAgreementActivity extends BriarActivity implements
BaseFragmentListener, IntroScreenSeenListener, EventListener,
ContactExchangeListener {
public abstract class KeyAgreementActivity extends BriarActivity implements
BaseFragmentListener, IntroScreenSeenListener,
KeyAgreementFragment.KeyAgreementEventListener {
private enum BluetoothState {
UNKNOWN, NO_ADAPTER, WAITING, REFUSED, ENABLED
@@ -73,12 +62,6 @@ public class KeyAgreementActivity extends BriarActivity implements
@Inject
EventBus eventBus;
// Fields that are accessed from background threads must be volatile
@Inject
volatile ContactExchangeTask contactExchangeTask;
@Inject
volatile IdentityManager identityManager;
private boolean isResumed = false, enableWasRequested = false;
private boolean continueClicked, gotCameraPermission;
private BluetoothState bluetoothState = BluetoothState.UNKNOWN;
@@ -94,13 +77,9 @@ public class KeyAgreementActivity extends BriarActivity implements
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
setContentView(R.layout.activity_fragment_container_toolbar);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(R.string.add_contact_title);
if (state == null) {
showInitialFragment(IntroFragment.newInstance());
}
@@ -115,18 +94,6 @@ public class KeyAgreementActivity extends BriarActivity implements
if (bluetoothReceiver != null) unregisterReceiver(bluetoothReceiver);
}
@Override
public void onStart() {
super.onStart();
eventBus.addListener(this);
}
@Override
protected void onStop() {
super.onStop();
eventBus.removeListener(this);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -147,7 +114,7 @@ public class KeyAgreementActivity extends BriarActivity implements
if (canShowQrCodeFragment()) showQrCodeFragment();
}
boolean canShowQrCodeFragment() {
private boolean canShowQrCodeFragment() {
return isResumed && continueClicked
&& (SDK_INT < 23 || gotCameraPermission)
&& bluetoothState != BluetoothState.UNKNOWN
@@ -206,10 +173,11 @@ public class KeyAgreementActivity extends BriarActivity implements
}
private void showQrCodeFragment() {
continueClicked = false;
// FIXME #824
FragmentManager fm = getSupportFragmentManager();
if (fm.findFragmentByTag(ShowQrCodeFragment.TAG) == null) {
BaseFragment f = ShowQrCodeFragment.newInstance();
if (fm.findFragmentByTag(KeyAgreementFragment.TAG) == null) {
BaseFragment f = KeyAgreementFragment.newInstance();
fm.beginTransaction()
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
.addToBackStack(f.getUniqueTag())
@@ -279,69 +247,6 @@ public class KeyAgreementActivity extends BriarActivity implements
}
}
@Override
public void eventOccurred(Event e) {
if (e instanceof KeyAgreementFinishedEvent) {
KeyAgreementFinishedEvent event = (KeyAgreementFinishedEvent) e;
keyAgreementFinished(event.getResult());
}
}
private void keyAgreementFinished(KeyAgreementResult result) {
runOnUiThreadUnlessDestroyed(() -> startContactExchange(result));
}
private void startContactExchange(KeyAgreementResult result) {
runOnDbThread(() -> {
LocalAuthor localAuthor;
// Load the local pseudonym
try {
localAuthor = identityManager.getLocalAuthor();
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
contactExchangeFailed();
return;
}
// Exchange contact details
contactExchangeTask.startExchange(KeyAgreementActivity.this,
localAuthor, result.getMasterKey(),
result.getConnection(), result.getTransportId(),
result.wasAlice());
});
}
@Override
public void contactExchangeSucceeded(Author remoteAuthor) {
runOnUiThreadUnlessDestroyed(() -> {
String contactName = remoteAuthor.getName();
String format = getString(string.contact_added_toast);
String text = String.format(format, contactName);
Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG).show();
supportFinishAfterTransition();
});
}
@Override
public void duplicateContact(Author remoteAuthor) {
runOnUiThreadUnlessDestroyed(() -> {
String contactName = remoteAuthor.getName();
String format = getString(string.contact_already_exists);
String text = String.format(format, contactName);
Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG).show();
finish();
});
}
@Override
public void contactExchangeFailed() {
runOnUiThreadUnlessDestroyed(() -> {
Toast.makeText(KeyAgreementActivity.this,
string.contact_exchange_failed, LENGTH_LONG).show();
finish();
});
}
private class BluetoothStateReceiver extends BroadcastReceiver {
@Override

View File

@@ -2,18 +2,12 @@ package org.briarproject.briar.android.keyagreement;
import android.content.Context;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.UiThread;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
@@ -24,6 +18,7 @@ import com.google.zxing.Result;
import org.briarproject.bramble.api.UnsupportedVersionException;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.keyagreement.KeyAgreementResult;
import org.briarproject.bramble.api.keyagreement.KeyAgreementTask;
import org.briarproject.bramble.api.keyagreement.Payload;
import org.briarproject.bramble.api.keyagreement.PayloadEncoder;
@@ -36,11 +31,13 @@ import org.briarproject.bramble.api.keyagreement.event.KeyAgreementStartedEvent;
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementWaitingEvent;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.fragment.BaseEventFragment;
import org.briarproject.briar.android.fragment.ErrorFragment;
import org.briarproject.briar.android.view.QrCodeView;
import java.io.IOException;
import java.nio.charset.Charset;
@@ -59,13 +56,14 @@ import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.Toast.LENGTH_LONG;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class ShowQrCodeFragment extends BaseEventFragment
implements QrCodeDecoder.ResultCallback {
public class KeyAgreementFragment extends BaseEventFragment
implements QrCodeDecoder.ResultCallback, QrCodeView.FullscreenListener {
static final String TAG = ShowQrCodeFragment.class.getName();
static final String TAG = KeyAgreementFragment.class.getName();
private static final Logger LOG = Logger.getLogger(TAG);
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
@@ -83,26 +81,29 @@ public class ShowQrCodeFragment extends BaseEventFragment
EventBus eventBus;
private CameraView cameraView;
private LinearLayout cameraOverlay;
private View statusView;
private QrCodeView qrCodeView;
private TextView status;
private ImageView qrCode;
private TextView mainProgressTitle;
private ViewGroup mainProgressContainer;
private boolean fullscreen = false;
private boolean gotRemotePayload;
private volatile boolean gotLocalPayload;
private KeyAgreementTask task;
private KeyAgreementEventListener listener;
public static ShowQrCodeFragment newInstance() {
public static KeyAgreementFragment newInstance() {
Bundle args = new Bundle();
ShowQrCodeFragment fragment = new ShowQrCodeFragment();
KeyAgreementFragment fragment = new KeyAgreementFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
listener = (KeyAgreementEventListener) context;
}
@Override
public void injectFragment(ActivityComponent component) {
component.inject(this);
@@ -118,7 +119,6 @@ public class ShowQrCodeFragment extends BaseEventFragment
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_keyagreement_qr, container,
false);
}
@@ -126,47 +126,17 @@ public class ShowQrCodeFragment extends BaseEventFragment
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
cameraView = view.findViewById(R.id.camera_view);
cameraOverlay = view.findViewById(R.id.camera_overlay);
statusView = view.findViewById(R.id.status_container);
status = view.findViewById(R.id.connect_status);
qrCode = view.findViewById(R.id.qr_code);
mainProgressTitle = view.findViewById(R.id.title_progress_bar);
mainProgressContainer = view.findViewById(R.id.container_progress);
ImageView fullscreenButton = view.findViewById(R.id.fullscreen_button);
fullscreenButton.setOnClickListener(v -> {
View qrCodeContainer = view.findViewById(R.id.qr_code_container);
LinearLayout cameraOverlay = view.findViewById(R.id.camera_overlay);
LayoutParams statusParams, qrCodeParams;
if (fullscreen) {
// Shrink the QR code container to fill half its parent
if (cameraOverlay.getOrientation() == HORIZONTAL) {
statusParams = new LayoutParams(0, MATCH_PARENT, 1f);
qrCodeParams = new LayoutParams(0, MATCH_PARENT, 1f);
} else {
statusParams = new LayoutParams(MATCH_PARENT, 0, 1f);
qrCodeParams = new LayoutParams(MATCH_PARENT, 0, 1f);
}
fullscreenButton.setImageResource(
R.drawable.ic_fullscreen_black_48dp);
} else {
// Grow the QR code container to fill its parent
statusParams = new LayoutParams(0, 0, 0f);
qrCodeParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT, 1f);
fullscreenButton.setImageResource(
R.drawable.ic_fullscreen_exit_black_48dp);
}
statusView.setLayoutParams(statusParams);
qrCodeContainer.setLayoutParams(qrCodeParams);
cameraOverlay.invalidate();
fullscreen = !fullscreen;
});
qrCodeView = view.findViewById(R.id.qr_code_view);
qrCodeView.setFullscreenListener(this);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getActivity().setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR);
cameraView.setPreviewConsumer(new QrCodeDecoder(this));
}
@@ -175,30 +145,33 @@ public class ShowQrCodeFragment extends BaseEventFragment
public void onStart() {
super.onStart();
try {
cameraView.start(getScreenRotationDegrees());
cameraView.start();
} catch (CameraException e) {
logCameraExceptionAndFinish(e);
}
startListening();
}
/**
* See {@link Camera#setDisplayOrientation(int)}.
*/
private int getScreenRotationDegrees() {
Display d = getActivity().getWindowManager().getDefaultDisplay();
switch (d.getRotation()) {
case Surface.ROTATION_0:
return 0;
case Surface.ROTATION_90:
return 90;
case Surface.ROTATION_180:
return 180;
case Surface.ROTATION_270:
return 270;
default:
throw new AssertionError();
@Override
public void setFullscreen(boolean fullscreen) {
LinearLayout.LayoutParams statusParams, qrCodeParams;
if (fullscreen) {
// Grow the QR code view to fill its parent
statusParams = new LayoutParams(0, 0, 0f);
qrCodeParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT, 1f);
} else {
// Shrink the QR code view to fill half its parent
if (cameraOverlay.getOrientation() == HORIZONTAL) {
statusParams = new LayoutParams(0, MATCH_PARENT, 1f);
qrCodeParams = new LayoutParams(0, MATCH_PARENT, 1f);
} else {
statusParams = new LayoutParams(MATCH_PARENT, 0, 1f);
qrCodeParams = new LayoutParams(MATCH_PARENT, 0, 1f);
}
}
statusView.setLayoutParams(statusParams);
qrCodeView.setLayoutParams(qrCodeParams);
cameraOverlay.invalidate();
}
@Override
@@ -214,7 +187,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
@UiThread
private void logCameraExceptionAndFinish(CameraException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
Toast.makeText(getActivity(), R.string.camera_error,
LENGTH_LONG).show();
finish();
@@ -244,7 +217,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
// If we've stopped the camera view, restart it
if (gotRemotePayload) {
try {
cameraView.start(getScreenRotationDegrees());
cameraView.start();
} catch (CameraException e) {
logCameraExceptionAndFinish(e);
return;
@@ -278,7 +251,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
} catch (CameraException e) {
logCameraExceptionAndFinish(e);
} catch (IOException | IllegalArgumentException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, "QR Code Invalid", e);
LOG.log(WARNING, "QR Code Invalid", e);
reset();
Toast.makeText(getActivity(), R.string.qr_code_invalid,
LENGTH_LONG).show();
@@ -301,82 +274,60 @@ public class ShowQrCodeFragment extends BaseEventFragment
KeyAgreementAbortedEvent event = (KeyAgreementAbortedEvent) e;
keyAgreementAborted(event.didRemoteAbort());
} else if (e instanceof KeyAgreementFinishedEvent) {
runOnUiThreadUnlessDestroyed(() -> {
mainProgressContainer.setVisibility(VISIBLE);
mainProgressTitle.setText(R.string.exchanging_contact_details);
});
keyAgreementFinished(((KeyAgreementFinishedEvent) e).getResult());
}
}
@UiThread
private void generateBitmapQR(Payload payload) {
// Get narrowest screen dimension
Context context = getContext();
if (context == null) return;
DisplayMetrics dm = context.getResources().getDisplayMetrics();
new AsyncTask<Void, Void, Bitmap>() {
@Override
@Nullable
protected Bitmap doInBackground(Void... params) {
byte[] payloadBytes = payloadEncoder.encode(payload);
if (LOG.isLoggable(INFO)) {
LOG.info("Local payload is " + payloadBytes.length
+ " bytes");
}
// Use ISO 8859-1 to encode bytes directly as a string
String content = new String(payloadBytes, ISO_8859_1);
return QrCodeUtils.createQrCode(dm, content);
}
@Override
protected void onPostExecute(@Nullable Bitmap bitmap) {
if (bitmap != null && !isDetached()) {
qrCode.setImageBitmap(bitmap);
// Simple fade-in animation
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(200);
qrCode.startAnimation(anim);
}
}
}.execute();
}
private void setQrCode(Payload localPayload) {
runOnUiThreadUnlessDestroyed(() -> generateBitmapQR(localPayload));
}
private void keyAgreementFailed() {
runOnUiThreadUnlessDestroyed(() -> {
reset();
// TODO show failure somewhere persistent?
Toast.makeText(getActivity(), R.string.connection_failed,
LENGTH_LONG).show();
listener.keyAgreementFailed();
});
}
private void keyAgreementWaiting() {
runOnUiThreadUnlessDestroyed(
() -> status.setText(R.string.waiting_for_contact_to_scan));
() -> status.setText(listener.keyAgreementWaiting()));
}
private void keyAgreementStarted() {
runOnUiThreadUnlessDestroyed(() -> {
mainProgressContainer.setVisibility(VISIBLE);
mainProgressTitle.setText(R.string.authenticating_with_device);
qrCodeView.setVisibility(INVISIBLE);
statusView.setVisibility(VISIBLE);
status.setText(listener.keyAgreementStarted());
});
}
private void keyAgreementAborted(boolean remoteAborted) {
runOnUiThreadUnlessDestroyed(() -> {
reset();
mainProgressContainer.setVisibility(INVISIBLE);
mainProgressTitle.setText("");
// TODO show abort somewhere persistent?
Toast.makeText(getActivity(),
remoteAborted ? R.string.connection_aborted_remote :
R.string.connection_aborted_local, LENGTH_LONG)
.show();
qrCodeView.setVisibility(VISIBLE);
statusView.setVisibility(INVISIBLE);
status.setText(listener.keyAgreementAborted(remoteAborted));
});
}
private void keyAgreementFinished(KeyAgreementResult result) {
runOnUiThreadUnlessDestroyed(() -> {
statusView.setVisibility(VISIBLE);
status.setText(listener.keyAgreementFinished(result));
});
}
private void setQrCode(Payload localPayload) {
Context context = getContext();
if (context == null) return;
DisplayMetrics dm = context.getResources().getDisplayMetrics();
ioExecutor.execute(() -> {
byte[] payloadBytes = payloadEncoder.encode(localPayload);
if (LOG.isLoggable(INFO)) {
LOG.info("Local payload is " + payloadBytes.length
+ " bytes");
}
// Use ISO 8859-1 to encode bytes directly as a string
String content = new String(payloadBytes, ISO_8859_1);
Bitmap qrCode = QrCodeUtils.createQrCode(dm, content);
runOnUiThreadUnlessDestroyed(() -> qrCodeView.setQrCode(qrCode));
});
}
@@ -394,4 +345,31 @@ public class ShowQrCodeFragment extends BaseEventFragment
protected void finish() {
getActivity().getSupportFragmentManager().popBackStack();
}
@NotNullByDefault
interface KeyAgreementEventListener {
@UiThread
void keyAgreementFailed();
// Should return a string to be displayed as status.
@UiThread
@Nullable
String keyAgreementWaiting();
// Should return a string to be displayed as status.
@UiThread
@Nullable
String keyAgreementStarted();
// Should return a string to be displayed as status.
@UiThread
@Nullable
String keyAgreementAborted(boolean remoteAborted);
// Should return a string to be displayed as status.
@UiThread
@Nullable
String keyAgreementFinished(KeyAgreementResult result);
}
}

View File

@@ -18,6 +18,7 @@ import static android.graphics.Color.BLACK;
import static android.graphics.Color.WHITE;
import static com.google.zxing.BarcodeFormat.QR_CODE;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
class QrCodeUtils {
@@ -34,7 +35,7 @@ class QrCodeUtils {
smallestDimen, smallestDimen);
return renderQrCode(encoded);
} catch (WriterException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
return null;
}
}

View File

@@ -16,6 +16,8 @@ import java.util.List;
import javax.annotation.Nullable;
import static android.os.Build.VERSION.SDK_INT;
@UiThread
@NotNullByDefault
class HuaweiView extends PowerView {
@@ -45,6 +47,8 @@ class HuaweiView extends PowerView {
}
public static boolean needsToBeShown(Context context) {
// "Protected apps" no longer exists on Huawei EMUI 5.0 (Android 7.0)
if (SDK_INT >= 24) return false;
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(getIntent(),
PackageManager.MATCH_DEFAULT_ONLY);

View File

@@ -13,6 +13,7 @@ import android.widget.EditText;
import android.widget.ProgressBar;
import org.briarproject.briar.R;
import org.briarproject.briar.android.Localizer;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BaseActivity;
import org.briarproject.briar.android.controller.BriarController;
@@ -105,6 +106,8 @@ public class PasswordActivity extends BaseActivity {
private void deleteAccount() {
passwordController.deleteAccount(this);
Localizer.reinitialize();
UiUtils.setTheme(this, getString(R.string.pref_theme_light_value));
setResult(RESULT_CANCELED);
Intent i = new Intent(this, SetupActivity.class);
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);

View File

@@ -17,7 +17,8 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now;
@NotNullByDefault
public class PasswordControllerImpl extends ConfigControllerImpl
@@ -86,11 +87,9 @@ public class PasswordControllerImpl extends ConfigControllerImpl
@CryptoExecutor
String encryptDatabaseKey(SecretKey key, String password) {
long now = System.currentTimeMillis();
long start = now();
byte[] encrypted = crypto.encryptWithPassword(key.getBytes(), password);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Key derivation took " + duration + " ms");
logDuration(LOG, "Key derivation", start);
return StringUtils.toHexString(encrypted);
}
}

View File

@@ -15,6 +15,7 @@ import javax.annotation.Nullable;
import javax.inject.Inject;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@@ -94,7 +95,7 @@ public class SetupActivity extends BaseActivity
void showApp() {
Intent i = new Intent(this, OpenDatabaseActivity.class);
i.setFlags(FLAG_ACTIVITY_NEW_TASK);
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME);
startActivity(i);
supportFinishAfterTransition();
overridePendingTransition(R.anim.screen_new_in, R.anim.screen_old_out);

View File

@@ -68,6 +68,7 @@ public class NavDrawerActivity extends BriarActivity implements
public static final String INTENT_GROUPS = "intent_groups";
public static final String INTENT_FORUMS = "intent_forums";
public static final String INTENT_BLOGS = "intent_blogs";
public static final String INTENT_SIGN_OUT = "intent_sign_out";
private static final Logger LOG =
Logger.getLogger(NavDrawerActivity.class.getName());
@@ -99,6 +100,8 @@ public class NavDrawerActivity extends BriarActivity implements
R.id.nav_btn_contacts);
} else if (intent.getBooleanExtra(INTENT_BLOGS, false)) {
startFragment(FeedFragment.newInstance(), R.id.nav_btn_blogs);
} else if (intent.getBooleanExtra(INTENT_SIGN_OUT, false)) {
signOut(false);
}
setIntent(null);
}
@@ -225,12 +228,12 @@ public class NavDrawerActivity extends BriarActivity implements
finish();
} else if (fm.getBackStackEntryCount() == 0
&& fm.findFragmentByTag(ContactListFragment.TAG) == null) {
/*
* This makes sure that the first fragment (ContactListFragment) the
* user sees is the same as the last fragment the user sees before
* exiting. This models the typical Google navigation behaviour such
* as in Gmail/Inbox.
*/
/*
* This makes sure that the first fragment (ContactListFragment) the
* user sees is the same as the last fragment the user sees before
* exiting. This models the typical Google navigation behaviour such
* as in Gmail/Inbox.
*/
startFragment(ContactListFragment.newInstance(),
R.id.nav_btn_contacts);
} else {

View File

@@ -28,6 +28,7 @@ import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE;
import static org.briarproject.briar.android.TestingConstants.IS_BETA_BUILD;
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
@@ -143,7 +144,7 @@ public class NavDrawerControllerImpl extends DbControllerImpl
}
}
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -158,7 +159,7 @@ public class NavDrawerControllerImpl extends DbControllerImpl
settings.putBoolean(EXPIRY_SHOW_UPDATE, false);
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -178,8 +179,7 @@ public class NavDrawerControllerImpl extends DbControllerImpl
boolean ask = settings.getBoolean(DOZE_ASK_AGAIN, true);
handler.onResult(ask);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onResult(true);
}
});

View File

@@ -42,6 +42,7 @@ import javax.inject.Inject;
import static java.lang.Math.max;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@@ -152,7 +153,7 @@ class GroupControllerImpl extends
}
handler.onResult(contactIds);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -176,7 +177,7 @@ class GroupControllerImpl extends
createMessage(body, timestamp, parentId, author, previousMsgId,
handler);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -223,7 +224,7 @@ class GroupControllerImpl extends
LocalAuthor author = identityManager.getLocalAuthor();
handler.onResult(author);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -238,7 +239,7 @@ class GroupControllerImpl extends
privateGroupManager.isDissolved(getGroupId());
handler.onResult(isDissolved);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});

View File

@@ -33,6 +33,7 @@ import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@Immutable
@NotNullByDefault
@@ -81,7 +82,7 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
LocalAuthor author = identityManager.getLocalAuthor();
createGroupAndMessages(author, name, handler);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -109,7 +110,7 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
groupManager.addPrivateGroup(group, joinMsg, true);
handler.onResult(group.getId());
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -136,7 +137,7 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
}
signInvitations(g, localAuthor, contacts, message, handler);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -176,7 +177,7 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
//noinspection ConstantConditions
handler.onResult(null);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});

View File

@@ -22,6 +22,7 @@ import java.util.concurrent.Executor;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.api.privategroup.PrivateGroupManager.CLIENT_ID;
@NotNullByDefault
@@ -72,7 +73,7 @@ class GroupInvitationControllerImpl
ContactId c = item.getCreator().getId();
groupInvitationManager.respondToInvitation(c, g, accept);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});

View File

@@ -36,8 +36,10 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.api.privategroup.PrivateGroupManager.CLIENT_ID;
@MethodsNotNullByDefault
@@ -147,7 +149,7 @@ class GroupListControllerImpl extends DbControllerImpl
ResultExceptionHandler<Collection<GroupItem>, DbException> handler) {
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
Collection<PrivateGroup> groups =
groupManager.getPrivateGroups();
List<GroupItem> items = new ArrayList<>(groups.size());
@@ -161,12 +163,10 @@ class GroupListControllerImpl extends DbControllerImpl
// Continue
}
}
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading groups took " + duration + " ms");
logDuration(LOG, "Loading groups", start);
handler.onResult(items);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -176,13 +176,11 @@ class GroupListControllerImpl extends DbControllerImpl
public void removeGroup(GroupId g, ExceptionHandler<DbException> handler) {
runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
groupManager.removePrivateGroup(g);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Removing group took " + duration + " ms");
logDuration(LOG, "Removing group", start);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -196,7 +194,7 @@ class GroupListControllerImpl extends DbControllerImpl
handler.onResult(
groupInvitationManager.getInvitations().size());
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});

View File

@@ -16,7 +16,6 @@ import org.briarproject.briar.android.privategroup.conversation.GroupActivity;
import org.briarproject.briar.android.util.UiUtils;
import org.briarproject.briar.android.view.TextAvatarView;
import static android.support.v4.content.ContextCompat.getColor;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID;
@@ -83,8 +82,6 @@ class GroupViewHolder extends RecyclerView.ViewHolder {
postCount.setText(ctx.getResources()
.getQuantityString(R.plurals.messages, messageCount,
messageCount));
postCount.setTextColor(
getColor(ctx, R.color.briar_text_secondary));
long lastUpdate = group.getTimestamp();
date.setText(UiUtils.formatDate(ctx, lastUpdate));

View File

@@ -19,6 +19,7 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
class GroupMemberListControllerImpl extends DbControllerImpl
implements GroupMemberListController {
@@ -56,7 +57,7 @@ class GroupMemberListControllerImpl extends DbControllerImpl
}
handler.onResult(items);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});

View File

@@ -28,6 +28,7 @@ import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
import static org.briarproject.briar.api.privategroup.Visibility.INVISIBLE;
@@ -65,7 +66,7 @@ class RevealContactsControllerImpl extends DbControllerImpl
try {
handler.onResult(getItems(g, selection));
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
});
@@ -106,7 +107,7 @@ class RevealContactsControllerImpl extends DbControllerImpl
settings.getBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS,
true));
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
}
@@ -121,8 +122,7 @@ class RevealContactsControllerImpl extends DbControllerImpl
settings.putBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS, false);
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -136,11 +136,9 @@ class RevealContactsControllerImpl extends DbControllerImpl
groupInvitationManager.revealRelationship(c, g);
} catch (ProtocolStateException e) {
// action is outdated, move to next contact
if (LOG.isLoggable(INFO))
LOG.log(INFO, e.toString(), e);
logException(LOG, INFO, e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
handler.onException(e);
break;
}

View File

@@ -3,6 +3,7 @@ package org.briarproject.briar.android.reporting;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
@@ -33,6 +34,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Logger;
import static android.os.Build.VERSION.SDK_INT;
import static android.view.View.GONE;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
@@ -83,10 +85,27 @@ public class DevReportActivity extends BaseCrashReportDialog
}
@Override
public void onCreate(Bundle state) {
protected void preInit(@Nullable Bundle savedInstanceState) {
super.preInit(savedInstanceState);
getDelegate().installViewFactory();
getDelegate().onCreate(state);
super.onCreate(state);
getDelegate().onCreate(savedInstanceState);
if (getDelegate().applyDayNight()) {
// If DayNight has been applied, we need to re-apply the theme for
// the changes to take effect. On API 23+, we should bypass
// setTheme(), which will no-op if the theme ID is identical to the
// current theme ID.
int theme = R.style.BriarTheme_NoActionBar;
if (SDK_INT >= 23) {
onApplyThemeResource(getTheme(), theme, false);
} else {
setTheme(theme);
}
}
}
@Override
public void init(Bundle state) {
super.init(state);
getDelegate().setContentView(R.layout.activity_dev_report);
@@ -94,6 +113,7 @@ public class DevReportActivity extends BaseCrashReportDialog
getDelegate().setSupportActionBar(tb);
View requestReport = findViewById(R.id.request_report);
View reportForm = findViewById(R.id.report_form);
userCommentView = findViewById(R.id.user_comment);
userEmailView = findViewById(R.id.user_email);
includeDebugReport = findViewById(R.id.include_debug_report);
@@ -111,13 +131,18 @@ public class DevReportActivity extends BaseCrashReportDialog
if (isFeedback()) {
includeDebugReport
.setText(getString(R.string.include_debug_report_feedback));
reportForm.setVisibility(VISIBLE);
requestReport.setVisibility(INVISIBLE);
} else {
includeDebugReport.setChecked(true);
reportForm.setVisibility(INVISIBLE);
requestReport.setVisibility(VISIBLE);
}
findViewById(R.id.acceptButton).setOnClickListener(v -> {
reviewing = true;
requestReport.setVisibility(GONE);
reportForm.setVisibility(VISIBLE);
requestReport.setVisibility(INVISIBLE);
((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
.showSoftInput(userCommentView, SHOW_FORCED);
});
@@ -165,7 +190,6 @@ public class DevReportActivity extends BaseCrashReportDialog
MenuInflater inflater = getDelegate().getMenuInflater();
inflater.inflate(R.menu.dev_report_actions, menu);
sendReport = menu.findItem(R.id.action_send_report);
return super.onCreateOptionsMenu(menu);
}
@@ -258,27 +282,27 @@ public class DevReportActivity extends BaseCrashReportDialog
if (crashData != null) {
for (Entry<ReportField, String> e : crashData.entrySet()) {
ReportField field = e.getKey();
String value = e.getValue().replaceAll("\\\\n", "\n");
boolean required = requiredFields.contains(field);
boolean excluded = excludedFields.contains(field);
View v = inflater.inflate(R.layout.list_item_crash,
report, false);
CheckBox cb = v
.findViewById(R.id.include_in_report);
CheckBox cb = v.findViewById(R.id.include_in_report);
cb.setTag(field);
cb.setChecked(required || !excluded);
cb.setEnabled(!required);
cb.setOnCheckedChangeListener(DevReportActivity.this);
((TextView) v.findViewById(R.id.title))
.setText(e.getKey().toString());
((TextView) v.findViewById(R.id.content))
.setText(e.getValue());
TextView title = v.findViewById(R.id.title);
title.setText(field.toString());
TextView content = v.findViewById(R.id.content);
content.setText(value);
report.addView(v);
}
} else {
View v = inflater.inflate(
android.R.layout.simple_list_item_1, report, false);
((TextView) v.findViewById(android.R.id.text1))
.setText(R.string.could_not_load_report_data);
TextView error = v.findViewById(android.R.id.text1);
error.setText(R.string.could_not_load_report_data);
report.addView(v);
}
report.setVisibility(VISIBLE);

View File

@@ -36,5 +36,4 @@ public class SettingsActivity extends BriarActivity {
}
return false;
}
}

View File

@@ -1,6 +1,7 @@
package org.briarproject.briar.android.settings;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.media.Ringtone;
@@ -8,6 +9,7 @@ import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.StringRes;
import android.support.v4.text.TextUtilsCompat;
import android.support.v7.preference.CheckBoxPreference;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
@@ -30,13 +32,21 @@ import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.R;
import org.briarproject.briar.android.Localizer;
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
import org.briarproject.briar.android.util.UiUtils;
import org.briarproject.briar.android.util.UserFeedback;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.logging.Logger;
import javax.inject.Inject;
import static android.app.Activity.RESULT_OK;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.media.RingtoneManager.ACTION_RINGTONE_PICKER;
import static android.media.RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI;
import static android.media.RingtoneManager.EXTRA_RINGTONE_EXISTING_URI;
@@ -50,14 +60,20 @@ import static android.provider.Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS;
import static android.provider.Settings.EXTRA_APP_PACKAGE;
import static android.provider.Settings.EXTRA_CHANNEL_ID;
import static android.provider.Settings.System.DEFAULT_NOTIFICATION_URI;
import static android.support.v4.view.ViewCompat.LAYOUT_DIRECTION_LTR;
import static android.widget.Toast.LENGTH_SHORT;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_ALWAYS;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_DARK_THEME;
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_RINGTONE;
import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.INTENT_SIGN_OUT;
import static org.briarproject.briar.api.android.AndroidNotificationManager.BLOG_CHANNEL_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.CONTACT_CHANNEL_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.FORUM_CHANNEL_ID;
@@ -80,11 +96,13 @@ public class SettingsFragment extends PreferenceFragmentCompat
public static final String SETTINGS_NAMESPACE = "android-ui";
public static final String BT_NAMESPACE = BluetoothConstants.ID.getString();
public static final String TOR_NAMESPACE = TorConstants.ID.getString();
public static final String LANGUAGE = "pref_key_language";
private static final Logger LOG =
Logger.getLogger(SettingsFragment.class.getName());
private SettingsActivity listener;
private ListPreference language;
private ListPreference enableBluetooth;
private ListPreference torNetwork;
private CheckBoxPreference notifyPrivateMessages;
@@ -119,6 +137,10 @@ public class SettingsFragment extends PreferenceFragmentCompat
public void onCreatePreferences(Bundle bundle, String s) {
addPreferencesFromResource(R.xml.settings);
language = (ListPreference) findPreference(LANGUAGE);
setLanguageEntries();
ListPreference theme =
(ListPreference) findPreference("pref_key_theme");
enableBluetooth = (ListPreference) findPreference("pref_key_bluetooth");
torNetwork = (ListPreference) findPreference("pref_key_tor_network");
notifyPrivateMessages = (CheckBoxPreference) findPreference(
@@ -137,6 +159,25 @@ public class SettingsFragment extends PreferenceFragmentCompat
setSettingsEnabled(false);
language.setOnPreferenceChangeListener(this);
theme.setOnPreferenceChangeListener((preference, newValue) -> {
if (getActivity() != null) {
// activate new theme
UiUtils.setTheme(getActivity(), (String) newValue);
// bring up parent activity, so it can change its theme as well
// upstream bug: https://issuetracker.google.com/issues/38352704
Intent intent =
new Intent(getActivity(), NavDrawerActivity.class);
intent.setFlags(
FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
// bring this activity back to the foreground
intent = new Intent(getActivity(), getActivity().getClass());
startActivity(intent);
getActivity().finish();
}
return true;
});
enableBluetooth.setOnPreferenceChangeListener(this);
torNetwork.setOnPreferenceChangeListener(this);
if (SDK_INT >= 21) {
@@ -157,6 +198,8 @@ public class SettingsFragment extends PreferenceFragmentCompat
}
);
} else {
theme.setVisible(FEATURE_FLAG_DARK_THEME);
findPreference("pref_key_explode").setVisible(false);
findPreference("pref_key_test_data").setVisible(false);
PreferenceGroup testing =
@@ -180,24 +223,67 @@ public class SettingsFragment extends PreferenceFragmentCompat
eventBus.removeListener(this);
}
private void setLanguageEntries() {
CharSequence[] tags = language.getEntryValues();
List<CharSequence> entries = new ArrayList<>(tags.length);
List<CharSequence> entryValues = new ArrayList<>(tags.length);
for (CharSequence cs : tags) {
String tag = cs.toString();
if (tag.equals("default")) {
entries.add(getString(R.string.pref_language_default));
entryValues.add(tag);
continue;
}
Locale locale = Localizer.getLocaleFromTag(tag);
if (locale == null)
throw new IllegalStateException();
// Exclude RTL locales on API < 17, they won't be laid out correctly
if (SDK_INT < 17 && !isLeftToRight(locale)) {
if (LOG.isLoggable(INFO))
LOG.info("Skipping RTL locale " + tag);
continue;
}
String nativeName = locale.getDisplayName(locale);
// Fallback to English if the name is unknown in both native and
// current locale.
if (nativeName.equals(tag)) {
String tmp = locale.getDisplayLanguage(Locale.ENGLISH);
if (!tmp.isEmpty() && !tmp.equals(nativeName))
nativeName = tmp;
}
// Prefix with LRM marker to prevent any RTL direction
entries.add("\u200E" + nativeName.substring(0, 1).toUpperCase()
+ nativeName.substring(1));
entryValues.add(tag);
}
language.setEntries(entries.toArray(new CharSequence[0]));
language.setEntryValues(entryValues.toArray(new CharSequence[0]));
}
private boolean isLeftToRight(Locale locale) {
// TextUtilsCompat returns the wrong direction for Hebrew on some phones
String language = locale.getLanguage();
if (language.equals("iw") || language.equals("he")) return false;
int direction = TextUtilsCompat.getLayoutDirectionFromLocale(locale);
return direction == LAYOUT_DIRECTION_LTR;
}
private void loadSettings() {
listener.runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
Settings btSettings = settingsManager.getSettings(BT_NAMESPACE);
Settings torSettings =
settingsManager.getSettings(TOR_NAMESPACE);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading settings took " + duration + " ms");
logDuration(LOG, "Loading settings", start);
boolean btSetting =
btSettings.getBoolean(PREF_BT_ENABLE, false);
int torSetting = torSettings.getInt(PREF_TOR_NETWORK,
PREF_TOR_NETWORK_ALWAYS);
displaySettings(btSetting, torSetting);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -260,6 +346,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
}
private void setSettingsEnabled(boolean enabled) {
// theme not needed here, because handled by SharedPreferences
enableBluetooth.setEnabled(enabled);
torNetwork.setEnabled(enabled);
notifyPrivateMessages.setEnabled(enabled);
@@ -312,53 +399,75 @@ public class SettingsFragment extends PreferenceFragmentCompat
}
@Override
public boolean onPreferenceChange(Preference preference, Object o) {
if (preference == enableBluetooth) {
boolean btSetting = Boolean.valueOf((String) o);
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference == language) {
if (!language.getValue().equals(newValue))
languageChanged((String) newValue);
return false;
} else if (preference == enableBluetooth) {
boolean btSetting = Boolean.valueOf((String) newValue);
storeBluetoothSettings(btSetting);
} else if (preference == torNetwork) {
int torSetting = Integer.valueOf((String) o);
int torSetting = Integer.valueOf((String) newValue);
storeTorSettings(torSetting);
} else if (preference == notifyPrivateMessages) {
Settings s = new Settings();
s.putBoolean(PREF_NOTIFY_PRIVATE, (Boolean) o);
s.putBoolean(PREF_NOTIFY_PRIVATE, (Boolean) newValue);
storeSettings(s);
} else if (preference == notifyGroupMessages) {
Settings s = new Settings();
s.putBoolean(PREF_NOTIFY_GROUP, (Boolean) o);
s.putBoolean(PREF_NOTIFY_GROUP, (Boolean) newValue);
storeSettings(s);
} else if (preference == notifyForumPosts) {
Settings s = new Settings();
s.putBoolean(PREF_NOTIFY_FORUM, (Boolean) o);
s.putBoolean(PREF_NOTIFY_FORUM, (Boolean) newValue);
storeSettings(s);
} else if (preference == notifyBlogPosts) {
Settings s = new Settings();
s.putBoolean(PREF_NOTIFY_BLOG, (Boolean) o);
s.putBoolean(PREF_NOTIFY_BLOG, (Boolean) newValue);
storeSettings(s);
} else if (preference == notifyVibration) {
Settings s = new Settings();
s.putBoolean(PREF_NOTIFY_VIBRATION, (Boolean) o);
s.putBoolean(PREF_NOTIFY_VIBRATION, (Boolean) newValue);
storeSettings(s);
} else if (preference == notifyLockscreen) {
Settings s = new Settings();
s.putBoolean(PREF_NOTIFY_LOCK_SCREEN, (Boolean) o);
s.putBoolean(PREF_NOTIFY_LOCK_SCREEN, (Boolean) newValue);
storeSettings(s);
}
return true;
}
private void languageChanged(String newValue) {
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.pref_language_title);
builder.setMessage(R.string.pref_language_changed);
builder.setPositiveButton(R.string.sign_out_button,
(dialogInterface, i) -> {
language.setValue(newValue);
Intent intent = new Intent(getContext(),
NavDrawerActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra(INTENT_SIGN_OUT, true);
getActivity().startActivity(intent);
getActivity().finish();
});
builder.setNegativeButton(R.string.cancel, null);
builder.setCancelable(false);
builder.show();
}
private void storeTorSettings(int torSetting) {
listener.runOnDbThread(() -> {
try {
Settings s = new Settings();
s.putInt(PREF_TOR_NETWORK, torSetting);
long now = System.currentTimeMillis();
long start = now();
settingsManager.mergeSettings(s, TOR_NAMESPACE);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Merging settings took " + duration + " ms");
logDuration(LOG, "Merging settings", start);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -368,13 +477,11 @@ public class SettingsFragment extends PreferenceFragmentCompat
try {
Settings s = new Settings();
s.putBoolean(PREF_BT_ENABLE, btSetting);
long now = System.currentTimeMillis();
long start = now();
settingsManager.mergeSettings(s, BT_NAMESPACE);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Merging settings took " + duration + " ms");
logDuration(LOG, "Merging settings", start);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}
@@ -382,13 +489,11 @@ public class SettingsFragment extends PreferenceFragmentCompat
private void storeSettings(Settings settings) {
listener.runOnDbThread(() -> {
try {
long now = System.currentTimeMillis();
long start = now();
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Merging settings took " + duration + " ms");
logDuration(LOG, "Merging settings", start);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
logException(LOG, WARNING, e);
}
});
}

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