Compare commits

...

3083 Commits

Author SHA1 Message Date
Greyson Parrelli
bf40a07bb9 Bump version to 4.63.2 2020-06-10 14:43:24 -04:00
Greyson Parrelli
8f3a6b8479 Update unblock string. 2020-06-10 14:37:03 -04:00
Greyson Parrelli
7642b7cc72 Fix issue with typing indicators in blocked groups. 2020-06-10 14:28:12 -04:00
Greyson Parrelli
e12ea60d85 Bump version to 4.63.1 2020-06-10 12:48:15 -04:00
Greyson Parrelli
0b13c4aed6 Updated language translations. 2020-06-10 12:48:15 -04:00
Alan Evans
47919382e9 Show 'Add to another group' when launched from a group context. 2020-06-10 12:59:57 -03:00
Greyson Parrelli
d60d67ee7e Set contact colors more aggressively. 2020-06-10 10:49:22 -04:00
Alan Evans
559aa687a5 Show group participants menu item on a MMS group. 2020-06-10 11:32:50 -03:00
Cody Henthorne
bc0761f002 Fix navigate up behavior for Conversations. 2020-06-10 10:28:34 -04:00
Alan Evans
c0c2fc0eba When there are no recipients left on group create screen toast and return to list. 2020-06-10 09:07:12 -03:00
Alan Evans
44fe43c74c Hide 'Add to a group' for non-registered users. 2020-06-10 08:54:57 -03:00
Alan Evans
53a2a5d693 Prevent highlighter opacity affecting blur tool. 2020-06-09 23:56:03 -03:00
Greyson Parrelli
2334c26cbb Bump version to 4.63.0 2020-06-09 16:56:57 -04:00
Greyson Parrelli
0b6dde46d9 Updated language translations. 2020-06-09 16:55:50 -04:00
Greyson Parrelli
98d9d81aff Insert receipts in a transaction. 2020-06-09 15:11:37 -04:00
Greyson Parrelli
736a62b632 Update strings related to message requests. 2020-06-09 14:12:52 -04:00
Cody Henthorne
cea6a83d8a Show member count in contact selection list. 2020-06-09 13:32:48 -04:00
Greyson Parrelli
2751fd7efc Retrieve profiles in parallel. 2020-06-09 12:47:11 -04:00
Cody Henthorne
2822042eeb Show recent groups in Add to Groups screen. 2020-06-09 12:13:13 -04:00
Cody Henthorne
dc46d88ddd Provide two ways of listening for thread/message db updates. 2020-06-09 11:52:58 -04:00
Alex Hart
e04f76b558 Fix issue where invalid PagedList objects were passed to ConversationAdapter. 2020-06-09 12:37:19 -03:00
Alan Evans
a758056494 Take highlighter down from 50% to 37.5% opacity. 2020-06-09 12:35:53 -03:00
Alan Evans
1ecdea5db3 Reinstate highlighter under drawing menu. 2020-06-09 12:10:40 -03:00
Alan Evans
e1bb773d85 Add 'Add to a group' button to bottom sheet. 2020-06-09 12:09:59 -03:00
Alan Evans
7e934eff5d Make quotes not hold strong references to attachments. 2020-06-09 12:07:41 -03:00
Greyson Parrelli
cfdf5603af Bump version to 4.62.4 2020-06-09 00:39:55 -04:00
Greyson Parrelli
45bfb8c6b6 Updated language translations. 2020-06-09 00:38:19 -04:00
Alex Hart
65608a51b8 Fix API 19 crash by using different resource. 2020-06-09 00:33:38 -04:00
Greyson Parrelli
b6314597fe Bump version to 4.62.3 2020-06-08 16:32:08 -04:00
Greyson Parrelli
20a588199a Updated language translations. 2020-06-08 16:32:00 -04:00
Greyson Parrelli
59916f1e95 Add 'Add to contacts' button to bottom sheet. 2020-06-08 16:07:14 -04:00
Alan Evans
8b91f8f9e7 Disable disappearing messages option and remove from menu. 2020-06-08 12:31:55 -03:00
Alex Hart
cbc3cce66f Fix API 19 drawable crash in ManageGroupFragment. 2020-06-08 11:34:39 -03:00
Alex Hart
b4b63b5860 Add auto-mirroring to ic_forward_outline. 2020-06-08 10:23:43 -03:00
Alex Hart
b9ae15a890 Fix group name RTL alignment. 2020-06-08 10:21:55 -03:00
Greyson Parrelli
d955389c46 Bump version to 4.62.2 2020-06-07 22:05:02 -04:00
Greyson Parrelli
975eb885c1 Updated language translations. 2020-06-07 22:05:02 -04:00
Alan Evans
a3aed96757 Sort contacts without names after contacts with names. 2020-06-07 22:05:02 -04:00
Alan Evans
dc70bfabaf Lighter ultramarine + in dark mode. 2020-06-07 22:05:02 -04:00
Greyson Parrelli
6932340671 Add ability to copy a number via long-press. 2020-06-07 19:59:42 -04:00
Alan Evans
f6637b7caf Restore mute in conversation menu. 2020-06-07 19:59:42 -04:00
Alan Evans
4f4be44caa Load identities in transaction. 2020-06-07 19:59:42 -04:00
Greyson Parrelli
7832497ba7 Shorten logging in ConversationActivity. 2020-06-07 19:59:42 -04:00
Alex Hart
7d06e2395f Rework how ConversationFragment RecyclerView responds to data updates. 2020-06-07 19:59:42 -04:00
Greyson Parrelli
3a479d7eef Reduce database notifications for disappearing conversations. 2020-06-07 19:59:42 -04:00
Greyson Parrelli
8fe8a1e9ee Put refresh and upload profile jobs in the same queue. 2020-06-07 19:59:42 -04:00
Alan Evans
2d8b2e7fb0 Transitions for group settings. 2020-06-07 19:59:42 -04:00
Alan Evans
9c0365f92c Open group settings from group avatar click. 2020-06-07 19:59:42 -04:00
Greyson Parrelli
b48abb08d2 Show custom notifications for API < 26. 2020-06-07 19:59:42 -04:00
Alan Evans
d8f3e032c7 Fix group name clearing after avatar change. 2020-06-07 19:59:42 -04:00
Alan Evans
8dbcb255ad Hide Block and Leave options when not available in group settings, add unblock. 2020-06-07 19:59:42 -04:00
Greyson Parrelli
db06cbbc86 Remove unnecessary recipient refreshes. 2020-06-07 19:59:42 -04:00
Cody Henthorne
98ab23c1a3 Make Custom Notification dialog dismiss itself on up press. 2020-06-07 10:23:41 -04:00
Cody Henthorne
d0ca9ba6a6 Make text button color responsive to theme. 2020-06-07 09:43:14 -04:00
Alan Evans
b242368675 Remove group members button. 2020-06-07 09:31:18 -03:00
Alan Evans
664527ce63 Fix sort order for group members. 2020-06-07 08:25:31 -03:00
Alan Evans
99e4f80be0 Allow whole row selection for Shared media in group settings. 2020-06-07 08:12:25 -03:00
Alan Evans
702dae9fcd Fix double tap required for "See all" media in group settings. 2020-06-07 07:47:28 -03:00
Alan Evans
48fe1ba559 Fix group settings divider shade in dark mode. 2020-06-07 07:42:28 -03:00
Greyson Parrelli
382ac7ba0d Bump version to 4.62.1 2020-06-06 20:28:18 -04:00
Greyson Parrelli
a46f47f352 Updated language translations. 2020-06-06 20:27:48 -04:00
Greyson Parrelli
e984d8a42c Change Gif -> GIF. 2020-06-06 20:27:22 -04:00
Greyson Parrelli
554bad6b8d Improve DB access in group sends. 2020-06-06 20:25:02 -04:00
Jim Gustafson
ed13c97ad7 Handle legacy hangup properly. 2020-06-06 20:25:02 -04:00
Greyson Parrelli
d33873d59a Fix possible crash with null thread body. 2020-06-06 20:25:02 -04:00
Greyson Parrelli
1234899ea1 Add support for non-blocking media sends. 2020-06-06 20:25:02 -04:00
Cody Henthorne
13027dc44b Fix leaking MessageDetailsActivity via list items. 2020-06-06 20:25:02 -04:00
Cody Henthorne
5b4d74b7fe Move group resolution for conversations to background LiveData. 2020-06-06 20:25:02 -04:00
Alan Evans
18c7bc2b5b Prevent edit of a group post leave. 2020-06-06 20:25:02 -04:00
Alan Evans
bbbee0f372 Fix group create arrow for RTL. 2020-06-06 20:25:02 -04:00
Alex Hart
cf9d090154 Start Paging @ Unread count instead of -1. 2020-06-06 20:25:02 -04:00
Alan Evans
718471917f Separate text only message layouts. 2020-06-06 20:25:02 -04:00
Greyson Parrelli
bb97407cde Bump version to 4.62.0 2020-06-05 22:04:18 -04:00
Greyson Parrelli
92ce678e29 Updated language translations. 2020-06-05 22:04:16 -04:00
Cody Henthorne
e100aea2c7 Preserve scroll position in Message Details on update. 2020-06-05 21:46:04 -04:00
Greyson Parrelli
fea3b6cb4a Don't show 'conversation settings' for groups. 2020-06-05 21:46:04 -04:00
Cody Henthorne
afbc132faa Fix conversation item and data source memory leaks. 2020-06-05 21:46:04 -04:00
Alan Evans
b27198286d MMS proof new group UI. 2020-06-05 21:46:04 -04:00
Greyson Parrelli
ac93d81032 Remove pins4all feature flag. 2020-06-05 21:46:04 -04:00
Alan Evans
9981e5ca76 Enable new group UI. 2020-06-05 20:19:03 -03:00
Cody Henthorne
7dd3efeb53 Remove listeners when detaching conversation item views. 2020-06-05 19:29:55 -03:00
Greyson Parrelli
d38d702adf Parallelize group sends. 2020-06-05 18:10:50 -04:00
Alex Hart
04a000a8a8 Always display labels in contact search. 2020-06-05 15:16:55 -03:00
Fumiaki Yoshimatsu
3bbf0741ee Use localized string for Phone number.
Fixes #9626
2020-06-05 15:01:20 -03:00
Fumiaki Yoshimatsu
e9a336100b Display backup date in users locale on restore.
Fixes #9693
2020-06-05 15:01:20 -03:00
Cody Henthorne
fb600e9829 Update SMS/MMS as sending when retrying failed send.
This was only impacting SMS/MMS as Push already reset the status.
2020-06-05 13:46:25 -04:00
Alex Hart
4a455ff958 Implement new Add Members UI. 2020-06-05 13:44:02 -03:00
Cody Henthorne
707e238e5c Make borderless button style responsive to theme. 2020-06-05 12:01:00 -04:00
Alan Evans
90f22a4b66 Include face position and projection matrix into elements matrix. 2020-06-04 19:49:22 -03:00
Alex Hart
b4f134adf7 Add more descriptive messages for media notifications and chat previews. 2020-06-04 13:13:42 -03:00
Greyson Parrelli
1e00fc6149 Bump version to 4.61.6 2020-06-04 10:21:23 -04:00
Greyson Parrelli
f52133a69c Updated language translations. 2020-06-04 10:21:23 -04:00
Alan Evans
91b142e0d9 Fix waveform array out of bounds. 2020-06-04 10:21:10 -04:00
Greyson Parrelli
26a9dd98c1 Bump version to 4.61.5 2020-06-03 19:01:03 -04:00
Greyson Parrelli
99e38e1d23 Updated language translations. 2020-06-03 18:58:34 -04:00
Greyson Parrelli
a2d8a25fd9 Blur UI tweaks. 2020-06-03 18:51:38 -04:00
Alan Evans
d86d625bcc Smoother blur rendering. 2020-06-03 19:47:51 -03:00
Greyson Parrelli
18e3fb6609 Fix string format. 2020-06-03 17:19:32 -04:00
Greyson Parrelli
da33ba0ed5 Update blur UI. 2020-06-03 17:12:47 -04:00
Greyson Parrelli
66f021d01a Fix issue where rail wasn't showing in some situations. 2020-06-03 17:12:47 -04:00
Greyson Parrelli
40231ea45f Fix issue with view-once toggle and face blurring. 2020-06-03 17:12:42 -04:00
Alex Hart
cd80a47c04 Made edit profile save button move with the keyboard. 2020-06-03 17:12:27 -04:00
Alan Evans
1033bd7bda Blur faces rotation and crop and zoom support. 2020-06-03 14:02:24 -03:00
Greyson Parrelli
b4f60f3acb Bump version to 4.61.4 2020-06-03 06:40:09 -04:00
Greyson Parrelli
bed3b571cc Updated language translations. 2020-06-03 06:39:34 -04:00
Greyson Parrelli
c8dd4e5254 Added support for blurring faces.
Co-authored-by: Alan Evans <alan@signal.org>
2020-06-03 06:39:20 -04:00
Alan Evans
514048171b Add Image Editor support for blur mask layer. 2020-06-03 03:33:06 -03:00
Greyson Parrelli
32e9901592 Bump version to 4.61.3 2020-06-02 19:22:22 -04:00
Greyson Parrelli
d83f86a469 Revert "Make notifications and chat previews for media messages more descriptive."
This reverts commit a3f9737e63.
2020-06-02 19:19:30 -04:00
Greyson Parrelli
403d53586c Bump version to 4.61.2 2020-06-02 17:40:56 -04:00
Greyson Parrelli
6acae58694 Updated language translations. 2020-06-02 17:33:41 -04:00
Alex Hart
a3f9737e63 Make notifications and chat previews for media messages more descriptive. 2020-06-02 17:34:50 -03:00
Cody Henthorne
263af7c139 Add registration lock status to support email. 2020-06-02 16:14:19 -04:00
Alex Hart
7f2439f1e9 Fix contact selection behavior when searching and clear search on selection. 2020-06-02 16:27:04 -03:00
Alex Hart
ae87d23003 Always use the new group settings screen if the flag is enabled. 2020-06-02 16:09:48 -03:00
Alex Hart
3192cc0aac Add outlined view-once close icon. 2020-06-02 16:05:16 -03:00
Alex Hart
6102e9aa72 Apply better coordinatorlayout animation and RTL support. 2020-06-02 15:02:35 -03:00
Alan Evans
f4a152b0fe Fetch own profile after GV2 feature flag is enabled, improve GV2 capability check. 2020-06-02 11:48:40 -03:00
Greyson Parrelli
2b11bca7dc Guard against possible invalid conversation data loads. 2020-06-02 10:20:55 -04:00
Artem Varaksa
07d19f38e3 Fix typos in logging for remote delete. 2020-06-02 10:22:29 -03:00
Greyson Parrelli
cd228c439e Be more explicit with the ID we use for account updates. 2020-06-02 09:03:54 -04:00
Alan Evans
7a859c8961 For smaller width devices, use original 210dp for audio messages. 2020-06-02 09:32:59 -03:00
Alan Evans
543f38c75d Fix Wave form IOException thread issue. 2020-06-02 07:38:15 -03:00
Greyson Parrelli
f7b150f2d2 Bump version to 4.61.1 2020-06-01 17:43:05 -04:00
Greyson Parrelli
11328f643f Updated language translations. 2020-06-01 17:43:05 -04:00
Greyson Parrelli
f270a6b8c4 Fix potential crash by removing an unnecessary column.
The column I removed is already in the recipient half of the projection.
Having two representations of the groupId made reading the groupId out
of the cursor non-deterministic, and when compounded with another bug,
could cause a crash if one of them was null.
2020-06-01 17:43:05 -04:00
Alan Evans
3fec23fd36 Show remaining time on wave form view and cache wave form in database. 2020-06-01 17:43:05 -04:00
Alex Hart
e01838e996 Fix text size for pending members. 2020-06-01 17:43:05 -04:00
Greyson Parrelli
f70e41e7cd Don't allow account record updates to delete our profile key. 2020-06-01 17:43:05 -04:00
Greyson Parrelli
c4ec0c9897 Handle devices disallowing start of FcmFetchService.
Some devices are overzealous with battery management and disallow
starting services even when they're in response to a high-priority FCM
message (which should be allowed). So in these situations, we just
fall back to what we were doing before.
2020-06-01 17:43:05 -04:00
Greyson Parrelli
989b071a6d Ignore contacts that don't have a phone number. 2020-06-01 17:43:05 -04:00
Greyson Parrelli
c39751f9db Add info about play services to the debug log. 2020-06-01 17:43:05 -04:00
jimio-signal
dbf74a2234 Update copyright in README.md 2020-05-31 10:39:19 -07:00
Greyson Parrelli
837230d72d Bump version to 4.61.0 2020-05-29 19:18:55 -04:00
Greyson Parrelli
f544ec4126 Updated language translations. 2020-05-29 19:18:02 -04:00
Greyson Parrelli
79dbf85c1e Improve local encrypted PIN storage. 2020-05-29 19:15:56 -04:00
Greyson Parrelli
61fe6cc961 Enable the ability to react with any emoji. 2020-05-29 19:14:37 -04:00
Greyson Parrelli
70c88b68e2 Store recent reactions separately from keyboard emoji. 2020-05-29 19:14:37 -04:00
Greyson Parrelli
d70c33d20f Add support for mark as unread. 2020-05-29 19:14:37 -04:00
Greyson Parrelli
6b2e000e61 Prevent waiting for old queues in our retrieval strategies. 2020-05-29 19:14:37 -04:00
Alan Evans
b9f11dafff New internal testing flag and V1 group creation button. All menus create GV1. 2020-05-29 19:14:37 -04:00
Alan Evans
9b32eaeb8a Do not log URLs. 2020-05-29 19:14:37 -04:00
Alan Evans
a99c0d438e Rename GV2 "version" to "revision". 2020-05-29 19:14:37 -04:00
Alex Hart
c634c24afb Utilize Wrapper instead of dynamic theme. 2020-05-29 19:14:37 -04:00
Alex Hart
2ddd1437cf Utilize exclusive AudioFocus. 2020-05-29 19:14:37 -04:00
Alan Evans
9da309ca48 Enforce a local GV2 capacity limit driven by a feature flag. 2020-05-29 19:14:37 -04:00
henry
cfcd451db7 Fix crash on unlink device when offline. 2020-05-29 09:51:21 -04:00
Alex Hart
5ab72fd1a9 Ask for permission before launching avatar sheet. 2020-05-29 09:51:21 -04:00
Alan Evans
daace9bd1a Audio wave forms on voice notes. 2020-05-29 09:51:21 -04:00
Alan Evans
69adcd1d69 Tap avatar in chat preferences or group management to see full screen. 2020-05-29 09:51:21 -04:00
Alex Hart
0711a22188 Add overflow toast and fix edit menu option. 2020-05-29 09:51:21 -04:00
Greyson Parrelli
3a06412cd8 Throttle notifications when doing the intial message fetch. 2020-05-29 09:51:21 -04:00
Alan Evans
51c82702e2 Remove expectation of ActionBar in DeviceProvisioningActivity.
Fixes #9661
2020-05-29 09:51:21 -04:00
Greyson Parrelli
1b01196ec6 Refactor ThreadRecord. 2020-05-29 09:51:21 -04:00
Greyson Parrelli
1cd6b58ece Don't enqueue duplicate PushDecryptMessageJobs. 2020-05-29 09:51:21 -04:00
Greyson Parrelli
ea8e13b1c8 Create a WebsocketDrainedConstraint. 2020-05-29 09:51:21 -04:00
Greyson Parrelli
f392229393 Extract MessageNotifier interface. 2020-05-29 09:51:21 -04:00
Greyson Parrelli
a299bafe89 Create a new system for fetching the intial batch of messages. 2020-05-29 09:51:21 -04:00
Alex Hart
d2bf539504 Clear sticky WebRtcViewModel events when initiating a new call. 2020-05-29 09:51:21 -04:00
Alex Hart
903c3989b9 Fix chip jank and other groups v2 ux issues. 2020-05-29 09:51:21 -04:00
Alan Evans
00996f0d7a Rename back to build.gradle 2020-05-29 09:51:21 -04:00
Alan Evans
4aded3a436 Close keyboard on contact list scroll. 2020-05-29 09:51:20 -04:00
Alan Evans
9acdc37729 Alphabetical member order. 2020-05-29 09:51:20 -04:00
Greyson Parrelli
d4cdcbe54f Improve logging around group sends. 2020-05-29 09:51:20 -04:00
Alex Hart
6fa2a0f411 Polish UX for groups v2 management. 2020-05-29 09:51:20 -04:00
Alex Hart
558a8e4a14 Add polish to groups v2 creation flow. 2020-05-29 09:51:20 -04:00
Alan Evans
8947b82034 Make GV2 feature flags remote capable. 2020-05-29 09:51:20 -04:00
Alan Evans
56551025e9 Detect if group v2 is active from membership. 2020-05-29 09:51:20 -04:00
Alan Evans
befb4939d5 Restore groups from storage service. 2020-05-29 09:51:20 -04:00
Alan Evans
289f7aba63 Add versioned profiles feature flag. 2020-05-29 09:51:20 -04:00
Alan Evans
28bd245b96 While testing GV2 without UUID, fail jobs that hit UuidRecipientError. 2020-05-29 09:51:20 -04:00
Alan Evans
c5e7300df2 Fix matches logic in contact selection. 2020-05-29 09:51:20 -04:00
Greyson Parrelli
fe25d941bb Prevent FCM bottlenecking. 2020-05-29 09:51:20 -04:00
Alan Evans
4cda267f3b Show pending count and allow view of zero pending screen. 2020-05-29 09:51:20 -04:00
Alex Hart
82ba7e2b8b Display "You" at end of members list in ConversationTitleView. 2020-05-29 09:51:20 -04:00
Alex Hart
41ebaf3938 Clean up Overflow menu for GV2 groups. 2020-05-29 09:51:20 -04:00
Alex Hart
090c400037 Collapse title into toolbar on scroll in ManageGroupFragment. 2020-05-29 09:51:20 -04:00
Alan Evans
12b1232ac0 Fix groups v2 patch response handler. 2020-05-29 09:51:20 -04:00
Alex Hart
204a84c522 Apply proper spacing to RecipientBottomSheetDialogFragment. 2020-05-29 09:51:20 -04:00
Alan Evans
526afd539b Fix avatar tap in conversation multi-select mode. 2020-05-29 09:51:20 -04:00
Greyson Parrelli
d708984abd Require users be a system contact or whitelisted to appear in the contact list. 2020-05-29 09:51:20 -04:00
Greyson Parrelli
9d39db6428 Add additional account restore logging, prevent double avatar fetch. 2020-05-29 09:51:20 -04:00
Alan Evans
67a8ec0d39 Only admin can cancel any invite. 2020-05-29 09:51:20 -04:00
Alan Evans
297a7d0ef8 Handle absent change during invite. 2020-05-29 09:51:20 -04:00
Bastian Köcher
4712833853 Always convert HEIC images to JPEG.
This pr changes the behavior of sending HEIC images to always convert
them to JPEG. This conversion is required to support image inline
viewing accross different devices and operating systems. This follows
the same strategy as on IOS: https://github.com/signalapp/Signal-iOS/pull/2511

Fixes: https://github.com/signalapp/Signal-iOS/issues/4374 & https://github.com/signalapp/Signal-Android/issues/9395
2020-05-29 09:51:20 -04:00
Alan Evans
11d17f7496 GV2 storage service syncing. 2020-05-29 09:51:20 -04:00
Alan Evans
36df3f234f Enable the Zk group library. 2020-05-29 09:51:20 -04:00
Greyson Parrelli
098b298646 Add a network constraint to RemoteConfigRefreshJob. 2020-05-29 09:51:20 -04:00
Alan Evans
2f9320989a Server signed group v2 changes sent and received P2P. 2020-05-29 09:51:20 -04:00
Alan Evans
ec8d5defd4 Protect against unknown GV2 UUIDs. 2020-05-29 09:51:20 -04:00
Greyson Parrelli
981676c7f8 Bump version to 4.60.9 2020-05-29 09:40:26 -04:00
Greyson Parrelli
7c5ae57784 Updated language translations. 2020-05-29 09:38:57 -04:00
Alex Hart
fc7be87468 Downgrade AudioManagerCompat errors to warnings. 2020-05-29 10:31:36 -03:00
Greyson Parrelli
e55d8007fc Bump version to 4.60.8 2020-05-28 18:34:06 -04:00
Greyson Parrelli
43b7aa2d52 Updated language translations. 2020-05-28 18:33:46 -04:00
Alex Hart
cd1bad0718 Fix bluetooth behavior. 2020-05-28 17:36:40 -03:00
Greyson Parrelli
6b47618351 Bump version to 4.60.7 2020-05-26 18:27:05 -04:00
Greyson Parrelli
b6d384120d Updated language translations. 2020-05-26 18:26:39 -04:00
Greyson Parrelli
1268b26c1f Auto-dismiss PIN reminder dialog as you type. 2020-05-26 18:13:19 -04:00
Greyson Parrelli
f1233bfddc Bump version to 4.60.6 2020-05-25 14:57:59 -04:00
Greyson Parrelli
1aa3e6afea Updated language translations. 2020-05-25 14:57:59 -04:00
Greyson Parrelli
ce21eb241a Fix potential crash with data size in ConversationDataSource. 2020-05-25 14:57:59 -04:00
Greyson Parrelli
f96fb72eb1 Don't show PIN reminders if you're not registered.
Fixes #9657
2020-05-25 13:14:38 -04:00
Greyson Parrelli
207c467c6b Don't insert identity verification message for the initial restore. 2020-05-24 13:00:16 -04:00
Alex Hart
9d1d9e33ed Bumped version to 4.60.5 2020-05-21 20:03:31 -03:00
Alex Hart
e4a76c0690 Updated language translations. 2020-05-21 20:03:31 -03:00
Alex Hart
124c3e25e9 Implement layout changes to new call screen UX. 2020-05-21 20:03:31 -03:00
Greyson Parrelli
5cb1201903 Add the ability to disable PIN reminders. 2020-05-21 19:56:30 -03:00
Greyson Parrelli
bb6ca80d5a Don't create identity change methods for brand new contacts. 2020-05-21 19:56:30 -03:00
Greyson Parrelli
dc7c54a1f8 Ensure we upload the profile after a PIN restore. 2020-05-21 19:56:30 -03:00
Greyson Parrelli
23401440bf Prevent insertion of UUID-only contacts at the database level. 2020-05-21 19:56:30 -03:00
Greyson Parrelli
f8f959e05a Make rate limit message more generic. 2020-05-20 14:22:33 -04:00
Alex Hart
edbd4d2d03 Properly set profile key update flag. 2020-05-20 12:15:54 -03:00
Greyson Parrelli
a0b4065be3 Fix potention OOB error when pulse-highlighting a message.
This basically happened if you used full-text search to search for the
latest message in a conversation, but when you navigated there, it
*also* had a header set (like a typing indicator or unknownSenderView).
2020-05-19 17:09:25 -04:00
Greyson Parrelli
1b2f964f32 Fix possible crash around loading initial conversation pages. 2020-05-19 16:20:20 -04:00
Alex Hart
eaf5280d99 Bumped version to 4.60.4 2020-05-19 16:51:33 -03:00
Alex Hart
d435da980f Updated language translations. 2020-05-19 16:51:33 -03:00
Greyson Parrelli
8d3a91f3a4 Fix possible data source invalidation loop. 2020-05-19 16:51:33 -03:00
Greyson Parrelli
b80c339c5a Fix an issue where the add profile prompt wasn't dismissed. 2020-05-19 16:51:33 -03:00
Alan Evans
34159fc9da Log successful pin setting. 2020-05-19 16:34:52 -03:00
Alex Hart
b509ee9ee0 Bumped version to 4.60.3 2020-05-18 17:03:45 -03:00
Alex Hart
a6819448b9 fixup! Consolidate Call UI visibility selection logic. 2020-05-18 16:43:30 -03:00
Alex Hart
f2847f9aa5 Bumped version to 4.60.2 2020-05-18 16:31:20 -03:00
Alex Hart
8f01e5e1c3 Updated language translations. 2020-05-18 16:31:20 -03:00
Alan Evans
acb2f43620 Make Manage Group menu item replace Edit Group for GV2. 2020-05-18 16:31:20 -03:00
Greyson Parrelli
62ac65e4d8 Improve paging performance on slower devices. 2020-05-18 16:31:20 -03:00
Alex Hart
8f183bdcdc Consolidate Call UI visibility selection logic. 2020-05-18 16:31:20 -03:00
Greyson Parrelli
3d135d155e Disable view prefetching for now. 2020-05-18 16:31:20 -03:00
Alan Evans
090c811391 Force app compat version 1.1.0-beta01. 2020-05-18 16:31:20 -03:00
Alex Hart
2a9e8dc525 Bumped version to 4.60.1 2020-05-15 19:02:18 -03:00
Alex Hart
cb0b22cf2c Updated language translations. 2020-05-15 19:02:18 -03:00
Alex Hart
5aba3517ce Upgrade to RingRTC 2.0.3 and implement rounded corners for local pip. 2020-05-15 19:02:18 -03:00
Alex Hart
726f665388 Upgrade AppCompat to 1.2.0-rc01. 2020-05-15 19:02:18 -03:00
Alex Hart
e2ac55e9ac Fix ellapsed call timer restarting between activity restarts. 2020-05-15 19:02:18 -03:00
Greyson Parrelli
fa5729bac6 Better handle identity key changes in response to storage service syncs. 2020-05-15 19:02:18 -03:00
Greyson Parrelli
e714cb6423 Fix potential issues with ConversationDataSource boundaries. 2020-05-15 19:02:18 -03:00
Alex Hart
35a0162d5c Utilize EmojiTextView instead of TextView. 2020-05-15 19:02:18 -03:00
Alex Hart
76740adc3f Fix controls are removed when remote video is disabled. 2020-05-15 13:05:00 -03:00
Alex Hart
1c814141a2 Fix NullPointerException when trying to launch InviteActivity. 2020-05-15 10:43:25 -03:00
Alan Evans
5545daf992 Live group membership count in conversation. 2020-05-15 10:28:48 -03:00
Alan Evans
d300615d90 Ensure new group UI behind feature flag. 2020-05-15 10:27:39 -03:00
Alex Hart
908a5260c2 Enable note to self as recipient in share activity. 2020-05-15 10:03:49 -03:00
Alex Hart
7aac6644c3 Expand tappable area in header. 2020-05-14 16:27:52 -03:00
Alan Evans
3b673c07a0 Support gv2 avatar removal. 2020-05-14 15:57:40 -03:00
Alan Evans
d726da822c Add network constraint to GV2 messages. 2020-05-14 15:23:15 -03:00
Alex Hart
7894f72b0f Enable speaker when initiating a video call. 2020-05-14 14:18:49 -03:00
Alan Evans
4c5822ac67 GV2 Update message description. 2020-05-14 13:59:34 -03:00
Alex Hart
b917cccbee Bumped version to 4.60.0 2020-05-14 11:22:28 -03:00
Alex Hart
01d2d05d8e Updated language translations. 2020-05-14 11:22:28 -03:00
Alan Evans
4de86cb6cf Prevent ZkGroup link crashes. 2020-05-14 11:22:28 -03:00
henry
8861ad76ed Fix start SubmitDebugLog from registration and passphrase prompt. 2020-05-14 11:22:28 -03:00
Alan Evans
ef86372635 Ensure that the unknown UUID does not create an entry. 2020-05-14 11:22:28 -03:00
Alex Hart
ccff7b1148 Implement new group creation screens behind flag. 2020-05-14 11:22:28 -03:00
Greyson Parrelli
ed0825112d Fix some ordering problems with conversation data loading. 2020-05-14 11:22:28 -03:00
Alan Evans
b8df90531f GV2 message contexts. 2020-05-14 11:22:28 -03:00
Greyson Parrelli
f099c3591c Run PushProcessMessageJobs in parallel. 2020-05-14 11:22:28 -03:00
Greyson Parrelli
ed33e048ad Add CachedLayoutInflater to improve conversation render performance. 2020-05-14 11:22:28 -03:00
Greyson Parrelli
7fd3bfa30c Revert "Check to see if FCM is available at app launch."
This reverts commit eea7174f1d.
2020-05-14 11:22:28 -03:00
Alex Hart
07a492a32c Add dot character to reactions bottom sheet all tab label. 2020-05-14 11:22:28 -03:00
Alan Evans
11fffbd79e Remove P2P group change sending. 2020-05-14 11:22:28 -03:00
Alan Evans
eff564ad88 Adapt message requests to support invite flow. 2020-05-14 11:22:28 -03:00
Greyson Parrelli
d3d53e6099 Reduce recipient dirty state logging verbosity. 2020-05-14 11:22:28 -03:00
Greyson Parrelli
53d122ed55 Fix jumping to last seen position. 2020-05-14 11:22:28 -03:00
Alan Evans
1778c1ef7d Prevent some IOExceptions when past the end of stream. 2020-05-14 11:22:28 -03:00
Alan Evans
a510bc74e6 Recipient Id cache. 2020-05-14 11:22:28 -03:00
Alan Evans
a9ecdbdfec Groups V2 capability set by the feature flag. 2020-05-14 11:22:28 -03:00
Alan Evans
06ab3cf013 Fix cases of inlined & missing log tags. 2020-05-14 11:22:28 -03:00
Alan Evans
3db5da1c8d Generalize media input for use with Audio. 2020-05-14 11:22:28 -03:00
Greyson Parrelli
5937a50b6d Fix message receive timestamps on media messages. 2020-05-14 11:22:28 -03:00
Alan Evans
b4191ee5cc Fix usages of service logging in app. 2020-05-14 11:22:28 -03:00
Alan Evans
c63e42715e New logging lint checks.
[LogNotAppSignal] tells you about using signal service logger in the app.
[LogTagInlined] tells you about not using a constant tag.
2020-05-14 11:22:28 -03:00
Alex Hart
26e582d806 Integrate RingRTC v2.0.1 2020-05-14 11:22:28 -03:00
Alan Evans
ee9270845a Create GV2 group behind feature flag. 2020-05-14 11:22:28 -03:00
Alan Evans
6cf33897c0 Remove superfluous groups v2 capability checks. 2020-05-14 11:22:28 -03:00
Freddy Tuxworth
2161bbb8fa Display "No matching countries" when no filter matches found.
Fixes #9518
2020-05-14 11:22:28 -03:00
Greyson Parrelli
b75088874e Migrate conversation rendering to the paging library. 2020-05-14 11:22:28 -03:00
Alan Evans
9ac1897880 Job changes for GroupsV2 message receive and profile key updates. 2020-05-14 11:22:28 -03:00
Alan Evans
36c43ed2fa Ensure latest V2 group state from server upon conversation open. 2020-05-14 11:22:28 -03:00
Alan Evans
8084822f16 Connect GV2 title and avatar updates and prevent no-change avatar updates. 2020-05-14 11:22:28 -03:00
Alan Evans
959718618f Deprecate some ViewUtil methods. Inline others. Remove some old API code. 2020-05-14 11:22:28 -03:00
Alan Evans
75f3fe0cec Correct access control for MMS groups. 2020-05-14 11:22:28 -03:00
Alan Evans
b800477365 GV2 leave and eject operations. 2020-05-14 11:22:28 -03:00
Alex Hart
b191341c57 Add some polish to the groups V2 manager UI. 2020-05-14 11:22:28 -03:00
leet
88a40be901 Fix backup timestamp language.
Fixes #8842
Fixes #8986
2020-05-14 11:22:28 -03:00
Greyson Parrelli
3fef58057e Add additional info to support emails and debuglogs. 2020-05-14 11:22:28 -03:00
Greyson Parrelli
b156e4a79a Always use the UD cert with a UUID. 2020-05-14 11:22:28 -03:00
Alan Evans
30ac264cd3 Rename Group update message classes. 2020-05-14 11:22:28 -03:00
Alan Evans
a9b00e1cd3 Remove instances of Android logging. 2020-05-14 11:22:28 -03:00
Alex Hart
d94fc4bc13 Implement ability to react with any emoji behind a flag. 2020-05-14 11:22:28 -03:00
Greyson Parrelli
40b5339ef8 Allow auto-download for users you've shared your profile with. 2020-05-14 11:22:28 -03:00
Alan Evans
86f0456e8c Group Manager V2 operations. 2020-05-14 11:22:28 -03:00
Alan Evans
48a693793f GV2 Group Manager. 2020-05-14 11:22:28 -03:00
Alan Evans
ff28d72db6 New GV2 internal prefix and scrubber. 2020-05-13 16:18:18 -04:00
Alan Evans
456857bbbd Add custom lint rule project. 2020-05-13 16:18:18 -04:00
Alan Evans
7f17b66a6c Upgrade gradle and gradle plugin. 2020-05-13 16:18:18 -04:00
Greyson Parrelli
310ec8f296 Remove CellServiceConstraint in favor of NetworkOrCellServiceConstraint.
If a job was enqueued with a CellServiceConstraint (which is currently
only SMS jobs), then it'll never run until it gets service, even if you
flip the "enable SMS sending over wifi" toggle.

This has created bad situations in the past, where SMS jobs just get
stuck on devices that never report having cell service (like VM's or
wifi only devices).

This fixes it by *always* using NetworkOrCellServiceConstraint, and then
deciding whether a constraint is met by checking the "wifi SMS" setting
at decision-time.
2020-05-13 16:18:18 -04:00
Alan Evans
0c2afa9438 Fix FCM token via phone call registration.
Fixes #8992
2020-05-13 16:18:18 -04:00
Alex Hart
c3832cf8b1 New group notifications management ui. 2020-05-13 16:18:18 -04:00
Greyson Parrelli
a2de8a2a05 Ensure you can't set null values in DefaultValueLiveData. 2020-05-13 16:18:18 -04:00
Greyson Parrelli
3b601896d2 Fix crash in SubmitDebugLogActivity. 2020-05-13 16:18:18 -04:00
Greyson Parrelli
e1a90bcb00 Transition conversation loading from a Loader to a Repository. 2020-05-13 16:18:18 -04:00
Greyson Parrelli
2b65916344 Show calling foreground notification on all OS versions.
Fixes #9516
Fixes #9414
2020-05-13 16:18:18 -04:00
Greyson Parrelli
f149005026 Add support for remote config v1.1 2020-05-13 16:18:18 -04:00
Alex Hart
5eb663aa1b New group avatar and name selection screen. 2020-05-13 16:18:18 -04:00
Alan Evans
12b7d6c0e3 Use bottom sheet shape. 2020-05-13 16:18:18 -04:00
Alan Evans
723639d928 New group management screen. 2020-05-13 16:18:18 -04:00
Greyson Parrelli
e0502c24e1 Only search for visible parts of a contact. 2020-05-13 16:18:18 -04:00
Alex Hart
358d6333c3 Open new recipient bottom sheet when accessing contact from group context. 2020-05-13 16:18:18 -04:00
Alan Evans
0b279d1df3 Group contact chips behind feature flag. 2020-05-13 16:18:18 -04:00
Alan Evans
8e0fba7992 New group button behind new Group UI feature flag. 2020-05-13 16:18:18 -04:00
Alex Hart
d5419ec9fa Implement new call screen UI/UX. 2020-05-13 16:18:18 -04:00
Alan Evans
33e3f78be6 LiveDataUtil combineLatest. 2020-05-13 16:17:29 -04:00
Alex Hart
3c5ad519dd Decrease QuoteView reveal animation duration to 150ms. 2020-05-13 16:17:29 -04:00
Alan Evans
17c5b858b5 Recipient bottom sheet. 2020-05-13 16:17:29 -04:00
Greyson Parrelli
f6f6496c9c Bump version to 4.59.10 2020-05-13 15:40:44 -04:00
Greyson Parrelli
b1d725e23a Updated language translations. 2020-05-13 15:40:44 -04:00
Greyson Parrelli
a74622997e Bump libsignal-metadata to 0.1.2
Includes fix for how we're prioritizing UUID vs E164.

Fixes #9621
2020-05-13 15:40:42 -04:00
Greyson Parrelli
b1a200001e Bump version to 4.59.9 2020-05-09 13:19:57 -04:00
Greyson Parrelli
3b1041fa1f Updated language translations. 2020-05-09 13:19:31 -04:00
Greyson Parrelli
a83ccc18bb Fix processing of early messages.
1. Eliminated any possibility of infinite recursion.
2. Handle the fact that you can have multiple 'early contents' for a
   single message.
2020-05-09 13:16:45 -04:00
Greyson Parrelli
618b1b5ace Handle PIN creation failure better. 2020-05-09 13:16:45 -04:00
Greyson Parrelli
14858adc88 Bump version to 4.59.8 2020-05-04 18:22:45 -04:00
Greyson Parrelli
c07f35f3aa Updated language translations. 2020-05-04 18:21:50 -04:00
Alan Evans
87eab27996 Prevent the creation of 'weak' PINs.
Simple checks to prevent the same number, or sequentially
increasing/decreasing PINs. e.g. 1111, 1234, 54321, etc.
2020-05-04 18:17:36 -04:00
Greyson Parrelli
b7296a4fe3 Bump version to 4.59.7 2020-05-04 11:06:28 -04:00
Greyson Parrelli
3fb9ae1fb4 Updated language translations. 2020-05-04 11:05:55 -04:00
Greyson Parrelli
9705939489 Fix issue with editing and forwarding a received video. 2020-05-04 10:54:55 -04:00
Greyson Parrelli
eca67b1204 Broaden exception handling in custom DNS.
A set of LG devices is crashing when using the custom DNS. Safest thing
for now would be to treat all failures as network errors while we we try
to get a repro to figure out what's happening.
2020-05-04 10:54:55 -04:00
Greyson Parrelli
c59fc3581a Make LiveRecipientCache throw exceptions instead of errors.
Errors were causing crash loops if they occur in a job. This will still
allow the app to crash, but prevent loops.
2020-05-04 00:48:09 -04:00
Greyson Parrelli
e00f8c94ff Bumped version to 4.59.6 2020-04-30 17:03:28 -04:00
Greyson Parrelli
4186153f0c Updated language translations. 2020-04-30 17:03:28 -04:00
Greyson Parrelli
6c01807f4f Fix issue with PIN verification. 2020-04-30 17:03:28 -04:00
Greyson Parrelli
9d35fb397b Fix issue with re-using forwarded attachment pointers.
We were deleting upload data for incoming attachments when we shouldn't
have.

Fixes #9570
2020-04-30 16:36:06 -04:00
Jim Gustafson
c9f2f57427 Update to ringrtc v1.3.2 2020-04-30 08:12:31 -07:00
Greyson Parrelli
c862ab0c56 Bump version to 4.59.5 2020-04-28 10:41:37 -04:00
Greyson Parrelli
7aaaa57c14 Updated language translations. 2020-04-28 10:41:06 -04:00
Greyson Parrelli
11b6394a87 Fix issue with group storage IDs. 2020-04-28 10:38:58 -04:00
Greyson Parrelli
bdd48fd2df Show PIN reminder for non-reglock users. 2020-04-28 10:38:49 -04:00
Alan Evans
e99af75400 Fix crash when blocking group. 2020-04-27 16:52:17 -03:00
Greyson Parrelli
321440e13f Bump version to 4.59.4 2020-04-27 13:07:41 -04:00
Greyson Parrelli
0556d984e0 Updated language translations. 2020-04-27 13:07:19 -04:00
Greyson Parrelli
0ba1f66136 Use the same Recipient.self() instance in storage sync. 2020-04-27 13:05:22 -04:00
Greyson Parrelli
7562555687 Add additional storage sync validations. 2020-04-27 12:38:07 -04:00
Greyson Parrelli
668ccfcd12 Clean up logging. 2020-04-27 11:29:52 -04:00
Greyson Parrelli
9c0337c4ef Fix threading issue with message resends. 2020-04-27 11:11:24 -04:00
Greyson Parrelli
3fde06ab0f Bump version to 4.59.3 2020-04-24 19:48:20 -04:00
Greyson Parrelli
73959f328a Updated language translations. 2020-04-24 19:47:57 -04:00
Greyson Parrelli
cca85bfee3 Fix some PinState bugs. 2020-04-24 19:40:50 -04:00
Greyson Parrelli
575caa53d3 Fix some storage service consistency issues. 2020-04-24 19:14:08 -04:00
Greyson Parrelli
33874a8866 Fix attachment upload bug. 2020-04-24 09:24:43 -04:00
Greyson Parrelli
b8e909a134 Revert to preferring system photos over profile photos. 2020-04-24 08:45:58 -04:00
Greyson Parrelli
5193a5d309 Prevent some crash loops. 2020-04-23 22:25:56 -04:00
Greyson Parrelli
7db288b9aa Make PINs work with password managers. 2020-04-23 22:25:56 -04:00
Greyson Parrelli
9f033e64aa Fix lint error. 2020-04-23 22:25:56 -04:00
Greyson Parrelli
5a15ba97dc Bump version to 4.59.2 2020-04-23 13:33:59 -04:00
Greyson Parrelli
ce6ec72683 Updated language translations. 2020-04-23 13:33:59 -04:00
Greyson Parrelli
eedbcdd564 Fix issue with group storage sync. 2020-04-23 13:33:59 -04:00
Greyson Parrelli
0ca2848e01 Improve logging for storage service. 2020-04-23 12:03:31 -04:00
Greyson Parrelli
208275b6a9 Improve logging for PinState. 2020-04-23 11:24:23 -04:00
Greyson Parrelli
4bdcaa72cd Fix some more UX issues with blocked users. 2020-04-23 11:06:52 -04:00
Greyson Parrelli
8c6001fa5a Improve correctness and performance of camera contact search. 2020-04-23 10:25:45 -04:00
Greyson Parrelli
c4e88abce1 Update PIN change strings. 2020-04-22 19:42:17 -04:00
Greyson Parrelli
eea7174f1d Check to see if FCM is available at app launch. 2020-04-22 19:32:40 -04:00
Greyson Parrelli
3f7d0688fc Bump version to 4.59.1 2020-04-22 14:18:28 -04:00
Greyson Parrelli
6d319618c6 Updated language translations. 2020-04-22 14:18:28 -04:00
Greyson Parrelli
4250fa707b Fix crash when videos are missing a duration.
Fixes #9556
2020-04-22 14:18:28 -04:00
Greyson Parrelli
7734cd2c8f Clean up some corner cases in storage syncing. 2020-04-22 14:18:28 -04:00
Alan Evans
57467bb338 Dismiss group participant list on contact click. 2020-04-22 14:18:28 -04:00
Alex Hart
8ad61a52b9 Fix call termination when muting before call is connected. 2020-04-22 14:18:28 -04:00
Alan Evans
9742a212a2 Fix Transifex string name clash. 2020-04-22 14:18:28 -04:00
Greyson Parrelli
fd21fc1a31 Fix some UX issues with blocked users. 2020-04-22 14:18:28 -04:00
Greyson Parrelli
1b5a0ab9f3 Sync the profile photo to linked devices when appropriate. 2020-04-22 10:34:43 -04:00
Greyson Parrelli
f466fef20a Fix issue where contact photos weren't being shown at all. 2020-04-22 10:13:56 -04:00
Greyson Parrelli
9bc70adbbd Update PIN setting strings. 2020-04-21 19:23:47 -04:00
Greyson Parrelli
6f39f9849a Bump version to 4.59.0 2020-04-21 16:09:30 -04:00
Greyson Parrelli
5bc950ed28 Updated language translations. 2020-04-21 16:09:30 -04:00
Alan Evans
b80d460a8f Account for deleted conversations in profile key send job. 2020-04-21 16:09:30 -04:00
Alan Evans
3f555ce5e2 Extract method for creating safety number intents. 2020-04-21 16:09:30 -04:00
Jim Gustafson
9513b476ef Update to ringrtc v1.3.1 2020-04-21 16:09:30 -04:00
Greyson Parrelli
8f9e79ae37 Updated PIN strings. 2020-04-21 16:09:30 -04:00
Alan Evans
53b681ef67 Make reaction and remote delete jobs GV2 ready. 2020-04-21 16:09:30 -04:00
Alan Evans
9a8094cb8a Guard against malformed group ids. 2020-04-21 16:09:30 -04:00
Alex Hart
00ee6d0bbd Dialog theme rename. 2020-04-21 16:09:30 -04:00
Greyson Parrelli
83f6640bd3 Add a more generic system for handling early messages. 2020-04-21 16:09:30 -04:00
Alex Hart
2afb939ee6 Implement send support for resumable uploads behind a flag. 2020-04-21 16:09:30 -04:00
Greyson Parrelli
7c442865c5 Interpret non-present message bodies as 'null'. 2020-04-21 16:09:30 -04:00
Greyson Parrelli
b3d57edb24 Update and centralize block strings. 2020-04-21 16:09:30 -04:00
Alex Hart
6d6e017c71 Proactively share profile key after accepting a message request. 2020-04-21 16:09:30 -04:00
Greyson Parrelli
fc6b5c1d7c Add ultramarine as a conversation color option. 2020-04-21 16:09:30 -04:00
Greyson Parrelli
6ecd3b59fd Add pre-alpha receive support for remote delete. 2020-04-21 16:09:13 -04:00
Ehren Kret
456bcf3d57 Require CDN number match rather than use default CDN
This marks messages as failed if the CDN number does not match a
configured CDN number rather than falling back to the default CDN in
the event the CDN is not recognized.
2020-04-21 13:33:41 -04:00
Greyson Parrelli
f12a9b9ac7 Store the server timestamp for a message. 2020-04-21 13:33:41 -04:00
Greyson Parrelli
00b6a222bd Remove jumpiness when rendering reactions. 2020-04-21 13:33:41 -04:00
Greyson Parrelli
b8ccc4453e Update pins4all flag.
We still have to keep the legacy one though so that people in the old
bucket stay in the new one.
2020-04-21 13:33:41 -04:00
Alan Evans
dbb31420af Ensure all support article urls are the correct format and not translatable. 2020-04-21 13:33:41 -04:00
Greyson Parrelli
35f4f3f81e Add support for passing data between jobs. 2020-04-21 13:33:41 -04:00
Greyson Parrelli
acbfff89d3 Update registration to allow PIN entry. 2020-04-21 13:33:41 -04:00
Greyson Parrelli
6b37675a81 Remove long-press action in settings. 2020-04-21 13:33:41 -04:00
Greyson Parrelli
a471ffa6d8 Fix UD indicators for sent transcripts. 2020-04-21 13:33:41 -04:00
Alan Evans
7bf090fdab GroupsV2 state mapping. 2020-04-21 13:33:41 -04:00
Alan Evans
4e0279200f Refactor out MediaPreviewActivity Intent creation method. 2020-04-21 13:33:41 -04:00
Alan Evans
78055e3ccb GroupsV2 update sending and local context storage. 2020-04-21 13:33:41 -04:00
Alan Evans
f5e6fd6340 Allow RetrieveProfileJob to be used for self. 2020-04-21 13:33:33 -04:00
Alex Hart
2d60d5fb1f Check menu item visibility when calculating menu size. 2020-04-21 13:33:33 -04:00
Alan Evans
c6dd25a119 Ensure group membership for typing indicators. 2020-04-21 13:33:33 -04:00
Alan Evans
68d29d9a0f Allow pending member invite cancelation. 2020-04-21 13:33:33 -04:00
Alan Evans
1d63970a25 Hardcode all class names in old work manager migration. 2020-04-21 13:33:33 -04:00
Alan Evans
2b1ffac564 Groups V2 avatar download job. 2020-04-21 13:33:33 -04:00
Alan Evans
e2d3a43593 Use readBodyBytes for correct exceptions. 2020-04-21 13:33:33 -04:00
Greyson Parrelli
8e13403cca Separate PINs from Registration Lock.
You can now have a PIN without having registration lock.

Note: We still need to change the registration flow to allow non-reglock
users to enter their PIN.
2020-04-21 13:33:33 -04:00
Ehren Kret
3c6a7b76ca Send increased protocol version number if CDN key or attachment are used. 2020-04-21 13:33:33 -04:00
Alan Evans
428128651e Move database protos to separate files. 2020-04-21 13:33:33 -04:00
Alan Evans
326678f214 Add support for GV2 group update messages. 2020-04-21 13:33:29 -04:00
Alex Hart
1f994495f8 Clear search if user sends message. 2020-04-21 13:33:29 -04:00
Greyson Parrelli
fb1637006d Include screen size details in debuglogs. 2020-04-21 13:33:29 -04:00
Ehren Kret
37a35e8f70 Add initial support for send/receive on CDN2. 2020-04-21 13:33:29 -04:00
Alan Evans
1290d0ead9 Add pending member activity. 2020-04-21 13:33:25 -04:00
Greyson Parrelli
ef0f26b64c Remove borders from images in the gallery picker. 2020-04-03 12:20:15 -04:00
Greyson Parrelli
485d211768 Remove border from images in the attachment keyboard. 2020-04-03 12:20:15 -04:00
Greyson Parrelli
f1ea035197 Re-enable and clean up Signal PINs.
- Require PINs during registration agian.
- Change min length to 4.
- Allow the full-screen megaphone to be enabled remotely.
- Clean up and remove some code.
2020-04-03 12:20:15 -04:00
Martijn van den Hoek
6f961ade74 Fix crash when importing vcf after exporting it.
Fixes #9465
2020-04-03 12:20:15 -04:00
Alan Evans
b8e17e0116 Enable video trimming feature by default. 2020-04-03 12:20:15 -04:00
Alan Evans
040e1fe8f6 Apply dark theme to scroll to bottom button. 2020-04-03 12:20:15 -04:00
Alan Evans
e9c92bdf51 Show unblock dialog when tap blocked contact. 2020-04-03 12:20:15 -04:00
Alan Evans
48c33f3dcd GroupsV2 service changes. 2020-04-03 12:20:15 -04:00
Alex Hart
6b2bc924dd Prefer profile photo over system contact photo. 2020-04-03 12:20:15 -04:00
Ehren Kret
a65c4f90f4 Avoid potential race condition in attachment uploads. 2020-04-03 12:19:13 -04:00
Alan Evans
04bb4b351a Refactor group leave dialog out of conversation. 2020-04-03 12:19:13 -04:00
Alan Evans
e02e4d52b4 Prevent empty message processing. 2020-04-03 12:19:13 -04:00
Alex Hart
6f3c4434f6 Add animation when replying to a message. 2020-04-03 12:19:13 -04:00
Greyson Parrelli
711715ca1e Add DNS fallback system. 2020-04-03 12:19:12 -04:00
Greyson Parrelli
d6000af843 Re-use recently-acquired attachment pointers. 2020-04-03 12:19:12 -04:00
Greyson Parrelli
9b0954a898 Bump version to 4.58.5 2020-04-03 11:18:39 -04:00
Greyson Parrelli
42a2c33fd7 Updated language translations. 2020-04-03 11:18:13 -04:00
Greyson Parrelli
a4d18a18d9 Don't use vector assets for notification icon. 2020-04-03 11:14:36 -04:00
Alex Hart
bf32409d4e Split drawable into light and dark. 2020-04-03 12:14:09 -03:00
Greyson Parrelli
e38aec225f Bump version to 4.58.4 2020-04-01 14:48:47 -04:00
Greyson Parrelli
995b7a4712 Updated language translations. 2020-04-01 14:48:25 -04:00
Alex Hart
9fe3026941 Fix AdaptiveActionsToolbar sizing algorithm. 2020-04-01 11:26:19 -03:00
Greyson Parrelli
520658e1b8 Bump version to 4.58.3 2020-03-31 17:10:00 -04:00
Greyson Parrelli
f822d8eddb Updated language translations. 2020-03-31 16:59:36 -04:00
Alex Hart
2f879ce4d6 Remove MMS groups from message request logic. 2020-03-31 16:00:26 -03:00
Greyson Parrelli
24528bf101 Fix accent color in alert dialogs in dark theme. 2020-03-31 14:59:00 -04:00
Greyson Parrelli
822682caba Fix NPE in BitmapUtil.toJpeg()
Fixes #9513
2020-03-31 11:44:18 -04:00
Greyson Parrelli
5dc3cc65a8 Bump version to 4.58.2 2020-03-30 17:53:08 -04:00
Greyson Parrelli
0f80caffb5 Updated language translations. 2020-03-30 17:53:08 -04:00
Greyson Parrelli
6c428b2777 Fix issue with some notifications linking to the wrong conversation. 2020-03-30 17:53:08 -04:00
Greyson Parrelli
c9be37b84a Fix camera rotation issues.
Had to manually detect when CameraX is giving us bad data.

Fixes #9509
2020-03-30 16:04:28 -04:00
Jim Gustafson
87ea2f86c0 Update ringrtc to v1.2.0 2020-03-30 13:01:14 -07:00
Greyson Parrelli
7e80be5ca0 Separate out model info in debug logs. 2020-03-30 15:24:29 -04:00
Greyson Parrelli
989a818a67 Fix issue where reaction notifications may jump to the wrong message. 2020-03-30 12:49:08 -04:00
Greyson Parrelli
af2e17df9e Ensure old typing observers are unsubscribed. 2020-03-30 11:33:21 -04:00
Greyson Parrelli
728ec1c16d Fix issue where leave messages were pending forever. 2020-03-30 10:11:15 -04:00
Greyson Parrelli
f859c5b1b5 Prevent conscrypt crash during profile retrieval.
This was a mitigation that was previously in place that was forgotten
during the recent avatar refactor.
2020-03-29 18:53:30 -04:00
Greyson Parrelli
ab600d7df1 Bump version to 4.58.1 2020-03-27 16:51:21 -04:00
Greyson Parrelli
4644f64fd6 Updated language translations. 2020-03-27 16:51:21 -04:00
Greyson Parrelli
c274312265 Fix scrolling in the emoji variation popup. 2020-03-27 16:51:21 -04:00
Greyson Parrelli
f8e63098a2 Don't show empty date popovers. 2020-03-27 16:40:55 -04:00
Greyson Parrelli
264d353ec2 Bump quality of camera1 photos. 2020-03-27 16:30:36 -04:00
Alex Hart
2b58dcbe7f Remove explicit CameraX initialization. 2020-03-27 16:30:36 -04:00
Greyson Parrelli
dc791487c5 Jump to the relevant message when tapping a reaction notification.
Fixes #9503
2020-03-27 16:30:36 -04:00
Greyson Parrelli
5637f132d4 Fixed issue where leave message wasn't displayed locally. 2020-03-27 16:30:36 -04:00
Alan Evans
9e6cca1cd0 GV2 database. 2020-03-27 16:30:36 -04:00
Alan Evans
640c82d517 GV2 group context proto. 2020-03-27 16:30:36 -04:00
Greyson Parrelli
20d1a93b09 Don't refresh own profile if not registered. 2020-03-27 16:30:36 -04:00
Greyson Parrelli
f5d1b11bda Fix some dark theme text contrast issues. 2020-03-27 16:30:36 -04:00
Alan Evans
66c7f8bcb2 GroupId for GV2. 2020-03-27 11:28:48 -03:00
Alex Hart
d8fa46c558 Copy action should display if message body is not empty.
Fixes #9491
2020-03-27 11:18:02 -03:00
Greyson Parrelli
10bfc8a753 Migrate avatars and group avatars. 2020-03-26 22:38:33 -04:00
Greyson Parrelli
9848599807 Bump version to 4.58.0 2020-03-26 17:49:10 -04:00
Greyson Parrelli
2e38ebcfbb Updated language translations. 2020-03-26 17:46:51 -04:00
Greyson Parrelli
f875623cd0 Resize avatars to 1024x1024. 2020-03-26 17:37:52 -04:00
Greyson Parrelli
e6f9cb9929 Remove TextSecurePreferences.getAvatarId() 2020-03-26 17:37:52 -04:00
Greyson Parrelli
6aac3baa55 Remove TextSecurePreferences.getProfileName() 2020-03-26 17:37:52 -04:00
Alan Evans
a860315587 GroupId class. 2020-03-26 17:37:52 -04:00
Greyson Parrelli
a73a73e42c Fix AudioView tinting on Android 10. 2020-03-26 17:37:52 -04:00
Greyson Parrelli
a3358e5b21 Rotate profile key after blocking if shared via group. 2020-03-26 17:37:52 -04:00
Alex Hart
7e9e2fead2 Fix NPE after call failure. 2020-03-26 17:37:52 -04:00
Alan Evans
0269a3eb6f Groups V2 protobufs and local conflict resolution. 2020-03-26 17:37:51 -04:00
Alex Hart
f449a45912 Utilize normal fallback for homescreen icons. 2020-03-26 17:37:51 -04:00
Alan Evans
f69d4ccd22 Increase Lib Signal Service compatibility to Java 8. 2020-03-26 17:37:51 -04:00
Alan Evans
0e2df2adbb Image Editor: Keep text on top.
Sorts children by a new z-order.
2020-03-26 17:37:51 -04:00
Alex Hart
d46894e5db Upgrade CameraX to Beta01. 2020-03-26 17:37:51 -04:00
Greyson Parrelli
951a61117a Add storage support for the AccountRecord. 2020-03-26 17:37:51 -04:00
Greyson Parrelli
7a038ab09d Add interim storage support for GroupV2Record. 2020-03-26 17:37:51 -04:00
Alex Hart
707a2aca0a Swap profile megaphone icon and use user avatar if present. 2020-03-26 17:37:51 -04:00
Alan Evans
624837fcf1 Include zkgroup 0.4.1
All behind feature flag, excluding .so files for space.
2020-03-26 17:37:51 -04:00
Greyson Parrelli
e3ea36c76f Remove unnecessary okhttp close when canceling.
Canceling should handle closing stuff now. And if we close from a
different thread than the calling thread, okhttp will crash.
2020-03-26 17:37:51 -04:00
Alan Evans
453996c374 Restrict CI branches. 2020-03-26 17:37:51 -04:00
Greyson Parrelli
8add9ba0a6 Removed ExperienceUpgradeActivity.
Pour one out.
2020-03-26 17:37:51 -04:00
Alan Evans
da11b56eab Check for and clear quote on new intent.
Fixes #9478
2020-03-26 17:37:51 -04:00
Greyson Parrelli
19377c2132 Remote maxInstance restriction on RetrieveProfileAvatarJob. 2020-03-26 17:37:51 -04:00
Greyson Parrelli
b2bff39fe1 Don't send group info requests in response to group info requests. 2020-03-26 17:37:51 -04:00
Greyson Parrelli
5f7075d39a Update and refactor storage service syncing.
Switched to proto3, updated protos, and generally refactored things to
make it easier to add new storage record types.
2020-03-26 17:37:51 -04:00
Alex Hart
40d9d663ec Disable auto-mirror for help icon 2020-03-26 17:37:51 -04:00
Greyson Parrelli
31f9b77c32 Ignore empty names when populating contact list. 2020-03-26 17:37:51 -04:00
Greyson Parrelli
690a66a093 Show any user with a displayable name in the contact list. 2020-03-26 17:37:51 -04:00
Ehren Kret
e7e7d36774 Configure Android Studio to pickup protobuf generated sources 2020-03-26 17:37:51 -04:00
Greyson Parrelli
f95a37956c Improve emoji sticker suggestions.
There was a bug around some emoji being marked as 'obsolete' and
therefore not being found.

I also made a change so that you can use skin variations of emoji and
still find emoji tagged with the default yellow version of it.

Fixes #9471
2020-03-26 17:37:51 -04:00
Greyson Parrelli
1e2a27f902 Close dangling groups cursor. 2020-03-26 17:37:51 -04:00
Greyson Parrelli
d90e3dc210 Fix crash when syncing empty usernames. 2020-03-26 17:37:51 -04:00
Greyson Parrelli
5df4b56c0d Update okhttp to 3.12.10 2020-03-26 17:37:51 -04:00
Jim Gustafson
436da1cb32 Update ringrtc to v1.1.0 2020-03-26 17:37:51 -04:00
Greyson Parrelli
4d0dbbc6cd Add ability to listen to jobs based on a filter. 2020-03-26 17:37:51 -04:00
Alan Evans
033bf77cbb Allow future display of pending member count. 2020-03-26 17:37:51 -04:00
Greyson Parrelli
1068c3ca7e Fix UnknownSenderView in dark theme. 2020-03-26 17:37:51 -04:00
Greyson Parrelli
df4422369d Update icons and colors. 2020-03-26 17:37:51 -04:00
Greyson Parrelli
a62183c9e0 Reduce AttachmentCipherTest flakiness. 2020-03-19 14:50:06 -04:00
Greyson Parrelli
de48cf8243 Bump version to 4.57.2 2020-03-19 14:49:52 -04:00
Greyson Parrelli
acd4fc4518 Fix issue where minimum PIN length was miscalculated.
Fixes #9484
2020-03-19 14:49:10 -04:00
Greyson Parrelli
da59ed019f Bump version to 4.57.1 2020-03-07 16:43:35 -05:00
Greyson Parrelli
e73b174d1d Updated language translations. 2020-03-07 16:43:08 -05:00
Alan Evans
2753a22e3a Remove old activity from manifest. 2020-03-07 16:40:17 -05:00
Alex Hart
79fc33630b Add toast instead of crash if no email app installed. 2020-03-07 16:40:17 -05:00
Greyson Parrelli
bf5331ba6e Bump version to 4.57.0 2020-03-05 18:51:45 -05:00
Greyson Parrelli
3be47d3e54 Updated language translations. 2020-03-05 18:51:21 -05:00
Alex Hart
f9de131017 Add new contact us flow. 2020-03-05 18:42:17 -05:00
Alan Evans
f1f505d41c Try getKeyStoreEntry twice on UnrecoverableKeyException.
To try to get around potentially temporary UnrecoverableKeyExceptions.
2020-03-05 18:42:17 -05:00
Alan Evans
51603be5ec Add video trimming time indication pill. 2020-03-05 18:42:17 -05:00
Alex Hart
2152b4a2cd Add warning dialog for insecure calls. 2020-03-05 18:42:17 -05:00
Alan Evans
a70023a32b Use group manager to leave group. 2020-03-05 18:42:17 -05:00
Alan Evans
5038210d78 Add tap to pause to video trimming editor. 2020-03-05 18:42:17 -05:00
Alan Evans
28bbfd88b2 Group member dialog update. 2020-03-05 18:42:17 -05:00
Greyson Parrelli
d05a71c8fe Update Glide to 4.11.0 2020-03-03 08:52:11 -05:00
Greyson Parrelli
245b0a7e50 Add a new buildType with Flipper. 2020-03-02 16:25:05 -05:00
Alan Evans
ceb9e4aee2 Write capabilities to service. 2020-03-02 12:01:50 -04:00
Alan Evans
d2e94dad7e Remove argon2 test job. 2020-03-02 11:22:37 -04:00
Alex Hart
240b2108f3 Use the image editor for avatars. 2020-03-02 11:21:57 -04:00
Greyson Parrelli
f68d99d16d Clean up dangling transfer files.
Fixes #9033
2020-03-02 10:11:40 -05:00
Greyson Parrelli
44e845c875 Update emoji. 2020-03-02 10:11:40 -05:00
Alan Evans
d8e2368a18 Convert UUID supported into a Capability enum. 2020-03-02 10:11:40 -05:00
Alan Evans
172a43679d Add GV2 recipient capability. 2020-03-02 10:11:40 -05:00
Greyson Parrelli
82305ce2b3 Bump version to 4.56.4 2020-03-02 09:55:04 -05:00
Greyson Parrelli
eaf73edcad Updated language translations. 2020-03-02 09:54:35 -05:00
Greyson Parrelli
543a4ee177 Fix backup restore crash. 2020-03-02 09:48:18 -05:00
Greyson Parrelli
fd2a464bae Use internal contact viewer for avatar clicks. 2020-03-02 08:33:25 -05:00
Alex Hart
b06152ba58 Fix and simplify Y translation calculation for Conversation. 2020-03-02 08:57:11 -04:00
Greyson Parrelli
c24d285cd3 Bump version to 4.56.3 2020-02-28 17:35:13 -05:00
Greyson Parrelli
be39cd653e Updated language translations. 2020-02-28 17:35:13 -05:00
Greyson Parrelli
6813f47bc1 Remove feature flags that are no longer remote capable. 2020-02-28 17:35:10 -05:00
Greyson Parrelli
8e795c4177 Read the sticker length during backup import. 2020-02-28 16:58:47 -05:00
Greyson Parrelli
9c96afee09 Fix storage service crash with new users. 2020-02-28 16:58:47 -05:00
Greyson Parrelli
d507be0ab0 Don't backup the KeyValueDatabase. 2020-02-28 16:58:47 -05:00
Greyson Parrelli
75a52f801a Implement storage service protocol changes. 2020-02-28 16:58:47 -05:00
Greyson Parrelli
d3b123f3a9 Fix StorageSyncHelperTest. 2020-02-28 08:07:36 -05:00
Greyson Parrelli
da3cdd984b Bump version to 4.56.2 2020-02-26 17:57:36 -05:00
Greyson Parrelli
6184e5f828 Update the storage service. 2020-02-26 17:11:34 -05:00
Curt Brune
133bd44b85 Update ringrtc to v1.0.2 2020-02-26 17:11:34 -05:00
Greyson Parrelli
0c254c9621 Improve debuglog submission. 2020-02-26 17:11:34 -05:00
Greyson Parrelli
1faf196f82 Implement additional message request improvements. 2020-02-26 17:11:29 -05:00
Greyson Parrelli
81c7887d47 Switch language string to 'System default.' 2020-02-26 17:08:27 -05:00
Greyson Parrelli
e62e630987 Fix theming issue in CameraContactSelectionFragment. 2020-02-26 17:08:27 -05:00
Alex Hart
739e38a047 Fix reaction details bottom sheet scrolling. 2020-02-26 17:08:27 -05:00
Greyson Parrelli
8c23b17517 Fix some state issues post backup restore. 2020-02-26 17:08:27 -05:00
Greyson Parrelli
fda8f3e1ce Refer to yourself as 'you' in reactions and group membership. 2020-02-26 17:08:27 -05:00
Alex Hart
9e5f64c431 Improve message requests, add megaphone. 2020-02-26 17:08:27 -05:00
Alex Hart
dc689d325b Various PIN bug fixes. 2020-02-26 17:06:21 -05:00
Greyson Parrelli
0a883dc234 Fix issue with mimeType resolution in share flow. 2020-02-26 17:06:06 -05:00
Greyson Parrelli
3824e90997 Improve prekey refresh logic. 2020-02-26 17:06:06 -05:00
Greyson Parrelli
5158a15379 Disable PIN requirement for new registrations. 2020-02-26 17:06:06 -05:00
Curt Brune
1bae79af5b Check callManager reference is still valid in ListenableFutureTask callbacks. 2020-02-26 17:06:04 -05:00
Curt Brune
58b7612987 Drop requests to deny stale incoming calls.
This is not an illegal state, as the remote side could have hung-up
a microsecond before the local side tries to deny the call.
2020-02-26 17:06:02 -05:00
Curt Brune
9506da6dd3 Validate activePeer during Bluetooth and Speaker audio state transitions. 2020-02-26 17:05:54 -05:00
Greyson Parrelli
4ea886d05a Bump version to 4.56.1 2020-02-14 12:20:40 -05:00
Greyson Parrelli
7a52fccfd1 Updated language translations. 2020-02-14 12:20:40 -05:00
Greyson Parrelli
f79d308a9f Update profile name megaphone. 2020-02-14 12:20:40 -05:00
Curt Brune
5aa64641d2 Convert IllegalStateException to warning log in receivedBusy()
This is not a fatal condition.  Convert to warning log message in
order to gather more information.
2020-02-14 08:13:11 -08:00
Curt Brune
ae594a0400 Check activeRemote is non-null during handleScreenOffChange() 2020-02-14 08:13:11 -08:00
Curt Brune
eeece55b45 Check activeRemote is non-null during handleWiredHeadsetChange() 2020-02-14 08:13:11 -08:00
Greyson Parrelli
9fbc50d26f Fix crash when cleared ShareViewModel. 2020-02-14 09:57:26 -05:00
Greyson Parrelli
16ebf0556a Bump version to 4.56.0 2020-02-13 20:53:10 -05:00
Greyson Parrelli
bb104b5763 Updated language translations. 2020-02-13 20:53:10 -05:00
Greyson Parrelli
9bac88697b Support sharing multiple photos/videos into Signal. 2020-02-13 20:53:10 -05:00
Alan Evans
7ab240643e Remove build instructions. 2020-02-13 20:53:10 -05:00
Greyson Parrelli
70d5b798b2 Add some developer utils. 2020-02-13 20:53:10 -05:00
Greyson Parrelli
4e7a92637c Follow system theme on Android 10+. 2020-02-13 20:53:10 -05:00
Greyson Parrelli
2e19d0459b Fix album ordering issue.
Fixes #9381
2020-02-13 20:53:10 -05:00
Curt Brune
0970fd7040 Update ringrtc to v1.0.1
Add support for RingRTC Call Manager, a new component which provides
the control layer for all calling features.
2020-02-13 20:53:10 -05:00
Greyson Parrelli
81532cad95 Use a min length of 6 for new PIN reminders. 2020-02-13 20:53:10 -05:00
Greyson Parrelli
dcb5f7b211 Update copy for PIN setting. 2020-02-13 20:53:10 -05:00
Alan Evans
40fd7ca332 Video trimming behind feature flag. 2020-02-13 20:53:10 -05:00
Alan Evans
7f867a6185 Remove KBS restore after set check. 2020-02-13 20:53:10 -05:00
Alan Evans
23e55ac5f7 Clear unidentified access mode when profile key changes. 2020-02-13 20:53:10 -05:00
Jonathan Leitschuh
455974cb05 Add official Gradle Wrapper validation action.
See: https://github.com/gradle/wrapper-validation-action
2020-02-13 20:53:10 -05:00
Greyson Parrelli
66a668f55b Add some Swoon blessed packs. 2020-02-13 20:53:10 -05:00
Alan Evans
7ecb50a3fe Versioned Profiles support (disabled). 2020-02-13 20:53:10 -05:00
Alan Evans
f10d1eac61 Migrate profile key into database. 2020-02-13 20:53:10 -05:00
Alan Evans
b92c389a5b Fix media rail thumbnail for in-app recorded video. 2020-02-13 20:53:10 -05:00
Alex Hart
9dfc57c462 Fix RTL icon issue in toolbar. 2020-02-13 20:53:10 -05:00
Alex Hart
3ea1492d67 Add profile names megaphone. 2020-02-13 20:53:07 -05:00
Greyson Parrelli
c041614d1f Only store remote values for flags in a whitelist. 2020-02-11 12:03:34 -05:00
Greyson Parrelli
d9c5907ea9 Bump version to 4.55.8 2020-02-11 12:03:12 -05:00
Greyson Parrelli
0b6a52277d Fixed PIN reminders showing too often, reminder UI improvements. 2020-02-11 12:03:12 -05:00
Greyson Parrelli
944adb5d7c Bump version to 4.55.7 2020-02-10 20:01:47 -05:00
Greyson Parrelli
ac4129c1e1 Updated language translations. 2020-02-10 20:01:28 -05:00
Greyson Parrelli
0220a88ea5 Mark registration complete after PIN failure. 2020-02-10 19:56:41 -05:00
Greyson Parrelli
6d33763ec9 Bump version to 4.55.6 2020-02-08 10:58:43 -05:00
Greyson Parrelli
3cedadbb97 Fix video duration rendering issue. 2020-02-08 10:58:12 -05:00
Greyson Parrelli
5a6d339a89 Bump version to 4.55.5 2020-02-08 10:26:01 -05:00
Greyson Parrelli
905d8a4f33 Updated language translations. 2020-02-08 10:26:01 -05:00
Greyson Parrelli
917d312ea0 Reduced padding above megaphone button. 2020-02-08 10:26:01 -05:00
Greyson Parrelli
ddc01b539f Use megaphones for PIN reminders. 2020-02-07 21:14:20 -05:00
Greyson Parrelli
38e4733433 Improve network reliability when setting PINs. 2020-02-07 01:06:41 -05:00
Greyson Parrelli
cbd7160e23 Show profile creation before PIN creation. 2020-02-07 00:47:52 -05:00
Greyson Parrelli
f2b3acb0c9 Update string for creating PIN. 2020-02-07 00:15:42 -05:00
Greyson Parrelli
49c7b5c442 Bump version to 4.55.4 2020-02-06 11:19:46 -05:00
Greyson Parrelli
7b7d180207 Updated language translations. 2020-02-06 11:19:46 -05:00
Alex Hart
21cf390d0e Clip reactions mask if the view falls below the input panel. 2020-02-06 11:19:46 -05:00
Greyson Parrelli
5e59f77f83 Update PIN feature flags. 2020-02-06 11:19:46 -05:00
Greyson Parrelli
62814490b3 Only store remote values for flags in a whitelist. 2020-02-06 11:19:46 -05:00
Alan Evans
e5fedb8163 Add pull request trigger. 2020-02-06 07:52:32 -05:00
Greyson Parrelli
cfc74c1080 Bump version to 4.55.3 2020-02-05 20:50:25 -05:00
Greyson Parrelli
eaf53ad3b9 Updated language translations. 2020-02-05 20:49:59 -05:00
Greyson Parrelli
a1f0c198a7 Auto-show keyboard for PIN entry. 2020-02-05 18:49:31 -05:00
Greyson Parrelli
6b1e48e485 Don't show the full-screen PIN megaphone. 2020-02-05 18:49:31 -05:00
Greyson Parrelli
83ea919434 Remove "(You)" from the reactions details.
This reverts commit ed2b049ad4.
2020-02-05 11:36:57 -05:00
Greyson Parrelli
c94e93b916 Fix issue with reactions pill not appearing. 2020-02-05 11:32:20 -05:00
Alex Hart
49d418bb39 Fix RTL support for reaction sending. 2020-02-05 11:20:36 -05:00
Greyson Parrelli
23adda1817 Update reaction pill padding. 2020-02-05 10:40:08 -05:00
Alex Hart
7c729c2c4e Add AdaptiveActionsToolbar for better context bar controls. 2020-02-05 08:51:05 -04:00
Greyson Parrelli
ecf7a416eb Bump version to 4.55.2 2020-02-04 20:10:36 -05:00
Greyson Parrelli
2f87f2bb62 Updated language translations. 2020-02-04 20:10:00 -05:00
Greyson Parrelli
39f4102e81 Fix issue where quoted replies showed a 'save' option. 2020-02-04 19:21:01 -05:00
Greyson Parrelli
4fcd6b15ed Improved feel of reaction popover. 2020-02-04 19:21:01 -05:00
Greyson Parrelli
8f9ed4bc40 Fix the shape of reaction pills. 2020-02-04 19:21:01 -05:00
Alex Hart
73dedd79d2 Fix crash in reactions overlay OnTouch. 2020-02-04 19:21:01 -05:00
Greyson Parrelli
2754b397d5 Darken the background more when selecting a message. 2020-02-04 19:21:01 -05:00
Greyson Parrelli
7d949ee8fd Prevent crash in megaphones after backup restore. 2020-02-04 19:21:01 -05:00
Greyson Parrelli
28e2f22550 Fix layout issues with reaction badges. 2020-02-04 19:21:01 -05:00
Alex Hart
eaa1760511 Animate toolbar in reactions overlay. 2020-02-04 19:21:01 -05:00
Alex Hart
53dfd3f4c0 Fix wrong avatar displaying in reactions fragment. 2020-02-04 19:21:01 -05:00
Alex Hart
ed2b049ad4 Add You to reactions you've sent in the bottom dialog fragment. 2020-02-04 10:35:45 -04:00
Alex Hart
092fb40333 Check if target is attached to window before trying to mask it. 2020-02-04 09:47:26 -04:00
Alan Evans
36a4225858 Always return passphrase without spaces. 2020-02-04 08:10:58 -05:00
Greyson Parrelli
e551ea8bd9 Bump version to 4.55.1 2020-02-04 00:59:45 -05:00
Greyson Parrelli
5a28b1bf1c Updated language translations. 2020-02-04 00:59:15 -05:00
Greyson Parrelli
4cd1129c92 Show snooze snackbars for longer. 2020-02-04 00:55:38 -05:00
Greyson Parrelli
a5d7bc4efc Force custom emoji for reactions. 2020-02-04 00:42:41 -05:00
Greyson Parrelli
1ff5b2af2a Capitalize 'PIN' in strings. 2020-02-04 00:01:07 -05:00
Greyson Parrelli
82446ce30a Hide attachment keyboard after selecting an action. 2020-02-04 00:00:06 -05:00
Alan Evans
6465248483 Fix megaphone snooze. 2020-02-03 22:44:43 -05:00
Greyson Parrelli
48e7f82466 Fix issue with view-once toggle breaking video controls. 2020-02-03 18:26:49 -05:00
Greyson Parrelli
6fef21ebc0 Update permission copy in attachment keyboard. 2020-02-03 15:32:20 -05:00
Greyson Parrelli
837e594607 Bump version to 4.55.0 2020-02-03 15:05:05 -05:00
Greyson Parrelli
ab0cb55b80 Updated language translations. 2020-02-03 15:05:05 -05:00
Greyson Parrelli
2d24c8c525 Update conditions for PIN megaphone.
Handles additional corner cases.
- Shows megaphone when you register with a v1 pin.
- Show fullscreen when you fail to set a PIN during registration.
2020-02-03 15:04:53 -05:00
Alan Evans
40383f3733 Handle presenting KBS account locked cases. 2020-02-03 15:04:53 -05:00
Alex Hart
e14861d79d CreatePinActivity naming update and copy fixes. 2020-02-03 15:04:53 -05:00
Alan Evans
b29b3d0432 Require at least 4 digits during registration. 2020-02-03 15:04:53 -05:00
Greyson Parrelli
c21d4861c0 Clear text entry after changing PIN types. 2020-02-03 15:04:53 -05:00
Greyson Parrelli
a6786e5c2b Fix strings in KBS PIN flow. 2020-02-03 15:04:53 -05:00
Greyson Parrelli
77caa9e9d4 Fix crash in getIntentForPinCreate(), show 'Create' in prefs. 2020-02-03 15:04:53 -05:00
Greyson Parrelli
835ef02872 Add an 'All' tab to reaction details. 2020-02-03 15:04:53 -05:00
Alex Hart
279dcb1428 Apply KBS Lock fixes and pluralization 2020-02-03 15:04:53 -05:00
Alan Evans
4a8c312e0a Clear pin on confirm screen on submit. 2020-02-03 15:04:53 -05:00
Alan Evans
c2bc376f87 Hide PIN from summary when feature flag set. 2020-02-03 15:04:37 -05:00
Greyson Parrelli
73160d4d26 Update reactions UI. 2020-02-03 14:20:08 -05:00
Alan Evans
1dd2a4e9c5 Allow backup passphrase verification. 2020-02-03 14:20:08 -05:00
Alan Evans
ed0c4b8de5 Remove KBS feature flag. 2020-02-03 14:20:08 -05:00
Greyson Parrelli
4f921d761d Enable reaction sending. 2020-02-03 14:20:08 -05:00
Greyson Parrelli
37f85d6deb Delete unused megaphones from the database. 2020-02-03 14:20:08 -05:00
Alex Hart
e1b75c78ab Add Pins for All Megaphone Kill Switch. 2020-02-03 14:20:08 -05:00
Alan Evans
5e83206e6e Fix group timer message. 2020-02-03 14:20:08 -05:00
Alan Evans
1ea6838db6 Bring KBS fragment source into RegistrationLockFragment and handle account locked. 2020-02-03 14:20:08 -05:00
Alex Hart
fb82420376 Implement new PIN UX. 2020-02-01 12:42:29 -04:00
Greyson Parrelli
109d67956f Implement new attachment keyboard.
Such beauty. Such grace.
2020-02-01 12:38:53 -04:00
Greyson Parrelli
9f7b2e2cfd Track the first time a megaphone appeared. 2020-01-30 11:40:22 -05:00
Greyson Parrelli
22f9bfeceb Add support for creating Megaphones. Includes reactions megaphone. 2020-01-29 19:15:02 -05:00
Greyson Parrelli
ef4c7e96da Bump version to 4.54.3 2020-01-29 18:31:07 -05:00
Greyson Parrelli
02865f99a9 Limit impact of crash on unexpected SMS receive. 2020-01-29 18:28:59 -05:00
Greyson Parrelli
ef6019f13b Fix reddit link previews. 2020-01-29 18:26:16 -05:00
Greyson Parrelli
33d02bb7b8 Bump version to 4.54.2 2020-01-28 15:31:11 -05:00
Greyson Parrelli
d34df2c1cf Updated language translations. 2020-01-28 15:30:11 -05:00
Alex Hart
7fdf540742 Implement new reaction notifications. 2020-01-28 15:48:24 -04:00
Alex Hart
f916aabb98 Fix NPE when retrieving display name of unknown recipient. 2020-01-28 15:22:41 -04:00
Alex Hart
4ae7d56db4 Fix NPE when returning to profile from background.
Also generally improves saved-state management for Profile editor.
2020-01-28 14:57:17 -04:00
Alex Hart
e3878ffde7 Change profile preference screen to use toolbar. 2020-01-28 13:41:06 -04:00
Alex Hart
5221b6fb43 Fix expiration timer display issue on devices with modified font sizes.
Fixes #9335
2020-01-27 14:54:04 -04:00
Alex Hart
5e0fe86858 Add SM-G920F and BLK-L09 to LegacyCameraModels. 2020-01-27 14:32:48 -04:00
Alex Hart
c86ced0911 Add back arrow to profile editor. 2020-01-27 14:30:53 -04:00
Alex Hart
0aad82d3d7 Check content disposition flag in carrier config before parsing PDU.
Fixes #9081
2020-01-27 12:15:32 -04:00
Greyson Parrelli
ce86adab82 Bump version to 4.54.1 2020-01-27 10:09:48 -05:00
Greyson Parrelli
b543f727be Fix lint error. 2020-01-27 10:09:24 -05:00
Greyson Parrelli
8de7e0f198 Bump version to 4.54.0 2020-01-27 09:51:00 -05:00
Alan Evans
866dacf198 Updated language translations. 2020-01-27 09:51:00 -05:00
Alan Evans
3589fa381d Make better effort to delete leftover temporary backup files. 2020-01-27 09:51:00 -05:00
Greyson Parrelli
5d54ebfaa0 Fix crash when notification state is empty. 2020-01-27 09:51:00 -05:00
Alan Evans
fea2b6253f KBS remote feature flag. 2020-01-27 09:51:00 -05:00
Alan Evans
ba6e1ab15a Add type to KBS json. 2020-01-27 09:51:00 -05:00
Curt Brune
1d9fff3c98 Update ringrtc to 0.3.3 2020-01-27 09:51:00 -05:00
Greyson Parrelli
526adce603 Add support for sticky and hot-swappable feature flags. 2020-01-27 09:51:00 -05:00
Alan Evans
e7f568e162 Trimming profile names to fit byte budget and remove leading/trailing spaces. 2020-01-27 09:51:00 -05:00
Alan Evans
7d15c602a6 Enable KBS. 2020-01-27 09:51:00 -05:00
Greyson Parrelli
bdb30ebc48 Set a better User-Agent on requests. 2020-01-27 09:51:00 -05:00
Greyson Parrelli
a31da7616d Rename 'userAgent' to 'signalAgent'.
This wasn't actually being used in the User-Agent header. Instead, it
was used as the value for an X-Signal-Agent header. To avoid confusion,
I'm renaming this.
2020-01-27 09:51:00 -05:00
Alex Hart
f1147c10ee Disable reaction sending on update messages. 2020-01-27 09:51:00 -05:00
Alan Evans
544a5386ad Always show sticker icon in image editor.
Fixes flicker seen jumping toggling view once.
2020-01-27 09:51:00 -05:00
Greyson Parrelli
2d502213e4 Remove forced feature flag for reaction sending. 2020-01-27 09:51:00 -05:00
Greyson Parrelli
55e9f8722f Add support for remote feature flags. 2020-01-27 09:51:00 -05:00
Greyson Parrelli
b8602ee004 Fix issues with Mexican phone number formatting.
Fixes #9317
2020-01-27 09:40:27 -05:00
Alan Evans
e37c4b1f87 Replace pinstretcher with Argon2 and new PIN encryption. 2020-01-24 10:54:39 -05:00
Greyson Parrelli
f7a3bb2ae8 Add the ability to re-order sticker packs. 2020-01-24 10:54:39 -05:00
Alan Evans
7d70ea78cd Hmac-SIV encryption/decryption. 2020-01-24 10:54:39 -05:00
Alex Hart
3907ec8b51 Add support for setting an optional last name in profiles. 2020-01-24 10:54:39 -05:00
Alan Evans
f2b9bf0b8c Use SignalStore for KBS Values. 2020-01-24 10:54:38 -05:00
Greyson Parrelli
fadcc606f8 Optimize uploads during media composition.
By uploading in advance (when on unmetered connections), media messages
can send almost instantly.
2020-01-24 10:54:38 -05:00
Alex Hart
92e97e61c1 Clear cached self id on successful registration. 2020-01-24 10:54:38 -05:00
Greyson Parrelli
4b5b9fbde8 Add an encrypted key-value store.
SignalStore is backed by SQLCipher and is intended to be used instead of
TextSecurePreferences moving forward.
2020-01-24 10:54:38 -05:00
Alan Evans
711d22a0ed Do not specify random provider. 2020-01-24 10:54:38 -05:00
Greyson Parrelli
06757153b3 Add support for adding jobs with existing dependencies. 2020-01-24 10:54:38 -05:00
Greyson Parrelli
38597aea00 Add support for canceling Jobs. 2020-01-24 10:54:38 -05:00
Alex Hart
b10ce080a9 Consolidate Notification Ids to a centralized constants class. 2020-01-16 05:41:27 -05:00
Alan Evans
72e10ac597 Bump version to 4.53.7 2020-01-15 16:20:47 -05:00
Alan Evans
5b591364ba Updated language translations. 2020-01-15 16:18:45 -05:00
Alan Evans
ace1855797 Test various Argon2 parameters. 2020-01-15 16:11:41 -05:00
Alan Evans
ddedf73939 Bump version to 4.53.6 2020-01-13 14:15:48 -05:00
Alan Evans
538014935e Updated language translations. 2020-01-13 12:22:55 -05:00
Greyson Parrelli
5e9bbf1200 Reduce avatar outlines to 1px. 2020-01-13 12:13:22 -05:00
qrest
29d6d3c041 Add Xiaomi Mi A2 to echo cancellation blacklist. 2020-01-13 08:09:00 -05:00
Alan Evans
53ab303fd9 Bump version to 4.53.5 2020-01-10 16:54:40 -05:00
Alan Evans
24103ee856 Updated language translations. 2020-01-10 16:48:54 -05:00
Greyson Parrelli
20e368ab5e Update outgoing view-once message toast. 2020-01-10 16:28:30 -05:00
Greyson Parrelli
05763191ce Show the correct quoted media type for unviewed view-once messages. 2020-01-10 15:34:38 -05:00
Alan Evans
f6685fb9c9 Fix content NPE. 2020-01-10 07:48:06 -05:00
Greyson Parrelli
dbdf9602c2 Bump version to 4.53.4 2020-01-09 18:45:38 -05:00
Greyson Parrelli
6173f7049c Updated language translations. 2020-01-09 18:44:48 -05:00
Greyson Parrelli
4adacf4b98 Fix issue where you could send text with a view-once message. 2020-01-09 18:38:34 -05:00
Greyson Parrelli
8cb6ed26a1 Update view-once design. 2020-01-09 18:32:14 -05:00
Greyson Parrelli
fd7aa9ccfa Fix view-once sync and quote descriptions. 2020-01-09 18:32:14 -05:00
Alex Hart
e2a48d1714 Fix notification reply image. 2020-01-09 12:36:46 -04:00
Greyson Parrelli
a5c4c1e0a6 Converted outlines from 1px to 1dp. 2020-01-08 15:27:55 -05:00
Alan Evans
b29d03e872 Bump version to 4.53.3 2020-01-08 11:51:27 -05:00
Alan Evans
dff11092ec Updated language translations. 2020-01-08 11:50:39 -05:00
Greyson Parrelli
5e9c4e8fa3 Remove tap-to-dismiss from view-once. 2020-01-07 21:44:41 -05:00
Greyson Parrelli
c346f32762 Made view-once a non-sticky setting. 2020-01-07 16:18:07 -05:00
Greyson Parrelli
d2d450aff2 Make view-once viewed bubble match the conversation background. 2020-01-07 16:14:11 -05:00
Greyson Parrelli
09af858be8 Show upload progress for view-once messages. 2020-01-07 15:50:12 -05:00
Alan Evans
9c8a99c79c Bump version to 4.53.2 2020-01-07 15:02:43 -05:00
Greyson Parrelli
c6b9855198 Always show view-once video remaining time. 2020-01-07 15:02:43 -05:00
Alan Evans
c142928fad Updated language translations. 2020-01-07 13:45:45 -05:00
Greyson Parrelli
fc0cfd5188 Disable multiselect actions for inapplicable message types. 2020-01-07 13:09:25 -05:00
Greyson Parrelli
d9c78e5c3e Fix toolbar overlap with cutouts in recipient preferences.
Fixes #9323
2020-01-07 12:17:41 -05:00
Greyson Parrelli
b449fceca0 Dismiss conversation search after swipe-to-reply.
Fixes #9325
2020-01-07 11:13:16 -05:00
Greyson Parrelli
f0d15c0bce Fix crash when clicking group avatars. 2020-01-07 10:51:40 -05:00
Greyson Parrelli
8f031f61ea Fix group update string when re-added to group. 2020-01-06 18:36:56 -05:00
Alan Evans
502e8559f0 Bump version to 4.53.1 2020-01-06 16:53:31 -05:00
Alan Evans
8cf6f7e936 Relocate jni libs. 2020-01-06 16:52:41 -05:00
Alan Evans
0ef01cc620 Bump version to 4.53.0 2020-01-06 11:08:30 -05:00
Alan Evans
930828ef86 Updated language translations. 2020-01-06 11:08:30 -05:00
Alan Evans
9ebe920195 Move all files to natural position. 2020-01-06 11:08:30 -05:00
Greyson Parrelli
0df36047e7 Ensure transport type gets reset in onNewIntent()
Fixes #9319
2020-01-06 11:08:27 -05:00
Greyson Parrelli
94604921f9 Fix issue with swipe-to-reply triggering incorrectly.
Fixes #9227
2020-01-06 11:08:27 -05:00
Curt Brune
284fe294ac Skip monochrome cameras when switching cameras on video calls. 2020-01-06 11:08:27 -05:00
Greyson Parrelli
ffa01d491a Do not list yourself in group membership updates. 2020-01-06 11:08:27 -05:00
Kevin T. Berstene
1d9513e743 Respect local camera aspect ratio in calls.
Fixes #8615
2020-01-06 11:08:27 -05:00
Greyson Parrelli
277c9e22f1 Show long-press-magnify in sticker preview screen. 2020-01-06 11:08:27 -05:00
Greyson Parrelli
4e7b4da941 Implement resumable downloads. 2020-01-06 11:08:27 -05:00
Greyson Parrelli
7e72c9c33b Add view-once tooltip. 2020-01-06 11:08:27 -05:00
Greyson Parrelli
e0e2c3a3f5 Fix some UI bugs in view-once sending. 2020-01-06 11:08:27 -05:00
Greyson Parrelli
3b5e444e76 Enable view-once send support. 2020-01-06 11:08:27 -05:00
Alan Evans
02006e3ff5 Update copyright year. 2020-01-06 11:08:27 -05:00
Greyson Parrelli
8083596f19 Use FitCenter sizing for stickers. 2020-01-06 11:08:27 -05:00
Greyson Parrelli
6551689a0c Increase the size of stickers in the conversation. 2020-01-06 11:08:27 -05:00
Greyson Parrelli
3fbf21a34e Don't crash on packs missing metadata. 2020-01-06 11:08:27 -05:00
Alan Evans
b598431237 Separate message decryption from message processing. 2020-01-06 11:08:27 -05:00
Greyson Parrelli
3b5d9a2cae Consider groups 'unknown' if they have no title, avatar, or members. 2020-01-06 11:08:27 -05:00
Alex Hart
3bd8aa8a86 Apply MessageStyle and fix chronology issues. 2020-01-06 11:08:27 -05:00
Greyson Parrelli
fe5fca8eaf Sync thread order and archive status with linked devices. 2020-01-06 11:08:27 -05:00
Greyson Parrelli
848101a783 Refactor AvatarImageView#setAvatarClickHandler.
This triggered a call to Recipient#isGroup when rendering a view, which
itself could trigger a DB read. This delays the call to #isGroup to
lower the possibility of doing DB reads on the main thread.
2019-12-19 18:06:29 -05:00
Alex Hart
d7c350f987 Fix in-call proximity lock for wireless, speaker, and bluetooth. 2019-12-19 18:06:29 -05:00
Curt Brune
4c526f0b3c Update ringrtc to 0.3.0 2019-12-19 18:06:29 -05:00
Greyson Parrelli
876ffb5b13 Bump version to 4.52.4 2019-12-19 18:00:56 -05:00
Greyson Parrelli
0b14cf3d6a Show sticker install tooltips less often. 2019-12-19 17:59:42 -05:00
Greyson Parrelli
c2044b36b1 Bump version to 4.52.3 2019-12-18 20:58:07 -05:00
Greyson Parrelli
f970b4acfa Revert "Remove the Pixel 4 from the CameraX blacklist."
This reverts commit 1f5a597d50.
2019-12-18 20:55:03 -05:00
Greyson Parrelli
e69c0af613 Bump version to 4.52.2 2019-12-18 19:56:16 -05:00
Greyson Parrelli
42e2dd8b30 Updated language translations. 2019-12-18 18:04:42 -05:00
Greyson Parrelli
4fd6e7b033 Fix issue with stickers flickering on send. 2019-12-18 16:45:07 -05:00
Greyson Parrelli
3580816eac Bump version to 4.52.1 2019-12-18 00:50:02 -05:00
Greyson Parrelli
f1c2e5f194 Updated language translations. 2019-12-18 00:49:36 -05:00
Greyson Parrelli
b6d59f1d46 Fix sticker manager text wrapping issues. 2019-12-17 22:26:09 -05:00
Greyson Parrelli
a3521681e7 Bump version to 4.52.0 2019-12-17 15:38:12 -05:00
Alan Evans
ca10e1136c Updated language translations. 2019-12-17 15:37:11 -05:00
Greyson Parrelli
282fb2af0e Fix tinting issues on API 21. 2019-12-17 14:36:54 -05:00
Greyson Parrelli
1f5a597d50 Remove the Pixel 4 from the CameraX blacklist. 2019-12-17 14:36:54 -05:00
Greyson Parrelli
a32666817c Remove old image editor stickers. 2019-12-17 14:36:54 -05:00
Greyson Parrelli
b9bd3f2b4c Launch stickers. 2019-12-17 14:36:54 -05:00
Alex Hart
4173efbe5a Fix NPE on call initalization 2019-12-16 11:01:32 -04:00
yate
8121c8bd41 Remove blank MMS config overrides.
Some SIM cards include blank values for `uaProfUrl` and `userAgent`.

Passing in these blank values along with the overrides causes a 412 precondition error when downloading MMS from ATT&T.

If these values happen to be blank, then they should be removed completely from the overrides, allowing the request to use the default `uaProfUrl` and `userAgent` for the system.

Fixes #9173
2019-12-14 11:29:46 -05:00
Greyson Parrelli
6ca8218d55 Bump version to 4.51.6 2019-12-06 11:58:12 -05:00
Greyson Parrelli
653afbdd46 Updated language translations. 2019-12-06 11:57:33 -05:00
Alex Hart
4453d1752f Fix reactions scrubber positioning on vertically split multiscreen. 2019-12-06 11:43:51 -05:00
Alan Evans
5782c8a58b Make media overview view pager scrollable for long translations. 2019-12-06 11:43:51 -05:00
Greyson Parrelli
3e041befc8 Bump version to 4.51.5 2019-12-06 01:14:24 -05:00
Greyson Parrelli
6d3847c26f Updated language translations. 2019-12-06 01:10:47 -05:00
Alex Hart
4bdfc37bc1 Fix swipe to reply clobbering long press events. 2019-12-06 01:00:39 -05:00
Alan Evans
28afe0d829 Fix first media overview item selected text. 2019-12-06 01:00:39 -05:00
Greyson Parrelli
04dddd3378 Bump version to 4.51.4 2019-12-05 19:15:10 -05:00
Greyson Parrelli
23a14583fe Updated language translations. 2019-12-05 19:14:48 -05:00
Greyson Parrelli
19c83de510 Fix possible performance issues with reactions query. 2019-12-05 19:10:37 -05:00
Greyson Parrelli
e94d4b64cf Bump version to 4.51.3 2019-12-05 12:21:12 -05:00
Greyson Parrelli
7380c99f3a Updated language translations. 2019-12-05 12:20:28 -05:00
Greyson Parrelli
2961a372c3 Avoid unneccessary recipient refreshes. 2019-12-05 12:20:28 -05:00
Greyson Parrelli
5e2a4fb058 Put safeguards around Recipient creation in the IdentityStore. 2019-12-05 12:20:28 -05:00
Greyson Parrelli
a16242b9f8 Fix issues with RecipientDatabase#update(). 2019-12-05 12:20:28 -05:00
Alan Evans
acfba9ac96 Show total file size of selected items when appropriate. 2019-12-05 12:20:28 -05:00
Alan Evans
006343460e Fix long press on image thumbnail in detail view.
Allow long press to select inside select mode.
2019-12-05 12:20:28 -05:00
Alex Hart
1cc8634cc7 Display reactions in ImageView instead of TextView on message bubbles. 2019-12-05 12:20:27 -05:00
Greyson Parrelli
9f8a110428 Bump version to 4.51.2 2019-12-05 02:59:42 -05:00
Greyson Parrelli
07b4279d0b Updated language translations. 2019-12-05 02:59:42 -05:00
Greyson Parrelli
6a33b231e3 Add a FrameRateTracker to log frame drops. 2019-12-05 02:59:42 -05:00
Greyson Parrelli
b38d02061d Improve logging in RetrieveProfileJob. 2019-12-05 02:59:42 -05:00
Greyson Parrelli
f832a36a5e Prevent possible UUID-only recipient creations. 2019-12-05 02:59:42 -05:00
Alan Evans
911ca7c29d Improve storage management detail view descriptions. 2019-12-05 02:59:42 -05:00
Greyson Parrelli
544b75a2a7 Bump version to 4.51.2 2019-12-04 15:30:30 -05:00
Greyson Parrelli
56e8d4fb06 Updated language translations. 2019-12-04 15:28:45 -05:00
Greyson Parrelli
36a2278aef Add sanity checks for phone number during link process. 2019-12-04 15:28:45 -05:00
Alex Hart
0c785b85b8 Fix video icon issue. 2019-12-04 15:28:45 -05:00
Alan Evans
a0ecba147e Use decimal digit groups in file size pretty printing. 2019-12-04 15:28:45 -05:00
Alan Evans
977591ac82 Remove assertion error in recipient preferences. 2019-12-04 15:28:28 -05:00
Greyson Parrelli
fe1838d3fe Fix issue where unlocking would dismiss MainActivity. 2019-12-04 15:25:26 -05:00
Greyson Parrelli
ede06cf97d Remove unnecessary directory refreshes. 2019-12-04 15:25:26 -05:00
Greyson Parrelli
93deee6824 Attempt to fix crash in ClassicOpenHelper.
These users must have > 1.5-year-old installs that haven't been updated,
but it's still a top crash for whatever reason, so gotta try to fix it.
2019-12-04 15:25:26 -05:00
Greyson Parrelli
db19077834 Fix crash when receiving a PreKey message in a new session.
We don't allow creating recipients with only a UUID at the moment
(for good reason), but the way the decrypt method was written, it
was possible to do so. Until we have CDS, we should prefer the phone
number in scenarios like these.
2019-12-04 15:25:26 -05:00
Alex Hart
6f91f62db2 Fix InviteActivity sendSmsMessage type error. 2019-12-04 15:25:26 -05:00
Greyson Parrelli
1fc63b7597 Fix crash in conversation search. 2019-12-04 15:25:26 -05:00
Alex Hart
a079e479ec Skip call dialog if signal call is already active. 2019-12-04 15:25:26 -05:00
Alex Hart
e90705b459 Add correct archive icon to light theme. 2019-12-04 15:25:26 -05:00
Alex Hart
244db437cb Fix reaction display issues. 2019-12-04 15:25:25 -05:00
Alan Evans
6558eae032 Fix audio color on light theme. 2019-12-04 09:10:48 -05:00
Greyson Parrelli
88b54a262b Bump version to 4.51.0 2019-12-04 00:17:03 -05:00
Alan Evans
4fa8b8a4bd Updated language translations. 2019-12-04 00:08:01 -05:00
Greyson Parrelli
cc0ced9a81 Add internal pre-alpha support for storage service. 2019-12-04 00:08:01 -05:00
Alan Evans
52447f5e97 Add storage management features. 2019-12-04 00:07:49 -05:00
Alex Hart
bceb69b284 Add internal pre-alpha support for receiving reactions. 2019-12-04 00:07:49 -05:00
Alex Hart
a8d826020d Implement new video call experience. 2019-12-04 00:07:49 -05:00
Alan Evans
2ada7f87f2 Update lib phone number. 2019-12-04 00:07:49 -05:00
Alan Evans
7f8ca58762 Add internal pre-alpha support for Registration Lock v2. 2019-12-04 00:07:49 -05:00
Greyson Parrelli
058c25808b Clean up website auto-update APKs.
I think previously we thought that because we always used the same
filename, that we were just overwring the same file repeatedly. However,
DownloadManager will actually append numbers to a filename instead of
overwriting, so we were generating a ton of files.

Now we just clear out any previous files before downloading a new one.

Related to #9033
2019-12-04 00:07:49 -05:00
Greyson Parrelli
c1e6b6b086 Add better Loader performance logs. 2019-12-04 00:07:49 -05:00
Greyson Parrelli
b0a6bb79f6 Fix issue with setting Note to Self color.
Fixes #9235
2019-12-04 00:07:49 -05:00
Greyson Parrelli
de52bf50a2 Improve image and sticker notifications. 2019-12-04 00:07:49 -05:00
Greyson Parrelli
207dd23c86 Fix performance issue with large number of notifications.
Constructing the notification would call KeyCachingService#isLocked()
many times in a loop. This call is slow, because when the device isn't
locked, it would construct the master secret each time, which can take
50+ ms. Do that twice in a loop a hundred times, and it adds up.

This simplified #isLocked to avoid the unnecessary master secret
generation.
2019-12-04 00:07:49 -05:00
Alex Hart
7e0de29dd7 Add notification policy permission and runtime check.
Fixes #9217
2019-12-04 00:07:49 -05:00
Greyson Parrelli
eaa8f1ee8f Ignore expiration updates from groups you've left. 2019-12-04 00:07:49 -05:00
Alex Hart
fb494c1151 Implement new invite screen. 2019-12-04 00:07:49 -05:00
Greyson Parrelli
49ecd9ef5d Added additional logging in RetrieveProfileJob. 2019-12-04 00:07:49 -05:00
Greyson Parrelli
8772214fd4 Increase number of log files to 7. 2019-12-04 00:07:49 -05:00
Greyson Parrelli
5b74d0cbeb Improve activity lifecycle logging. 2019-12-04 00:07:49 -05:00
Greyson Parrelli
1e7c93007d Convert the conversation list into a real fragment.
It was a fragment before, but it's functionality was inappropriately
split between the various layers.

This also sets us up better to do tablet stuff in the future, if we
choose to do that.
2019-12-04 00:07:49 -05:00
Greyson Parrelli
608815a69b Add internal pre-alpha support for usernames. 2019-12-04 00:07:42 -05:00
Greyson Parrelli
fb49efa34d Add internal pre-alpha libsignal support for reactions. 2019-12-04 00:07:13 -05:00
Android Team
b20e8616ec Move libsignal-service-java into this repo.
libsignal-service-java repo commit: 1a01c22636
2019-12-04 00:07:13 -05:00
Alan Evans
acf78b6b63 Make new top level gradle file, make app dir and move build.gradle. 2019-12-04 00:07:13 -05:00
Alex Hart
d68fe928b8 Fix nav bar contrast on sticker preview. 2019-12-04 00:07:13 -05:00
Alex Hart
db4d561d9e Fix nav bar color on shared contacts edit screen. 2019-12-04 00:07:07 -05:00
Alex Hart
6933ca50a7 Implement new Message Request UI. 2019-12-04 00:07:07 -05:00
Greyson Parrelli
88c0e6f8ab Fail a job when you can't instantiate it.
This will still crash, but prevent apps from getting into crash loops
when we have bad data in a job.
2019-11-25 11:32:16 -05:00
Greyson Parrelli
6cd4728e3c Update job serialized data after retry. 2019-11-25 11:32:16 -05:00
Greyson Parrelli
97cc82837c Don't backup the JobsDatabase. 2019-11-25 11:32:16 -05:00
Greyson Parrelli
5f0b0e8495 Bump version to 4.50.6 2019-11-25 11:32:07 -05:00
Greyson Parrelli
c837d590ab Removed RefreshUnidentifiedDeliveryAvailabilityJob.
It's been long enough -- it's no longer necessary to check.

Also, the service is going to start returning certs no matter what, so
at this point it's just an unnecessary network call.
2019-11-25 11:32:06 -05:00
Greyson Parrelli
6108a32631 Prevent reading UUIDs from external contacts. 2019-11-25 11:29:58 -05:00
Greyson Parrelli
6d78e1760d Fix possible crash in very old database migration.
The NumberMigrator constructor is crashing. One possibility is that this
migration is running before the user registered, in which case they
wouldn't have a number. Wrapped the parts that don't need to run in this
situation in an `if` block.
2019-11-25 11:29:58 -05:00
Greyson Parrelli
c7b7242eff Fix issues with blocking and MMS groups.
Fixes #9218.

Note that this removes MMS group blocking for now, just because it never
really worked, and I don't want to hotfix in a feature.
2019-11-25 11:29:19 -05:00
Greyson Parrelli
77c687efcf Bump version to 4.50.5 2019-11-21 13:28:23 -05:00
Greyson Parrelli
274af2f010 Ensure group message is being sent to a group. 2019-11-21 13:28:00 -05:00
Greyson Parrelli
6cd5100530 Ensure Recipient.self() is available. 2019-11-21 13:24:54 -05:00
Alan Evans
115a408b0b Bump version to 4.50.4 2019-11-18 09:36:14 -05:00
Alan Evans
d983016137 Updated language translations. 2019-11-18 09:33:53 -05:00
Greyson Parrelli
a8309b6b2b Fix attachment sizes during backup exports. 2019-11-18 09:19:11 -05:00
Alan Evans
e241589c92 Bump version to 4.50.3 2019-11-15 15:43:47 -05:00
Alan Evans
dcb6240a6a Updated language translations. 2019-11-15 15:39:39 -05:00
Alex Hart
599bb5ab0f Update insights copy and queries. 2019-11-15 16:33:54 -04:00
Alan Evans
739fe584c6 Bump version to 4.50.2 2019-11-14 14:49:48 -05:00
Alan Evans
920d1c6207 Updated language translations. 2019-11-14 14:49:48 -05:00
Greyson Parrelli
c1d3d26a15 Removed unnecessary subtext in Insights. 2019-11-14 14:49:48 -05:00
theBoatman
e3b66dc7e8 Fixing RealtimeSleepTimer to work in concurrent threads. 2019-11-14 13:56:12 -05:00
Alan Evans
dfa08d1356 In dark mode, use a dark theme base for RegistrationLockDialog and RationaleDialog.
Fixes #8995
Closes #9077
2019-11-14 13:51:01 -05:00
Curt Brune
6da734c2f9 Update ringrtc to 0.2.0 2019-11-13 14:05:22 -08:00
Alan Evans
a9f3141a77 Create android.yml running qa task. 2019-11-13 15:49:22 -05:00
Alan Evans
ee267d4702 Bump version to 4.50.1 2019-11-13 14:40:04 -05:00
Alan Evans
c39174ed8a Updated language translations. 2019-11-13 14:40:04 -05:00
Greyson Parrelli
9c872b6da6 Fix issue where SMS groups showing up as 'Unnamed Group'. 2019-11-13 11:37:49 -05:00
Greyson Parrelli
2924a09936 Don't run UuidMigration if not registered. 2019-11-13 11:37:49 -05:00
Greyson Parrelli
b9da012cc4 Fix media send issues on Android 4.4.
Before lollipop, Android would ignore activity results for activities
launched with singleTask. So I switched to singleTop, since that should
still solve the problem of double-activity-opens without running into
this issue.

Fixes #9149
2019-11-13 11:37:49 -05:00
Alan Evans
8626d41787 I18N for "Unlock Signal". 2019-11-13 11:37:49 -05:00
Alex Hart
c58705722a Fix Insights Adapter item text clashing. 2019-11-13 11:37:49 -05:00
Greyson Parrelli
c702ff676a Support additional sync behavior for linked devices. 2019-11-13 11:37:49 -05:00
Alan Evans
995569dd50 Bump version to 4.50.0 2019-11-12 10:55:41 -05:00
Greyson Parrelli
a0dfd42527 Fix possible context crash. 2019-11-12 10:55:41 -05:00
Alex Hart
a7dd78cce6 Implement in-app insights. 2019-11-12 10:55:41 -05:00
Greyson Parrelli
e2e9cd40b3 Blacklist additional phone models from the new camera. 2019-11-11 18:13:34 -05:00
Alan Evans
e4fc6f41b8 Schedule first backup after restore for 24hrs time. 2019-11-11 13:00:01 -05:00
Alan Evans
778b2a0d27 Remove old strings file. 2019-11-10 09:23:44 -05:00
Alan Evans
64cd15ca0b Make AlbumThumbnailView_plus non-translatable. 2019-11-10 09:23:43 -05:00
Alan Evans
1e46c3c0ba Make app_name non-translatable. 2019-11-10 09:23:43 -05:00
Alan Evans
91772b4e11 Exclude non-translatable strings.
Lint exclude ExtraTranslation.
2019-11-10 09:23:42 -05:00
Alan Evans
af5c7cb7ca Added dotted lines to time icons. 2019-11-09 07:45:53 -05:00
Alan Evans
e760474fa9 Clear unauthorized flag on connect. 2019-11-09 07:01:08 -05:00
Greyson Parrelli
28bb88e347 Lower max number of JobScheduler IDs.
Some devices can only handle 25 job IDs, so I lowered it to 20.
2019-11-09 07:01:08 -05:00
Curt Brune
17a1fe97ca Send hangup message when terminating on call errors.
When errors occur during a call, attempt to send the remote peer a
hangup message before terminating the call.  This allows the remote
peer to shutdown their side of the call in a timely manner.
2019-11-09 07:01:08 -05:00
Alan Evans
7348237862 Lint.
- baseline update.
- eradicate ButtonOrder.
- eradicate VectorRaster.
- eradicate HardcodedText.
2019-11-09 07:01:08 -05:00
Alex Hart
4e66db5dc1 Fix timer disabled icon. 2019-11-09 07:01:08 -05:00
Alex Hart
ffa6c9acd1 Utilize icon_tint color filter for UpdateItem icons. 2019-11-09 07:01:08 -05:00
Greyson Parrelli
b3e66a9259 Prevent creation of UUID-only recipients. 2019-11-09 07:01:08 -05:00
Alan Evans
5c0cf8c1f0 English staging app name. 2019-11-09 07:01:08 -05:00
Alex Hart
89c716fca4 Fix layout gravity on recv long message footer. 2019-11-09 07:01:08 -05:00
Alan Evans
aae9830dfa Use lib-signal-servivce 2.15.1 2019-11-09 07:01:08 -05:00
Alan Evans
48c72697c1 Add protobuf lite exception for proguard. 2019-11-09 07:01:08 -05:00
Greyson Parrelli
aac7e9ea53 Fix issue with ShareActivity contact display. 2019-11-09 07:01:08 -05:00
Alan Evans
a1b10b3222 Update to protobuf 3.10 lite.
Update fingerprint logic.
Update for additional validation around SignalServiceAddresses.

Co-authored-by: Greyson Parrelli <greyson@signal.org>
2019-11-09 07:01:08 -05:00
Curt Brune
2ab8db33e3 Update ringrtc to 0.1.9 2019-11-09 07:01:08 -05:00
Curt Brune
2b1386232f Implement logging interface for ringrtc-0.1.8
Implement the org.signal.ringrtc.Log.Logger interface, using
org.thoughtcrime.securesms.logging.Log as the underlying logger.

This allows ringrtc to log in the same way as the rest of the
application.
2019-11-09 07:01:07 -05:00
Alex Hart
7bb1caa22e Remove unused pictures that were captured outside of the in-app camera. 2019-11-09 07:01:07 -05:00
Alex Hart
72c14b8651 Apply new Keyboard and Dial Pad icons. 2019-11-09 07:01:07 -05:00
Alex Hart
f85c3bb1e6 Add feature flag to new Profile display. 2019-11-09 07:01:07 -05:00
Alan Evans
d8714fe3b4 Delegate to library Base64. 2019-11-09 07:01:07 -05:00
Alex Hart
c54c1907b6 Fix nav bar colors on reg and call screen. 2019-11-09 07:01:07 -05:00
Greyson Parrelli
55257155dd Handle ProtocolInvalidMessageExceptions with no sender. 2019-11-09 07:01:07 -05:00
alex-signal
55a8bd86de Consolidate profile display labels. 2019-11-09 07:01:07 -05:00
Greyson Parrelli
c60909272b UUID migration. 2019-11-09 07:01:07 -05:00
Greyson Parrelli
3dcc2d8171 Moved DirectoryHelper. 2019-11-09 07:01:07 -05:00
Greyson Parrelli
0ccbb22e4c Unsubscribe from old recipient observers in ConversationActivity. 2019-11-09 07:01:07 -05:00
Greyson Parrelli
0ffa10eaea Bump version to 4.49.18 2019-11-08 20:27:14 -05:00
Alan Evans
9824073023 Keep line numbers within R8. 2019-11-08 16:17:32 -05:00
Alan Evans
d2adc11a2d New languages.
bn,bs,ms,mr,ta,ur
2019-11-08 16:17:32 -05:00
Alan Evans
4d0b870c88 Updated language translations. 2019-11-08 16:17:32 -05:00
Alan Evans
840997cb7d Translate tasks. 2019-11-08 11:41:38 -05:00
Alex Hart
e4406621ed Fix lint issues. 2019-11-08 11:41:38 -05:00
Greyson Parrelli
7f96ee0b62 Clear DATA_HASH column. 2019-11-08 11:30:48 -05:00
Alan Evans
17f850b31a Ensure that we can still navigate when we get a response from server. 2019-11-08 11:19:57 -05:00
Alan Evans
5d87ad0301 Ignore period in phone number entry.
Fixes #9168
2019-11-08 11:19:32 -05:00
Greyson Parrelli
a33eeed6d3 Bump version to 4.49.17 2019-11-07 16:18:27 -05:00
Alex Hart
554ce29337 Adjust Typing Indicator margin in groups. 2019-11-07 16:03:13 -05:00
Alex Hart
6054d0b36f Nullify Data Hash when Data is Nullified 2019-11-07 16:02:56 -05:00
Greyson Parrelli
8ba15cf3b4 Bump version to 4.49.16 2019-11-06 16:42:16 -05:00
Greyson Parrelli
b15e5b4867 Fix potential invalid context crash. 2019-11-06 16:38:28 -05:00
Greyson Parrelli
544511905a Fix issue where deduped media might not be kept in sync. 2019-11-06 16:37:25 -05:00
Greyson Parrelli
02e3f511bd Bump version to 4.49.15 2019-11-04 11:30:08 -05:00
Alex Hart
0539b071e7 Fix message info icon inflation error on API 19 devices.
Fixes #9148
2019-11-04 11:29:31 -05:00
Greyson Parrelli
36e400650c Fix backup restore issue.
Fixes #9133
2019-11-04 11:21:11 -05:00
Greyson Parrelli
d8930daf4b Bump version to 4.49.14 2019-11-01 17:23:52 -04:00
Greyson Parrelli
17b5816d5b Skip corrupt attachments during backup restore.
Instead of aborting the entire backup restore.

Related to #8355
2019-11-01 17:11:10 -04:00
Curt Brune
e574c81ea2 Update ringrtc to 0.1.7.2 2019-11-01 12:26:00 -07:00
Greyson Parrelli
6799a2f841 Bump version to 4.49.13 2019-10-29 16:10:09 -04:00
Curt Brune
61fb20f412 Update ringrtc to v0.1.7 2019-10-29 12:46:01 -07:00
Alan Evans
47f648e7bc Correct text on registration lock fragment. 2019-10-29 13:47:14 -04:00
Alan Evans
064c0ddb82 Manually restrict to 30 digits to allow pasting containing any number of spaces. 2019-10-29 09:59:53 -04:00
Greyson Parrelli
b42c42007d Bump version to 4.49.12 2019-10-28 19:48:07 -04:00
Greyson Parrelli
807cdfce2e Increase backup passphrase input length to 35.
The way pasting works, it could prevent you from pasting in text if you
included the spaces in between number chunks.
2019-10-28 19:47:05 -04:00
Greyson Parrelli
43dc3aeebd Fix 'direct share' icon rendering issue.
Fixes #9138
2019-10-28 16:51:06 -04:00
Greyson Parrelli
0369c5ee16 Make avatars larger in conversations. 2019-10-28 16:46:21 -04:00
Greyson Parrelli
3df2390fe4 Bump version to 4.49.11 2019-10-28 12:28:58 -04:00
Greyson Parrelli
9ec4a7af0f Update max video duration for MMS. 2019-10-28 12:09:54 -04:00
Alex Hart
70636fb4a7 Blacklist Pixel4 from CameraX (#319)
* Blacklist Pixel4 from CameraX

* Create isSupported method
2019-10-28 13:07:28 -03:00
Alex Hart
3c4efdd8f9 Apply proper color when action mode destroyed 2019-10-28 12:00:59 -04:00
Greyson Parrelli
80deb301e5 Bump version to 4.49.10 2019-10-25 14:00:33 -07:00
Greyson Parrelli
5eabfdc34c Fix crash if you leave during log generation. 2019-10-25 14:00:33 -07:00
Greyson Parrelli
5e96832666 Disable video capture for legacy camera devices. 2019-10-25 13:54:38 -07:00
Alan Evans
1ccce24cf8 Fix drawable crash on API 19. 2019-10-25 15:33:34 -04:00
Greyson Parrelli
d59e4f2da7 Bump version to 4.49.9 2019-10-24 14:20:09 -07:00
Greyson Parrelli
a254c1a7b2 Updated language translations. 2019-10-24 14:17:19 -07:00
Alex Hart
82cc610938 Apply themed context to SingleRecipientNotificationBuilder 2019-10-24 17:59:34 -03:00
Greyson Parrelli
becf7c40e8 Bump version to 4.49.8 2019-10-23 23:45:13 -07:00
Greyson Parrelli
ed21c3ca03 Improve send button in media send flow.
Fixes #8988
2019-10-23 23:45:13 -07:00
Greyson Parrelli
631005e565 CameraX cleanup. 2019-10-23 23:45:13 -07:00
Greyson Parrelli
b57fab8c75 Make MediaSendActivity singleTask. 2019-10-23 23:45:13 -07:00
Greyson Parrelli
4260a8436b Fix possible de-duping issues.
- Clean bad hashes from earlier release.
- Fix file equality comparison.
- Given our new de-duping, we don't want to run into a situation where two
simultaneous compressions could be happening on the same image.
2019-10-23 23:45:13 -07:00
Greyson Parrelli
23d478191f Don't render 'null' contact labels. 2019-10-23 23:45:13 -07:00
Greyson Parrelli
d075a33d4e Fix issue where video controls may be missing.
Fixes #9121
2019-10-23 23:45:13 -07:00
Greyson Parrelli
7507dadbe7 Bump version to 4.49.7 2019-10-22 14:17:24 -04:00
Greyson Parrelli
bfd0363390 Fix potential tooltip crash. 2019-10-22 14:17:01 -04:00
Greyson Parrelli
cfb22825f4 Fix recent conversation query. 2019-10-22 13:49:31 -04:00
Greyson Parrelli
d37fafbfe7 Bump version to 4.49.6 2019-10-22 13:02:26 -04:00
Greyson Parrelli
2dc2eb5835 Updated language translations. 2019-10-22 13:02:26 -04:00
Greyson Parrelli
019d036f69 Fix soft nav color in conversation list.
Going in and out of multi-select mode would screw it up.

This fixes it by setting the flags correctly instead of blasting them
all away.
2019-10-22 13:02:26 -04:00
Greyson Parrelli
f1ca5fc8e2 Exclude inactive groups from search results where appropriate.
Fixes #9091
Fixes #9080
2019-10-22 12:41:20 -04:00
Greyson Parrelli
9089fc4001 Fix potential display issues in Message Details screen. 2019-10-22 11:00:03 -04:00
Greyson Parrelli
b281b817ba Add additional logging around attachment upload/deletion. 2019-10-22 10:52:55 -04:00
Greyson Parrelli
cee6736656 Fix flickering 'about' section in group recipient preferences.
Gotta disable those pesky layout animations.

Fixes #9092
2019-10-22 10:30:11 -04:00
Greyson Parrelli
350ca059b9 Pick camera resolution based on screen resolution. 2019-10-22 10:16:14 -04:00
Greyson Parrelli
a7cc5bdc5e Ensure keyboard is hidden when going to the gallery.
Fixes #9120
2019-10-22 09:50:01 -04:00
Greyson Parrelli
2893dfff60 Bump version to 4.49.5 2019-10-21 20:05:31 -04:00
Greyson Parrelli
1c14f06734 Updated language translations. 2019-10-21 20:04:20 -04:00
Greyson Parrelli
ff053437e3 Fix issue where album rail wasn't immediately shown.
Fixes #9111
2019-10-21 20:04:20 -04:00
Alex Hart
03dc220cea Fix crash related to unsupported camera mode.
Fixes #9106
2019-10-21 19:32:19 -04:00
Greyson Parrelli
097f97b5e4 Add system to allow skipping attachment compression. 2019-10-21 19:32:19 -04:00
Alex Hart
95d3db3260 Add ic_message webp files 2019-10-21 15:30:20 -03:00
Greyson Parrelli
0485ae603b Set targetResolution to something reasonable for camera capture. 2019-10-21 10:58:07 -04:00
Alex Hart
2f93da6f1a Fix wrong icon color in expiry footer 2019-10-21 11:50:32 -03:00
Alex Hart
78f3e28974 Fix progress wheel color in share screen 2019-10-21 10:53:18 -03:00
Alex Hart
fecd8300c3 Swap ValueAnimator with version from NineOldAndroids 2019-10-21 10:51:04 -03:00
Alex Hart
262f90dbe7 Add new info icon to message details view 2019-10-21 10:09:54 -03:00
Alex Hart
ed271c6f3e Fix longmessage and shared contact footer alignment 2019-10-21 10:00:28 -03:00
Greyson Parrelli
3fa5843c93 Bump version to 4.49.4 2019-10-21 01:13:19 -04:00
Greyson Parrelli
7f544cb3e5 Updated language translations. 2019-10-21 01:12:51 -04:00
Greyson Parrelli
9f4d40a364 Revert "Prevent compression of images without EXIF data."
This reverts commit 8449d75684.
2019-10-21 01:00:31 -04:00
Greyson Parrelli
09f0c5b63f Fix bug in manual conversation search query submission.
Fixes #9115
2019-10-21 00:49:06 -04:00
Greyson Parrelli
53e0dc5dee Potential MMS download fix for some users.
Special thanks to @mdaniel

Fixes #8571
2019-10-21 00:36:54 -04:00
Greyson Parrelli
8b06051e7c Fix blurhash being visible on transparent images. 2019-10-21 00:21:53 -04:00
Greyson Parrelli
660ec88202 Fix data deduping issues.
Fixes #9109
2019-10-21 00:21:48 -04:00
Greyson Parrelli
b9057a1c11 Use fallback images for Giphy results. 2019-10-20 01:13:02 -04:00
Greyson Parrelli
1f85b1f3d2 Bump version to 4.49.3 2019-10-19 12:37:00 -04:00
Greyson Parrelli
71f78f03f4 Updated language translations. 2019-10-19 12:34:30 -04:00
Greyson Parrelli
4b3d129097 Cleanup some possible bad RecipientIds in the MMS table. 2019-10-19 12:31:06 -04:00
Greyson Parrelli
daeb823399 Fix CameraX crash. 2019-10-19 12:25:40 -04:00
Greyson Parrelli
c7f76c5d1c Add a util to safely set a MediaMetadataRetriever data source. 2019-10-19 12:23:23 -04:00
Greyson Parrelli
9ba1391a1e Fix issue with non-contact avatar colors not updating. 2019-10-19 12:15:14 -04:00
Greyson Parrelli
5d137465e8 Bump version to 4.49.2 2019-10-18 18:46:07 -04:00
Greyson Parrelli
78cbb3c073 Updated language translations. 2019-10-18 18:45:43 -04:00
Greyson Parrelli
097d95428a Fix conversation list toolbar styling. 2019-10-18 17:34:01 -04:00
Greyson Parrelli
2cfb6ede7f Increase record button size. 2019-10-18 17:34:01 -04:00
Greyson Parrelli
695663a5b1 Log more data about video capture support. 2019-10-18 17:34:01 -04:00
Greyson Parrelli
a2204c8370 Update video recording tooltip text. 2019-10-18 17:34:01 -04:00
Alex Hart
8c4757ea02 Fix safety number theme 2019-10-18 17:34:01 -04:00
Greyson Parrelli
85821274fa Don't render null phone number labels. 2019-10-18 17:34:01 -04:00
Greyson Parrelli
a8b1ec8e52 Increase compose maxLines to 5. 2019-10-18 17:34:01 -04:00
Alex Hart
adbdaebd69 Fix invite screen theme. 2019-10-18 17:33:45 -04:00
Alex Hart
c2da4fcd7d Update CameraX to Alpha06 and bring in new View / Module code. 2019-10-18 17:36:00 -03:00
Greyson Parrelli
46ebff3659 Bump version to 4.49.1 2019-10-18 13:58:59 -04:00
Greyson Parrelli
452ccd0350 Updated language translations. 2019-10-18 13:58:35 -04:00
Alan Evans
6e6c809690 Use lighter-weight shadow view. 2019-10-18 13:51:56 -04:00
Greyson Parrelli
7b5c1904cf Update contact list divider styling. 2019-10-18 13:09:20 -04:00
Alex Hart
c0aa9d7587 Update preference divider colors 2019-10-18 13:09:20 -04:00
Alex Hart
5d03e3d516 Apply video recording permissions checks and error handling. 2019-10-18 13:09:20 -04:00
Greyson Parrelli
2bc3a4417f Fix possible crash when retrieving a video thumbnail. 2019-10-18 11:10:26 -04:00
Greyson Parrelli
59d03cbeb2 Address possible issues with AvatarMigrationJob. 2019-10-18 11:08:06 -04:00
Alex Hart
f9f9ae68f5 Fix MediaSendActivity send button metrics and positioning. 2019-10-18 10:49:54 -03:00
Alex Hart
88f2b67984 Fix crash on conversation color picker open. 2019-10-18 10:33:10 -03:00
Greyson Parrelli
44dba4bd98 Only show video tooltip if capable. 2019-10-18 09:31:01 -04:00
Alan Evans
ef585eba42 Revert "Fix invite drawable on API 21."
This reverts commit 78fbfe40736dd8c9ccafb402aa7fc6921c1d4496.

We have turned on AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) now for API19.
2019-10-18 09:15:20 -04:00
Alex Hart
42967dab13 Apply proper tinting to conversation app bar. 2019-10-18 09:55:27 -03:00
Greyson Parrelli
4f75d1a5db Bump version to 4.49.0 2019-10-17 22:45:56 -04:00
Greyson Parrelli
debacbdf58 Updated language translations. 2019-10-17 22:44:32 -04:00
Greyson Parrelli
12c4283c30 Conditionally show a toolbar shadow in the conversation list. 2019-10-17 22:23:27 -04:00
Greyson Parrelli
096c9e0ff7 Ensure videos are paused properly in MediaSendActivity. 2019-10-17 21:33:52 -04:00
Greyson Parrelli
2f23a13a6f Fix issue where video playback controls sometimes don't appear. 2019-10-17 21:33:52 -04:00
Alan Evans
bdadbaaac4 Remove larger images for link preview intro.
(I bet you thought they would be together forever).
2019-10-17 21:33:52 -04:00
Alan Evans
16f41555ba Local SMS rate limiting. 2019-10-17 21:33:52 -04:00
Greyson Parrelli
8c037456e7 Warm up LiveRecipientCache at launch. 2019-10-17 21:33:52 -04:00
Greyson Parrelli
feccee557e Include better defaults for ConversationActivity. 2019-10-17 21:33:52 -04:00
Greyson Parrelli
67f5605bc4 Block in RestStrategy until PushDecryptJobs finish. 2019-10-17 21:33:52 -04:00
Greyson Parrelli
ccb18cd46c Added JobTracker. 2019-10-17 21:33:52 -04:00
Alan Evans
5b1d91016c Fix backup sorting logic and do not delete non-backups in path. 2019-10-17 21:33:52 -04:00
Alan Evans
27ab04ab41 Add version and spread out witness information. 2019-10-17 21:33:52 -04:00
alex-signal
9432a45b39 Implement blur-hash based low resolution thumbnail previews. 2019-10-17 21:33:52 -04:00
alex-signal
9e3475ed94 Upgrade Gradle to 5.6.2 and AGP to 3.5.1 2019-10-17 21:33:52 -04:00
Alan Evans
86d088bce2 Improved registration flow. 2019-10-17 21:33:52 -04:00
alex-signal
a135e7efa2 Check DND settings before show activity or play ring or vibrate. 2019-10-17 21:33:52 -04:00
tzm
c247935f1a Fix NPE when has no contact permissions.
Fixes #9048

Co-authored-by: Alan Evans <alan@signal.org>
2019-10-17 21:33:52 -04:00
Alan Evans
31657f5c15 Gradle witness sort dependencies and move to own auto generated file. 2019-10-17 21:33:52 -04:00
Greyson Parrelli
bcecc30d33 Disallow RecipientId's of zero. 2019-10-17 21:33:52 -04:00
Greyson Parrelli
7193252d77 Fix TooltipPopup positioning. 2019-10-17 21:33:51 -04:00
Greyson Parrelli
5b682a3a3d Use our own location retriever. 2019-10-17 21:33:51 -04:00
Greyson Parrelli
6b8659a393 Move JobManager to ApplicationDependencies. 2019-10-17 21:33:51 -04:00
Alan Evans
14557d3dc1 Change default GZIP behavior on Base64.decode(String).
Remove only reference to Base64.decode(byte[]).
2019-10-17 21:33:51 -04:00
Curt Brune
03cbee0277 Add ringrtc support.
RingRTC provides Signal Messenger applications with a common interface
for video and voice calling services built on top of WebRTC.
2019-10-17 21:33:51 -04:00
alex-signal
adc0907906 Copy image to encrypted blob and delete from device immediately.
Fixes #9097
2019-10-17 21:33:51 -04:00
Alan Evans
f14a71a076 Update Lint suppressions. 2019-10-17 21:33:51 -04:00
alex-signal
12c2b53f7c Set icon to themed version via attribute.
Fixes #9054
2019-10-17 21:33:51 -04:00
alex-signal
ff60b5b731 Add in-app video recording for supported devices. 2019-10-17 21:33:51 -04:00
alex-signal
43954a176a Apply new Signal icons and color palette. 2019-10-17 21:33:51 -04:00
Alex Hart
d698d3bd6f Added support for view-once video. 2019-10-17 16:01:34 -04:00
Greyson Parrelli
50a81c0e60 Added a simple staging build config. 2019-10-17 16:01:34 -04:00
Greyson Parrelli
b0b8377a8e Migrate notification channels to recipientId's. 2019-10-17 16:01:34 -04:00
alex-signal
7d02bb8487 Store file hash to avoid data duplication. 2019-10-17 16:01:34 -04:00
alex-signal
8449d75684 Prevent compression of images without EXIF data. 2019-10-17 16:01:34 -04:00
Greyson Parrelli
b89163bb14 Migrate avatars to use recipientId filenames. 2019-10-17 16:01:34 -04:00
Greyson Parrelli
b7ce220600 Updated libsignal version to 2.13.8 2019-10-15 10:35:59 -04:00
Greyson Parrelli
948079a42e Bump version to 4.48.17 2019-10-15 10:35:15 -04:00
Greyson Parrelli
de1c6cdd0c Fix crash when MMS messages have no 'from' address. 2019-10-15 10:35:15 -04:00
Greyson Parrelli
37147fb0a5 Bump version to 4.48.16 2019-10-08 21:28:54 -07:00
Greyson Parrelli
33334f80c3 Add back proper support for unknown recipients.
Fixes #9085
2019-10-08 21:28:35 -07:00
Greyson Parrelli
36286da9bd Bump version to 4.48.15 2019-10-08 14:23:29 -07:00
Greyson Parrelli
2248acb9f2 Remove unnecessary resolves. 2019-10-08 14:23:29 -07:00
Greyson Parrelli
3632a2cc95 Hide no-name contacts from system search results. 2019-10-08 13:38:20 -07:00
Greyson Parrelli
9447ea12cb Remove concept of 'unknown' recipient. 2019-10-08 13:33:13 -07:00
Greyson Parrelli
89c2329fdf Bump version to 4.48.14 2019-10-07 16:52:36 -07:00
Greyson Parrelli
84012c7adb Fix crash in SmsMigrator. 2019-10-07 16:41:47 -07:00
Greyson Parrelli
d7395af774 Simplify recipient inserts. 2019-10-07 16:31:04 -07:00
Greyson Parrelli
be4daff0f3 Ensure recipient models are up-to-date. 2019-10-07 16:31:04 -07:00
Greyson Parrelli
c2459d0a31 Bump version to 4.48.13 2019-10-04 12:13:16 -04:00
Greyson Parrelli
5f993ed0f7 Fix threading issue in RecipientDatabase. 2019-10-04 12:07:46 -04:00
Greyson Parrelli
acea24c19c Reduce Recipient refreshes. 2019-10-04 10:52:43 -04:00
Greyson Parrelli
82b5d58d04 Fix threading issues in LiveRecipient. 2019-10-04 10:52:43 -04:00
Greyson Parrelli
af2990fa08 Bump version to 4.48.12 2019-10-03 16:08:18 -04:00
Greyson Parrelli
0fa48540e1 Fix migration of old pending SMS sends. 2019-10-03 16:07:53 -04:00
Greyson Parrelli
0f06b96832 Bump version to 4.48.11 2019-10-03 11:18:51 -04:00
Greyson Parrelli
4f423be6f9 Updated language translations. 2019-10-03 11:18:07 -04:00
Greyson Parrelli
bea21ed5ff Further recipient insertion improvements. 2019-10-03 11:17:48 -04:00
Greyson Parrelli
a9cff032f5 Bump version to 4.48.10 2019-10-02 20:44:22 -04:00
Greyson Parrelli
b2d02d4ace Add extra protections to recipient insertions. 2019-10-02 20:13:49 -04:00
Greyson Parrelli
066df77abf Revert "Use recipientId's in ContactSelectionListAdapter."
This reverts commit 89e075c56e.
2019-10-02 19:26:24 -04:00
Greyson Parrelli
b38a3e6259 Remove unnecessary recipient resolves. 2019-10-02 19:16:59 -04:00
Greyson Parrelli
d78919acf8 Bump version to 4.48.9 2019-10-02 12:36:24 -04:00
Greyson Parrelli
af96d11188 Pretty-print missing recipientId crashes. 2019-10-02 12:22:26 -04:00
Greyson Parrelli
5e1bef26ed Fix display of profile names in FTS results. 2019-10-02 12:22:26 -04:00
Greyson Parrelli
95333eccd4 Cleanup bad recipients. 2019-10-02 12:22:26 -04:00
Greyson Parrelli
89e075c56e Use recipientId's in ContactSelectionListAdapter. 2019-10-02 11:24:55 -04:00
Greyson Parrelli
d026498a8c Use recipientId's in SearchRepository. 2019-10-02 11:24:55 -04:00
Greyson Parrelli
bae381e6f8 Bump version to 4.48.8 2019-10-01 08:20:16 -04:00
Greyson Parrelli
050f7a24c9 Updated language translations. 2019-10-01 08:19:46 -04:00
Greyson Parrelli
77ad1ea729 Prevent ConversationActivity recipientId crash. 2019-10-01 08:17:25 -04:00
Greyson Parrelli
bf667c0cfc Revert "Add logging to track down ConversationActivity crash."
This reverts commit 447236ee38.
2019-10-01 08:16:57 -04:00
Greyson Parrelli
ccb8ef98b4 Bump version to 4.48.7 2019-09-30 15:19:41 -04:00
Greyson Parrelli
a1f0660339 Updated language translations. 2019-09-30 15:19:24 -04:00
Greyson Parrelli
447236ee38 Add logging to track down ConversationActivity crash. 2019-09-30 15:19:24 -04:00
Alan Evans
ebf3b0dfe1 Change versionCode for universal builds. 2019-09-30 14:16:49 -04:00
Greyson Parrelli
ee9216df8a Ensure group status is available in ConversationAdapter constructor. 2019-09-30 14:15:19 -04:00
Greyson Parrelli
3e34668232 Bump version to 4.48.6 2019-09-28 00:16:41 -04:00
Curt Brune
8f8f41f184 Localize call audio and video activation code 2019-09-28 00:16:09 -04:00
Greyson Parrelli
4f7cba8d7c Bump version to 4.48.5 2019-09-27 14:26:08 -04:00
Greyson Parrelli
00b719c783 Updated language translations. 2019-09-27 14:22:13 -04:00
Greyson Parrelli
b03eccec33 Persist the JobFactory key after job migrations. 2019-09-27 14:18:15 -04:00
Greyson Parrelli
5805539deb Revert "Potential MMS download fix for some users."
This reverts commit 1e375ec494.
2019-09-27 14:02:01 -04:00
Greyson Parrelli
1b48fd07a3 Bump version to 4.48.4 2019-09-26 18:32:28 -04:00
Greyson Parrelli
1e375ec494 Potential MMS download fix for some users.
Special thanks to @mdaniel

Fixes #8571
2019-09-26 18:32:28 -04:00
Greyson Parrelli
ee9acf2687 Show tooltip for swipe-to-reply. 2019-09-26 16:37:09 -04:00
Greyson Parrelli
1d8e85fcad Updated the feel of swipe-to-reply. 2019-09-26 16:36:52 -04:00
Greyson Parrelli
4e2afa7362 Fix some more broken JobMigrations. 2019-09-26 11:18:04 -04:00
Greyson Parrelli
d06564c7b9 Bump version to 4.48.3 2019-09-25 19:12:24 -04:00
Greyson Parrelli
ced48d0788 Fix custom notification creation. 2019-09-25 18:58:21 -04:00
Greyson Parrelli
e273593343 Fix more possible JobMigration crashes. 2019-09-25 15:19:08 -04:00
Greyson Parrelli
c5767b07a7 Initialize CameraX on a background thread.
We saw a situation where CameraX initialization could lock up when
trying to obtain system resource. We already fallback to the
Camera1Fragment when CameraX isn't initialized, so it should be safe to
do this initialization on its own thread.
2019-09-25 15:17:35 -04:00
Greyson Parrelli
709ce7e9de Bump version to 4.48.2 2019-09-25 11:37:55 -04:00
Greyson Parrelli
a8f7908ed4 Updated language translations. 2019-09-25 11:37:55 -04:00
Greyson Parrelli
8230786638 Added permissions to the debug log. 2019-09-25 11:23:23 -04:00
Greyson Parrelli
df4ecc4e32 Add blocked threads to the debug log. 2019-09-25 11:23:23 -04:00
Greyson Parrelli
5b755b9501 Crash early when using a null RecipientId. 2019-09-25 09:51:50 -04:00
Greyson Parrelli
b3c7c8db5c Fix possible crash in DirectoryRefreshJob. 2019-09-25 09:51:50 -04:00
Greyson Parrelli
a21c537428 Fix crash during JobMigration. 2019-09-25 09:51:50 -04:00
Greyson Parrelli
6d339cd023 Fix a crash when starting a call from the system contacts. 2019-09-25 09:51:50 -04:00
Alan Evans
840c493265 Fix pretty print phone numbers.
Fixes #9047
2019-09-25 09:49:26 -04:00
alex-signal
14999800e2 Fix Swipe to Reply progress reset when AnimatorDurationScale is 0.
Fixes #9051
2019-09-25 10:08:10 -03:00
Greyson Parrelli
8e332d0798 Bump version to 4.48.1 2019-09-24 12:13:27 -04:00
Greyson Parrelli
cd007a20d7 Fix possible thread visibility issue in CellConstraintObserver.
Related to #9030.
2019-09-24 12:13:27 -04:00
Greyson Parrelli
8b99af3eef Fix threading issues with LiveRecipient. 2019-09-24 12:03:33 -04:00
Greyson Parrelli
d354de806e Bump version to 4.48.0 2019-09-24 10:24:37 -04:00
alex-signal
c7ef0c06f8 Fix exif dimension edge case and handle invalid dimens better in ThumbnailView. 2019-09-24 10:11:17 -04:00
Greyson Parrelli
9d14bcb808 Enable sticker sharing. 2019-09-24 10:11:17 -04:00
alex-signal
de03706d8d Fix video thumbnail not displaying after sharing to conversation thread. 2019-09-24 10:11:17 -04:00
alex-signal
a3caabcafd Fix video forwarding thumbnail display. 2019-09-24 10:11:17 -04:00
alex-signal
faafa40122 Fix DecryptableStreamLocalUriFetcher bug for external video thumbnails.
Fix bug where external video thumbnails do not appear.
2019-09-24 10:11:17 -04:00
Greyson Parrelli
d1a6582ad7 Support independent application migration versions. 2019-09-24 10:11:17 -04:00
alex-signal
f81c0b448e Add CameraXFlashToggleView and selfie flash. 2019-09-24 10:11:17 -04:00
Greyson Parrelli
70347e754c Add a feature flag system. 2019-09-24 10:11:17 -04:00
Greyson Parrelli
a1245baf61 Don't show MMS groups in recent Signal contacts list. 2019-09-24 10:11:17 -04:00
Alex Hart
007ea43dc8 Add Swipe-To-Reply in conversations.
Swipe-To-Reply is a progress based animation that is controlled
by the ConversationItemSwipeCallback.  We use the TouchListener to
keep track of the latest down coordinates, so that we can check whether
we are over a seek bar. The SwipeAnimationHelper is responsible for
actually performing the transitions as the swipe progresses.
2019-09-24 10:11:17 -04:00
Greyson Parrelli
582028f2c2 Search contacts via the RecipientDatabase. 2019-09-24 10:11:17 -04:00
Greyson Parrelli
0e2d52026e Migrated to locally-assigned RecipientId's.
Oh boy.
2019-09-24 10:11:17 -04:00
Greyson Parrelli
233cc7ecce Bump version to 4.47.6 2019-09-16 17:00:06 -04:00
Greyson Parrelli
1baf03f51a Fix message fetching bug when app is in the foreground.
Fixes #9036
2019-09-16 16:58:51 -04:00
Greyson Parrelli
f066a9cab2 Bump version to 4.47.5 2019-09-11 18:01:50 -04:00
Curt Brune
825d1a02ab Update to WebRTC M77 2019-09-11 13:55:26 -07:00
Curt Brune
97cc8b7777 Revert "Add ringrtc support."
Revert the following commits:

"Handle busy call while in PSTN call."
Commit 23a0bb3ce0.

"Add ringrtc support."
Commit 3ac540c687.
2019-09-11 11:17:23 -07:00
Greyson Parrelli
72662b5b52 Bump version to 4.47.4 2019-09-06 13:56:17 -04:00
Greyson Parrelli
ea4e0b6d6f Updated language translations. 2019-09-06 13:56:04 -04:00
Alan Evans
6df93c0bb5 Fix potential contact search crash. 2019-09-06 13:53:26 -04:00
Curt Brune
23a0bb3ce0 Handle busy call while in PSTN call. 2019-09-06 10:20:32 -07:00
Greyson Parrelli
4cd5256267 Bump version to 4.47.3 2019-09-04 11:10:47 -04:00
Greyson Parrelli
5362e07a5c Fix crash that may happen upon first sticker install. 2019-09-04 11:09:30 -04:00
Greyson Parrelli
936bd327bd Bump version to 4.47.2 2019-09-03 15:38:34 -04:00
Greyson Parrelli
db89619a4a Updated language translations. 2019-09-03 15:38:20 -04:00
Alan Evans
b5ce7325fc Fix invite drawable on API 19. 2019-09-03 15:20:09 -04:00
Greyson Parrelli
ccaeb089ab Bump version to 4.47.1 2019-09-02 18:57:14 -04:00
Greyson Parrelli
3240ba3a55 Updated language translations. 2019-09-02 18:53:57 -04:00
Alan Evans
bb7be66efe Fix stickers in image editor.
Fixes #9012
2019-09-02 18:16:30 -04:00
Alan Evans
8814a0d949 Update invite icon. 2019-09-02 18:15:27 -04:00
Greyson Parrelli
9aa488223f Bump version to 4.47.0 2019-08-31 11:28:34 -04:00
Greyson Parrelli
30d9233365 Updated language translations. 2019-08-31 11:28:34 -04:00
Curt Brune
3ac540c687 Add ringrtc support.
RingRTC provides Signal Messenger applications with a common interface
for video and voice calling services built on top of WebRTC.
2019-08-31 07:54:47 -07:00
Alan Evans
8d561ead21 Stickers in image editor. 2019-08-30 17:45:35 -04:00
Alan Evans
15b650382e Fullscreen media preview on tap. 2019-08-30 17:31:59 -04:00
Oscar Mira
110a40592b Make E164 log scrubber redact numbers of length >= 7. 2019-08-30 08:20:21 -04:00
Alan Evans
d0ce4ff032 Lottie play pause animation. 2019-08-29 11:57:41 -04:00
Alan Evans
85c9a9050a Add an invite button in the new conversation screen. 2019-08-29 11:07:33 -04:00
Greyson Parrelli
af42d5b671 Create system for job migrations. 2019-08-29 11:07:33 -04:00
Greyson Parrelli
9580bb0a38 Renamed WorkManager migration package. 2019-08-29 11:07:33 -04:00
Greyson Parrelli
9abb167874 Bump version to 4.46.2 2019-08-28 10:27:40 -04:00
Greyson Parrelli
cd13676a21 Updated language translations. 2019-08-28 10:26:29 -04:00
Greyson Parrelli
1dd59bee36 Use raw versionCodes in web apk json.
We missed a spot when transitioning to split apk versions. It ended up
breaking the update prompt for web apks.

This will put the raw universal apk version in the json file, which
should put us back on the right track.

Fixes #8936
2019-08-28 10:26:29 -04:00
Greyson Parrelli
59bcbe592b Revert "Add ringrtc support"
This reverts commit 7f0a7b0c13.
2019-08-28 09:16:51 -04:00
Greyson Parrelli
0917e17c69 Fix bug where you couldn't reply with media.
Fixes ##8999
2019-08-27 09:40:32 -04:00
Greyson Parrelli
eb249ca69a Bump version to 4.46.1 2019-08-24 15:18:22 -04:00
Greyson Parrelli
97d1175915 Updated language translations. 2019-08-24 14:35:35 -04:00
Alan Evans
2141f1073e Ensure memory file descriptor is available. 2019-08-24 14:30:02 -04:00
Greyson Parrelli
c6287547a3 Improve video transcoding exception handling.
Previously, we'd crash if we couldn't find the attachment at runtime,
but that's not uncommon if someone deletes before sending. Now we just
fail.

Also, previously we'd fail if we couldn't create a memory file. Now we
will only fail if the attachment is >100mb (same as the other video
failures).
2019-08-24 09:27:08 -04:00
Greyson Parrelli
9257c6ddf3 Fix failure propogation in longer job chains. 2019-08-24 09:09:20 -04:00
Greyson Parrelli
480748e1aa Bump version to 4.46.0 2019-08-23 10:01:29 -04:00
Greyson Parrelli
c015687951 Updated language translations. 2019-08-23 10:01:06 -04:00
Alan Evans
1bd1e9cc65 Read optional video display dimensions.
Add RequiresApi annotations.

Fixes #8982
2019-08-22 10:15:56 -04:00
Alan Evans
c4a4374465 RTL screen animations.
RTL fix Profile name in Settings.
2019-08-22 10:15:56 -04:00
Alan Evans
90681d47f8 Fix first item sticky header. 2019-08-22 10:15:56 -04:00
Alan Evans
936be693ce Enlarge some home touch targets and add search content description. 2019-08-22 10:15:56 -04:00
Alan Evans
a32b875587 Support disabled animations for accessibility. 2019-08-22 10:15:56 -04:00
Alan Evans
4e6798e38e Fix occasional double scroll bar on fast scroller. 2019-08-22 10:15:56 -04:00
Alan Evans
6352f7baf4 Update item design in contact selection. 2019-08-22 10:15:56 -04:00
Alan Evans
aac9725adc Move shared attachment job generation code to parent class. 2019-08-22 10:15:56 -04:00
Alan Evans
900371bb30 Call answer button listens to accessibility changes. 2019-08-22 10:15:56 -04:00
Alan Evans
a58f564d1e Escape string within Full Text Search.
Fixes #8975
2019-08-22 10:15:56 -04:00
Alan Evans
942154a61f Separate compression job. 2019-08-22 10:04:23 -04:00
Curt Brune
7f0a7b0c13 Add ringrtc support
Initial commit of the RingRTC Java interface implementation.

The implementation lives in an external .aar with the package
org.signal.ringrtc.

The package provides two high level objects of interest
=======================================================

org.signal.ringrtc.CallConnection -- represents the session of a call,
very similar to WebRTC's PeerConnection.

org.signal.ringrtc.CallConnectionFactory -- creates CallConnection
objects, very similar to WebRTC's PeerConnectionFactory.

The implementation interfaces with the Android application in a few
places:
==================================================================

src/org/thoughtcrime/securesms/ApplicationContext.java -- RingRTC
library initialization at application startup.

src/org/thoughtcrime/securesms/service/WebRtcCallService.java -- Call
creation and state machine.

src/org/thoughtcrime/securesms/ringrtc -- this package implements
interface classes needed by ringrtc and a CallConnectionWrapper helper
class.

The two interfaces needed so far are:

  ringrtc/Logger.java
  ringrtc/SignalMessageRecipient.java

The logger is self-explanatory, but SignalMessageRecipient is a little
more involved.  SignalMessageRecipient encapsulates the Signal-Android
notion of "Recipient" and the mechanism for sending Signal Messages
related to audio/video calling.

The CallConnectionWrapper class is clone of the original
org.thoughtcrime.securesms.webrtc.PeerConnectionWrapper, suitably
modified to match the CallConnection interface.

This class continues to handle the Camera switching APIs, with that
portion of the code remaining unmodified from the original.

CallConnectionFactory Details
=============================

The primary public methods:

initialize() -- initialize the WebRTC library and RingRTC library.
The WebRTC initialization is lifted from the original Signal-Android
code.

createCallConnectionFactory() -- creates a CallConnectionFactory
object.  Internally it creates a WebRTC PeerConnectionFactory object
and a RingRTC CallConnectionFactory object.

dispose() -- tears down the CallConnectionFactory object, including
the internal PeerConnectionFactory and RingRTC CallConnectionFactory.

createCallConnection() -- creates a CallConnection object, connecting
that with an application controlled CallConnection.Observer object.

This function takes a CallConnection.Configuration object to link the
CallConnection object with some application provided services, like
sending Signal protocol messages.

CallConnection Details
======================

This object is a subclass of WebRTC's PeerConnection class.

The primary public methods and objects:

CallConnection.Configuration
----------------------------

Configuration object used to parameterize a call.  Notable members:

- SignalServiceMessageSender messageSender
- long callId
- org.signal.SignalMessageRecipient recipient

The 'accountManager' is used to fetch public information from the Signal
service, specifically used here to obtain the public Signal TURN
server details.

The 'callId' is a 64-bit pseudo-random number generated when the call
is initiated, used to identify the call through out its lifetime.

The "recipient' is an implementation of the
org.signal.SignalMessageRecipient interface, which encapsulates the
sending of Signal service messages to a recipient (remote peer) using
existing Signal protocol data structures.

The native library needs to be able to send Signal messages via the
service, but it does not have a native implementation to do so.
Instead the native code calls out to the client for sending Signal
messages.  To accomplish this, the client implements the
org.signal.SignalMessageRecipient interface and passes an instance of
that in a CallConnection.Configuration object.

CallConnection
--------------

dispose() -- tears down the CallConnection object, including the
internal PeerConnection and RingRTC CallConnection.

sendOffer() -- initiates a call to a remote recipient.  This is the
beginning of an outbound call.

validateResponse() -- checks an offer response recipient against the
originating call details.

handleOfferAnswer() -- handles the receipt of answer, which was a
response from an originating offer.

acceptOffer() -- accept an offer from a remote participant.  This is
the begin of an incoming call.

answerCall() -- invoked when the call is completely established and
online.

hangUp() -- hang up the connection and shut things done.  This is the
end of the call.

sendBusy() -- send the remote side an indication that the local side
is already in a call and the line is busy.

sendVideoStatus() -- send the current state of the local camera video
stream to the remote side.

CallConnection.Observer
-----------------------

Observer object, used by the RingRTC library to notify the client
application of important events and status changes.  Similar in spirit
to WebRTC's PeerConnection.Observer.

Observer callbacks come in three flavors:

- state change notifications,
- on stream notifications
- errors conditions

For state notifications, the callback contains the callId, the
recipient and a CallConnection.CallEvent type.

For streams, the callback contains the callId, the
recipient and a org.webrtc.MediaStream.

For errors, the callback contains the callId, the recipient and an
exception type.  The currently thrown exceptions include:

- UntrustedIdentityException
- UnregisteredUserException
- IOException

Signed-off-by: Curt Brune <curt@signal.org>

Updates to support ringrtc-android version 0.1.0.

* simplify logging interface

It is no longer necessary for the application to specify a Log object
as the library can log via the NDK directly.

* improve error handling and notification

In a number of places where ringrtc errors could occur, no
notification was ever sent to the user, nor was the UI cleaned up.  It
would look like the app was in hung state.

This patch updates these situations to send the WebRtcViewModel a
NETWORK_FAILURE message.

* update handleIncomingCall() for lockManager and notification

During the conversion to RingRTC, the implementation of
handleIncomingCall() missed a couple of things:

-- updating the Phone state with the lockManager
-- sending a message to the viewModel

* log the callId in various handler methods

For debugging purposes it is very handy to have the callId present in
the log during the various call handler methods.

Signed-off-by: Curt Brune <curt@signal.org>
2019-08-22 10:04:23 -04:00
Alan Evans
37bcac40bb URL encoded scrubber.
* Replace scrubber and tests.

* Improves email regex performance.
2019-08-22 10:04:23 -04:00
Greyson Parrelli
02ea99254a Reset message receiver upon REST failure.
We've been seeing a lot of socket timeouts on REST requests under
certain conditions. The issue seems to be a problem with the OkHttp
client. Through testing, I've seen that resetting the receiver and
retrying again seems to resolve most issues.
2019-08-22 10:04:23 -04:00
Greyson Parrelli
3849b46f0a Refactor ApplicationDependencies. 2019-08-22 10:04:23 -04:00
Greyson Parrelli
116bd41c63 Use EmojiTextView in the sticker preview. 2019-08-22 10:04:23 -04:00
Greyson Parrelli
457ad4c607 Added a central system for message retrieval. 2019-08-22 10:04:23 -04:00
Greyson Parrelli
d0a9bd4c6d Create a new system for application-level migrations. 2019-08-22 10:04:23 -04:00
Greyson Parrelli
d3bed549f2 Switch back to storing incoming messages in PushDatabase.
On a Pixel 3, this adds ~30-40ms of delay, but it's going to be a
requirement for upcoming migrations.
2019-08-22 10:04:23 -04:00
Alan Evans
fe1aa016b9 Refactor group operations. 2019-08-22 10:04:17 -04:00
Greyson Parrelli
af55cb0c03 Bump version to 4.45.2 2019-08-05 15:48:22 -04:00
Greyson Parrelli
714eaa62a8 Updated language translations. 2019-08-05 15:48:22 -04:00
Greyson Parrelli
5038f49487 Fix issue with sticker preview sizing. 2019-08-05 15:48:22 -04:00
Greyson Parrelli
57835dc8f1 Update view-once message behavior. 2019-08-05 15:46:43 -04:00
Alan Evans
3439eb4536 Replace disk icon with download icon. 2019-08-05 12:13:15 -04:00
Alan Evans
929ee04814 Handle missing video duration.
On EncodingException, or no duration metadata found, when video < 100MB, continue with send.
2019-08-05 10:48:18 -04:00
Greyson Parrelli
9d98a779a8 Bump version to 4.45.1 2019-08-02 17:01:11 -04:00
Greyson Parrelli
5a23ddeaf4 Updated language translations. 2019-08-02 17:01:11 -04:00
Greyson Parrelli
7ae5159194 Downgrade some job exceptions.
Runtime exceptions were being thrown where it'd be safer to either
ignore it or throw a checked, failing exception.
2019-08-02 17:00:48 -04:00
Alan Evans
bdf93af3db Clear outstanding glide requests.
Fixes #8967
2019-08-02 16:00:22 -04:00
Alan Evans
dcc147d994 Reduce frame timeout crashes. 2019-08-02 15:57:20 -04:00
Greyson Parrelli
19b2658414 Fix Job.Result logging. 2019-08-01 16:42:59 -04:00
Greyson Parrelli
1c4833f3b4 Bump version to 4.45.0 2019-08-01 10:40:52 -04:00
Greyson Parrelli
e8ca673bf8 Updated language translations. 2019-08-01 10:40:52 -04:00
Alan Evans
5a614faee1 Camera content descriptions and allow camera capture in talk back. 2019-08-01 10:40:52 -04:00
Greyson Parrelli
af8042c5f4 Use proper icon and theme for camera button. 2019-08-01 10:40:52 -04:00
Greyson Parrelli
a46e7541d0 Switch from contentUris to fileUris in the media gallery.
Android Q encounters massive slowdown when using contentUris for media.
Switching to fileUris (which we're already doing for the folder
thumbnail) gets us back to the expected performance level.
2019-08-01 10:40:37 -04:00
Alan Evans
a6890fc8dd Video playback on TextureView and DepthPageTransformer. 2019-08-01 08:45:29 -04:00
Alan Evans
0c0d7aeead Remove old pre-v9, pre-v11, and pre-v12 assets. 2019-08-01 08:45:29 -04:00
Ellen Poe
874697f6e5 Added content descriptions for some important controls.
Fixes #8728

Co-authored-by: Alan Evans <alan@signal.org>
2019-08-01 08:45:29 -04:00
Alan Evans
e0d1987445 Accessible call answering/rejecting and content descriptions. 2019-08-01 08:45:29 -04:00
Greyson Parrelli
17400020b7 Allow RuntimeExceptions thrown by Jobs to crash. 2019-07-31 09:54:46 -04:00
Alan Evans
e8e80e5d05 Transcode video during attachment upload. 2019-07-31 09:54:46 -04:00
Alan Evans
f9946083dd Video transcoding. 2019-07-30 14:09:33 -04:00
Greyson Parrelli
453f93a84f Bump version to 4.44.7 2019-07-28 10:20:38 -04:00
Greyson Parrelli
a8c47b5091 Guard media reads with a permissions check. 2019-07-28 10:20:04 -04:00
Greyson Parrelli
78a818eba6 Bump version to 4.44.6 2019-07-28 10:05:58 -04:00
Greyson Parrelli
4ca90374b9 Fix bug displaying an empty camera contacts search result. 2019-07-28 10:05:22 -04:00
Greyson Parrelli
a5fbcffa14 Bump version to 4.44.5 2019-07-26 15:38:10 -04:00
Greyson Parrelli
a21ec2f166 Updated language translations. 2019-07-26 15:37:39 -04:00
Greyson Parrelli
cdfb88ea18 Some tweaks to the camera FAB. 2019-07-26 15:29:44 -04:00
Greyson Parrelli
1ec45fe364 Fix bug where search wasn't focused in contact select.
Introduced in c0a44c7fc3.
Apparently targetSdk 28 changed the view focus model.
We have to manually focus this particular view now.
2019-07-26 15:06:09 -04:00
Greyson Parrelli
60b5c82da8 Bump version to 4.44.4 2019-07-25 11:29:03 -04:00
Greyson Parrelli
f0af5743c4 Updated language translations. 2019-07-25 11:25:57 -04:00
Alan Evans
81930a6833 Fix push challenge, Event bus needs public. 2019-07-25 11:19:21 -04:00
Greyson Parrelli
278ee79df0 Update camera-first contact display. 2019-07-25 10:10:32 -04:00
Greyson Parrelli
7f2a758400 Require contacts permission for camera-first flow.
Fixes #8950
2019-07-25 10:04:03 -04:00
Greyson Parrelli
fc1c092cf0 Bump version to 4.44.3 2019-07-24 19:31:52 -04:00
Greyson Parrelli
f42a8cf962 Updated language translations. 2019-07-24 19:31:52 -04:00
Greyson Parrelli
27db9d06e4 Ensure media folder title is not null.
Fixes #8949
2019-07-24 19:31:52 -04:00
Greyson Parrelli
3d5cfb3c74 Remove some dead code. 2019-07-24 19:24:21 -04:00
Greyson Parrelli
df9186827c Fix some UI issues with view-once photo receive. 2019-07-24 19:24:16 -04:00
Greyson Parrelli
e0137706b2 Bump version to 4.44.2 2019-07-24 11:25:01 -04:00
Greyson Parrelli
99bcda8709 Updated language translations. 2019-07-24 11:25:01 -04:00
Greyson Parrelli
eddff07eb8 Fix TimedEventManager crash in a sane way.
Follow up on acb48752c.

Just have the subclass call that method to guarantee that everything is
initialized.
2019-07-24 11:24:52 -04:00
Greyson Parrelli
4e859a84ce UI tweaks in the media send flow. 2019-07-24 11:04:21 -04:00
Greyson Parrelli
8665dad867 Prevent clicks from passing through media rail. 2019-07-23 10:48:23 -04:00
Greyson Parrelli
c0996ed116 Bump version to 4.44.1 2019-07-23 09:48:16 -04:00
Greyson Parrelli
830e651fef Updated language translations. 2019-07-23 09:39:15 -04:00
Greyson Parrelli
acb48752ce Fix possible crash in RevealableMessageManager.
The crash happened because #getNextClosestEvent was called when
mmsDatabase was null, which would normally be impossible. However, it
seems implied that somehow #getNextClosestEvent was being called in the
parent constructor before the child class was fully initialized. That
would imply that the looper was called synchronously in some freak
scenario, but it's the only explanation. So I added a delay to the call
in the parent constructor.

```java
java.lang.NullPointerException:
  at org.thoughtcrime.securesms.revealable.RevealableMessageManager.getNextClosestEvent (RevealableMessageManager.java:40)
  at org.thoughtcrime.securesms.revealable.RevealableMessageManager.getNextClosestEvent (RevealableMessageManager.java:23)
  at org.thoughtcrime.securesms.service.TimedEventManager.lambda$scheduleIfNecessary$1 (TimedEventManager.java:44)
  at org.thoughtcrime.securesms.service.-$$Lambda$TimedEventManager$kZDO3F2WBQVtGx-SkAgEDt8jCeU.run (Unknown Source:2)
  at android.os.Handler.handleCallback (Handler.java:873)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:193)
  at android.os.HandlerThread.run (HandlerThread.java:65)
```
2019-07-23 09:39:15 -04:00
Greyson Parrelli
ba8597900a Fix NPE in MediaSendActivity. 2019-07-23 09:39:15 -04:00
Alan Evans
c1f0253aa3 Resolve MissingSuperCall lint. 2019-07-23 09:35:23 -04:00
Alan Evans
d70d82c5ea Make fragments public.
Fixes #8940
2019-07-23 08:56:07 -04:00
Greyson Parrelli
29b9d3f902 Fix crash when viewing "inbox zero" state. 2019-07-23 08:50:27 -04:00
Greyson Parrelli
1a85a9cb31 Fix media send HUD consistency issue.
Only affects people who have force-enabled revealable messages and then
gone back to a build that doesn't have it enabled.
2019-07-23 08:50:20 -04:00
Greyson Parrelli
ead6e6b2f3 Bump version to 4.44.0 2019-07-22 23:33:54 -04:00
Alan Evans
03b1eb4bd5 Prevent attempting to send push media messages to non-phone addresses.
Prevents crash loop in #8910
2019-07-22 23:16:01 -04:00
Greyson Parrelli
5c870ca8ea Prevent sending revealable messages in Note to Self.
Send support isn't enabled yet, but didn't want to forget about it.
2019-07-22 23:16:01 -04:00
Greyson Parrelli
965de16de1 Fix possible hangup with CellServiceConstraint.
On phones with no SIM card, if you manage to enqueue a job with a
CellServiceConstraint, the previous check we were using to check if
there was cell service could hang indefinitely on some devices.

This changes it to a fast check, which all constraints should be.
2019-07-22 23:16:01 -04:00
Greyson Parrelli
a210ef3136 Added ability to save image captures to external storage. 2019-07-22 23:16:01 -04:00
Greyson Parrelli
beaa86389d Implement camera-first capture flow.
This allows you to take a photo, then choose the recipients after. This
also makes it so we only upload the attachment once.
2019-07-22 23:15:50 -04:00
Greyson Parrelli
4fbb87b5b7 Created a new SectionedRecyclerViewAdapter. 2019-07-22 20:55:31 -04:00
Sebastian Kürten
76d1382d9a Fix some Javadoc typos 2019-07-22 20:55:31 -04:00
Alan Evans
79a142c1be Refactor media preview to use fragments. 2019-07-22 20:55:26 -04:00
Greyson Parrelli
dd66e22443 Ensure that camera captures have correct dimensions. 2019-07-18 16:10:59 -04:00
Greyson Parrelli
c77809fa90 Add support for view-once messages. 2019-07-18 16:10:10 -04:00
Greyson Parrelli
9f7bb69341 Update the media send flow with a persistent rail. 2019-07-18 11:04:14 -04:00
Alan Evans
b58faf4fd1 Change settings transitions. 2019-07-18 10:29:27 -04:00
Alan Evans
dbeb2b5330 Fix play button in RTL layouts. 2019-07-18 10:08:08 -04:00
Alan Evans
9574a19ec2 Signal service update 2.13.6.
Fixes #8901
2019-07-18 10:06:44 -04:00
Greyson Parrelli
73bb7873e1 Log FCM notification delay. 2019-07-17 17:07:32 -04:00
Greyson Parrelli
475c54213d Move from dagger to a service locator pattern. 2019-07-17 16:12:53 -04:00
Alan Evans
8d6f1341f1 Reduce resolution of image editor preview and make memory efficiencies.
Fixes #8929
2019-07-17 15:05:19 -04:00
Alan Evans
80d0ba31ca Specify locale in some String.formats. 2019-07-17 14:07:39 -04:00
Alan Evans
c7bfede74c Do not use Canvas size. 2019-07-17 14:07:20 -04:00
Greyson Parrelli
c902d17f98 Remove additional log information that is not necessary for debugging purposes. 2019-07-16 19:24:51 -04:00
Greyson Parrelli
6c31d656dd Fix queueKey for SmsSendJob. 2019-07-16 19:19:56 -04:00
Greyson Parrelli
34e8d5ac57 Ignore whitespace when determining if we show jumbomoji. 2019-07-15 16:02:51 -04:00
Greyson Parrelli
d636f37132 Updated Emoji icons. 2019-07-12 13:25:36 -04:00
Curt Brune
150a21bfa3 Update to WebRTC M75 2019-07-11 10:25:07 -04:00
Alan Evans
5b61c8ac18 Request a push challenge and supply to SMS and voice verification. 2019-07-10 16:59:08 -04:00
Alan Evans
d72d4c4c41 Update libsignal to 2.13.5 2019-07-10 15:19:23 -04:00
Greyson Parrelli
5a1464c069 Remove pending messages notification. 2019-07-10 14:38:28 -04:00
Greyson Parrelli
c2ec09f079 Remove AttachmentServer. 2019-07-03 19:04:17 -04:00
Greyson Parrelli
8a8817f8d3 Remove video player usage of AttachmentServer. 2019-07-03 19:04:17 -04:00
Greyson Parrelli
a5368b7ea9 Remove audio player usage of AttachmentServer.
Now that we use ExoPlayer, it's no longer needed.
2019-07-03 19:04:17 -04:00
Greyson Parrelli
d8a75d599d Update emoji. 2019-07-03 19:04:17 -04:00
Greyson Parrelli
f92e2bae4a Bump version to 4.43.8 2019-07-03 12:14:28 -04:00
Greyson Parrelli
19d15cb3e5 Updated language translations. 2019-07-03 12:14:28 -04:00
Greyson Parrelli
b66e0e7e32 Fix incorrect EditorModel being restored. 2019-07-03 11:51:22 -04:00
Alan Evans
4a1f39f4be Drop shadow below conversation title bar. 2019-07-03 11:41:13 -04:00
Greyson Parrelli
a17d3e1b47 Bump version to 4.43.7 2019-07-02 18:08:03 -04:00
Greyson Parrelli
f580128366 Fix camera crash on API 21. 2019-07-02 18:07:13 -04:00
Greyson Parrelli
18252712a5 Bump version to 4.43.6 2019-07-02 10:18:44 -04:00
Greyson Parrelli
ed5f5adc9b Prevented avatar read failures from crashing.
There are a handful of devices that refuse to use our AesGcmProvider,
and as a result they would crash with AssertionErrors when downloading
avatars. Still haven't found why, but for now, probably best to stop
these devices from crashing, since it puts them in a crash loop, and the
app is still usable without avatars.
2019-07-02 10:06:20 -04:00
Greyson Parrelli
4c30aa9f13 Fixed crash when setting your profile picture.
The version of the cropping library we were using had a targetSdk 28 bug
in it. Updating to the newest version fixes the problem.
2019-07-02 10:05:23 -04:00
Greyson Parrelli
3cdf17ccaa Bump version to 4.43.5 2019-07-01 17:15:46 -04:00
Greyson Parrelli
a8dbfd812d Fix issue with bad camera quality on some devices.
There appears to be a weird bucketing thing that happens on some
devices, where if you give them a resolution that's too small, it'll
default you to some potato resolution. So we just bumped it up to
1920x1920, and that seems to be working on my swath of devices.
2019-07-01 17:15:14 -04:00
Greyson Parrelli
ff3890cc12 Name threads more consistently. 2019-07-01 17:15:04 -04:00
Greyson Parrelli
9c196bd2d5 Fix issue where an empty file could be read forever.
If you gave the class an empty file, it would get back -1 for read(),
causing it to fall forever into negative values, never escaping the
existing conditions.

The side effect of this was weird corner cases where these infinite
reads could clog up threads, causing audio recordings to get blocked
and such.

Fixes #8898
2019-07-01 17:15:01 -04:00
Greyson Parrelli
4508aa7c35 Clean up logging. 2019-07-01 15:12:34 -04:00
Greyson Parrelli
f15a629731 Bump version to 4.43.4 2019-06-30 09:43:32 -04:00
Greyson Parrelli
857fda42c8 Fix audio playback on API 28 devices. 2019-06-30 09:41:58 -04:00
Greyson Parrelli
a5eb823a17 Avoid crash with Address parcelable.
There seems to be a bad implementation of Address parcelization that
pops up in certain scenarios. We can avoid it by just excluding it
from the parcel altogether.
2019-06-30 09:26:08 -04:00
Greyson Parrelli
31435128f4 Bump version to 4.43.3 2019-06-30 01:10:50 -04:00
Greyson Parrelli
6656077edc Updated language translations. 2019-06-30 01:10:34 -04:00
Greyson Parrelli
9974f6edf1 Correctly retrict BucketInfo API level. 2019-06-30 00:54:51 -04:00
Greyson Parrelli
6715a89a25 Disable default CameraX initializer.
CameraX was initializing Camera2 API stuff on API < 21, causing
crashes at boot. To handle this, we disable the default
ContentProvider initializer and initialize things ourselves for
appropriate API levels.
2019-06-30 00:54:42 -04:00
Greyson Parrelli
23b4a9b191 Bump version to 4.43.2 2019-06-28 19:17:35 -04:00
Greyson Parrelli
666cdeae6b Change compileSdk back to 28. 2019-06-28 19:16:27 -04:00
Greyson Parrelli
5d7ac81c4b Bump version to 4.43.1 2019-06-28 18:57:34 -04:00
Greyson Parrelli
93856ed8cf Fix some bookkeeping in CameraXFragment. 2019-06-28 18:57:04 -04:00
Greyson Parrelli
84fd1a9140 Bump version to 4.43.0 2019-06-28 18:39:32 -04:00
Greyson Parrelli
9949e5e3a5 Updated language translations. 2019-06-28 18:39:20 -04:00
Alan Evans
c0a44c7fc3 Target API 28. 2019-06-27 16:18:53 -04:00
Alan Evans
d9df1ec39e Preparing to target API 28. 2019-06-27 16:18:53 -04:00
Greyson Parrelli
abcd599ad8 Support Android Q call notifications. 2019-06-27 15:46:13 -04:00
Greyson Parrelli
8a3d0dde91 Bump compileSdk to 29. 2019-06-27 15:46:13 -04:00
Alan Evans
0f3de6c979 Check action mode is still valid.
Due to support library bug, onActionItemClicked can be called after finish/onDestroyActionMode so we can check for that by checking if our reference to the action mode is still valid.

Fixes #8891
2019-06-27 15:44:05 -04:00
Alan Evans
c089d6cd43 Allow multiple messages on the Generic Foreground Service. Show the oldest still active. 2019-06-27 12:18:52 -04:00
Alan Evans
cfcb9a8cdb Custom place picker to replace places SDK. 2019-06-27 12:14:54 -04:00
Matthias Riedl
83479d11b7 White text on dark theme pin input.
Fixed #7509
2019-06-27 11:28:59 -04:00
Greyson Parrelli
73b8f11b5a Improve camera capture with CameraX. 2019-06-26 18:11:49 -04:00
Greyson Parrelli
4593014d00 Bump version to 4.42.3 2019-06-24 12:55:02 -04:00
Greyson Parrelli
2cf5d57454 Updated language translations. 2019-06-24 12:54:37 -04:00
Greyson Parrelli
048d859881 Handle missing profile photos better.
There were a couple funny behaviors you could run into if you had a
contact that previously had a profile photo, but then removed it.
2019-06-24 12:36:05 -04:00
Greyson Parrelli
1df28c6564 Bump version to 4.42.2 2019-06-20 09:35:20 -04:00
Greyson Parrelli
f59e937006 Updated language translations. 2019-06-20 09:34:38 -04:00
Greyson Parrelli
5948b46ac7 Fix crash in AvatarImageView. 2019-06-20 09:27:58 -04:00
Greyson Parrelli
75b232bfdc Bump version to 4.42.1 2019-06-19 13:01:58 -04:00
Greyson Parrelli
9e6594cc0b Updated language translations. 2019-06-19 12:56:56 -04:00
Greyson Parrelli
7f85b61e89 Serialize RotateSignedPreKeyJob. 2019-06-19 12:56:56 -04:00
Alan Evans
1a32bc8232 Fix flickering avatar. 2019-06-19 12:29:15 -04:00
Greyson Parrelli
e603162ee7 Bump version to 4.42.0 2019-06-17 13:51:16 -04:00
Greyson Parrelli
08eca5d844 Updated language translations. 2019-06-17 13:51:16 -04:00
Greyson Parrelli
1d1dbcf9cd Fix RecyclerView lint errors. 2019-06-17 13:51:16 -04:00
Alan Evans
e6b107fa78 Add a content description for the inline add attachment button.
Fixes #8730
2019-06-17 13:51:16 -04:00
Alan Evans
284cca3e25 Prevent reply and mark as read abilities while Signal is locked.
Fixes #8874
2019-06-17 13:51:16 -04:00
Greyson Parrelli
1e0b0d926a Update libsignal to 2.13.4 2019-06-17 13:51:16 -04:00
Alan Evans
cb86be578b Handle accented characters in country name sorting.
Closes #8419
2019-06-17 13:51:16 -04:00
Alan Evans
b8bb2b78bd Query total memory just once.
Closes #8315
2019-06-17 13:51:16 -04:00
Alan Evans
6fceb25121 Take typing indicator into account when moving to quoted message.
Fixes #8858

And fixes same bug in search.
2019-06-17 13:51:16 -04:00
Alan Evans
0484047b4e Fix avatar removal. 2019-06-17 13:51:16 -04:00
Alan Evans
b9a10653f1 Image Editor - Multi-line text.
* Two pass rendering for text on top while editing.
2019-06-17 13:51:16 -04:00
Alan Evans
42a5504f0d Do not attempt to retrieve a profile when it is not a number.
Fixes #8855
2019-06-17 13:51:16 -04:00
Alan Evans
ae784db80d Video is initially disabled.
Fixes #8867
2019-06-17 12:52:42 -04:00
Alan Evans
f5cbf64ccf Fix initial visibility of scroll to bottom button.
Fixes #8862
2019-06-17 12:52:42 -04:00
Alan Evans
cecf16c595 Do not show contact address in subtitle. 2019-06-17 12:52:42 -04:00
Greyson Parrelli
fb4c9d3bf1 Improve message download reliability. 2019-06-17 12:52:43 -04:00
Greyson Parrelli
b5aa46bb67 Convert to AndroidX. 2019-06-17 12:52:42 -04:00
Greyson Parrelli
2dc68ed053 Switch from compile to implementation. 2019-06-17 12:52:42 -04:00
Greyson Parrelli
58d818923d Convert /res folder to webp.
Used lossless.
2019-06-17 12:52:42 -04:00
Greyson Parrelli
f4a6cd9c68 Convert emoji to webp.
Used lossy at 99% quality. No perceivable degredation at max font size,
but a pretty big improvement in size over lossless.
2019-06-17 12:52:42 -04:00
Greyson Parrelli
ed04535537 Convert image editor stickers to webp.
Used lossless.
2019-06-17 12:52:42 -04:00
Greyson Parrelli
7d4de3d4cb Removed some unused resources. 2019-06-17 12:52:42 -04:00
Greyson Parrelli
bc7cc306cb Bump version code to 4.41.6 2019-06-11 01:52:52 -04:00
Greyson Parrelli
5fa07e7094 Improve network reliability. 2019-06-11 01:51:46 -04:00
Greyson Parrelli
2b069fa63f Bump version to 4.41.5 2019-06-07 16:53:48 -04:00
Greyson Parrelli
99848f98d3 Sanitize sticker URL inputs. 2019-06-07 16:08:33 -04:00
Greyson Parrelli
967e9dd9a7 Disable sticker pack sharing. 2019-06-07 16:08:29 -04:00
Greyson Parrelli
4a720289e2 Bump version to 4.41.4 2019-06-06 10:56:52 -04:00
Greyson Parrelli
86d58e97cf Updated language translations. 2019-06-06 10:56:04 -04:00
Greyson Parrelli
bc6b7d15f1 Fix number formatting issue. 2019-06-06 10:41:37 -04:00
Greyson Parrelli
37f3b1f1ba Bump version to 4.41.3 2019-06-04 03:35:14 -04:00
Greyson Parrelli
262012887c Revert "Do not show contact address in subtitle."
This reverts commit dae0d30367.
2019-06-04 03:30:24 -04:00
Greyson Parrelli
d2cb6098fc Bump version to 4.41.2 2019-06-03 18:58:38 -04:00
Greyson Parrelli
1973fbf376 Fix programmatic VectorDrawable references.
Have to be careful with pre-21 devices. You have to use specific
compat loading methods with VectorDrawables or it'll crash.
2019-06-03 18:53:18 -04:00
Greyson Parrelli
bd63b9bec9 Updated language translations. 2019-06-03 14:50:15 -04:00
Greyson Parrelli
faa8c78f8d Clean up string for translators. 2019-06-03 14:46:51 -04:00
Greyson Parrelli
923016f12c Fix backup restore crash.
Fixes #8011
2019-06-03 14:06:55 -04:00
Greyson Parrelli
f469ce049d Bump version to 4.41.1 2019-05-30 20:22:54 -04:00
Greyson Parrelli
922f6d89e9 Render placeholders for unsupported messages. 2019-05-30 20:18:53 -04:00
Greyson Parrelli
4741a76f37 Add support for isRecipientUpdate flag. 2019-05-30 20:16:14 -04:00
Alan Evans
d197c57c55 Gradle witness - Do not hide resolution errors. 2019-05-30 20:22:03 -03:00
Greyson Parrelli
4ee60bf867 Fix bug where you couldn't forward albums. 2019-05-30 16:17:45 -04:00
Alan Evans
4351578838 Darker nav bar. 2019-05-30 17:11:56 -03:00
Greyson Parrelli
56c17e32f1 Bump version to 4.41.0 2019-05-30 01:17:07 -04:00
Alan Evans
48698381fc Dark theme navigation bar.
Fixes #8758
2019-05-30 01:10:10 -04:00
Alan Evans
5ad02f724c Enable 64-bit.
* Multiply version codes by 10 and add a code for each abi in order to generate different version codes for the play store.
2019-05-30 01:08:01 -04:00
Alan Evans
132c81b142 Bring Gradle Witness into repo.
- Api/Implementation compatible.
- Regex configuration name.
2019-05-30 01:08:01 -04:00
Greyson Parrelli
77e3cc40e0 Fix message bubble sizing with link previews and quotes.
Previously, quotes could extend beyond the width of the link preview
banner image. Now quotes will be constrained to the size of the link
preview banner image.
2019-05-30 01:08:01 -04:00
Greyson Parrelli
2a644437fb Add sticker support.
No sticker packs are available for use yet, but we now have the
latent ability to send and receive.
2019-05-30 01:08:01 -04:00
Alan Evans
d5fffb0132 Fix conversation menu colors. 2019-05-28 17:36:07 -03:00
Alan Evans
c8c152fe60 Lint - baseline of errors.
* qa task calls lint.
2019-05-28 17:36:07 -03:00
Alan Evans
350d1f47d3 Give conversation a standard navigate up button.
* Prevent a failing IDE preview.
2019-05-28 17:36:07 -03:00
Alan Evans
2ae42cb095 Hide local video when toggled on and off.
Fixes #8827
2019-05-28 17:36:07 -03:00
Alan Evans
dae0d30367 Do not show contact address in subtitle. 2019-05-23 16:57:50 -03:00
Alan Evans
e5f70bdbda End RTC call on incoming PSTN call.
* Hangs up when new device call is answered.
* Ensure not on a device call when starting a Signal call.
2019-05-23 16:56:05 -03:00
Alan Evans
156fe37a60 Get SubscriptionManager by name due to ContextCompat bug for API 22.
Fixes #8826
2019-05-23 11:38:24 -03:00
Alan Evans
56848fb83d Replace sgnl.link urls with a more readable url.
* Taken out random string, reverted to single "Let's switch".

#8767
2019-05-23 08:02:15 -03:00
Alan Evans
3cba8ab58a Keep system default SIM as a fallback for when no conversation default SIM.
Fixes #8452
2019-05-22 16:59:00 -03:00
Alan Evans
88dac70087 Lint - Custom Widgets extend Appcompat Widgets. 2019-05-22 14:02:21 -03:00
Alan Evans
9445555d66 Code analysis - address @NotNull/@Nullable issues. 2019-05-22 13:51:56 -03:00
Alan Evans
7db1588578 Do not assume phone number in conversation.
Fixes #8813
2019-05-22 13:30:27 -03:00
Alan Evans
0a7970ad0c Image Editor - Allow undoing back to the original state when exceeds the undo limit. 2019-05-22 13:28:02 -03:00
Alan Evans
10ad3fbf82 Lint - Use easily identifiable wake lock tags. 2019-05-20 13:24:34 -03:00
Alan Evans
95858898d7 Lint - avoid calling a restricted API. 2019-05-20 13:24:33 -03:00
Alan Evans
16c8cc88d7 Update visibility and icon of camera flip control in call.
Fixes #8221
2019-05-20 13:24:33 -03:00
Greyson Parrelli
c0c051bb66 Bump version to 4.40.4 2019-05-20 08:31:47 -07:00
Greyson Parrelli
bd0d1e842f Updated language translations. 2019-05-20 08:28:28 -07:00
Alan Evans
7f0c998b24 Image Editor - Further crop improvements.
* Thumb accuracy improved.
* When out of bounds from drag, try to fix by adjusting translation.
* Update undo state when listener changes.
2019-05-20 12:02:40 -03:00
Greyson Parrelli
5a4c2fc7b0 Bump version to 4.40.3 2019-05-17 15:56:50 -07:00
Alan Evans
456ba5fa02 Image Editor - Replace minimum scale, with minimum pixel count.
- Anti alias images.
- Minimum crop ratio of 15:1 or original image ratio.
2019-05-17 19:42:12 -03:00
Alan Evans
9de420fde6 Image Editor - On flip or rotate, ensure undo button visibility is updated. 2019-05-17 19:00:10 -03:00
Alan Evans
401e3687de Image Editor - when no sticker selected, go back to mode NONE. 2019-05-17 16:22:07 -03:00
Alan Evans
6777b3e0e6 Image Editor - Undo button visibility. 2019-05-17 16:15:27 -03:00
Greyson Parrelli
b5d37702f9 Switch back to the classic handling of landscape text entry.
Fixes #8814
2019-05-17 12:14:14 -07:00
Greyson Parrelli
320ea9eb4e Bump version to 4.40.2 2019-05-16 16:23:19 -07:00
Greyson Parrelli
86d8cde9b4 Updated language translations. 2019-05-16 16:22:32 -07:00
Alan Evans
bf759711ef Image Editor - Keep image within crop bounds.
* 4% of original pixels must be visible.
* The entire crop must be within the image.
* On release, try to scale crop area and image to fit if the crop is invalid.
* Undo to last valid position if that didn't work.
* Additionally, center thumbs now do not respect aspect ratio lock.
2019-05-16 15:52:15 -07:00
Alan Evans
068ffc2167 Image Editor - Allow undoing during croping. 2019-05-16 15:52:03 -07:00
Alan Evans
95304fe001 Image Editor - Remove initial text.
- Flashing cursor.
2019-05-16 15:51:56 -07:00
Alan Evans
2de64fca02 Image Editor - Fix double HUD animation on older devices. 2019-05-16 15:51:41 -07:00
Greyson Parrelli
3211dd2a8f Ignore resources.arsc in apkdiff.py
Due to a bug described in:

https://issuetracker.google.com/issues/110237303

Ordering of resources can be non-deterministic.

A comment on the issue indicates that this may be resolved in
Android Gradle Plugin 3.4. We should revisit when we update.
2019-05-11 10:46:25 -07:00
Peter Gerber
b6dc25a368 Reproducible build: Ensure apkdiff.py works properly again
The recent switch to Python3 (2ccdf0e396) introduced a regression
that led to file content no longer being compared:

   In compareEntries(), two generators/iterators are created:

     sourceInfoList      = filter(lambda sourceInfo: …, sourceZip.infolist())
     destinationInfoList = filter(lambda destinationInfo: …, destinationZip.infolist())

   Few lines later, those are exhausted:

     if len(sourceInfoList) != len(destinationInfoList):

   Yet another few lines later, the exhausted generator is used again:

     for sourceEntryInfo in sourceInfoList:
        …          # <-- unreachable

This is caused by behavioral differences between Python2 and Python3:

   user@z_signal:~$ python2
   Python 2.7.13 (default, Sep 26 2018, 18:42:22)
   [GCC 6.3.0 20170516] on linux2
   Type "help", "copyright", "credits" or "license" for more information.
   >>> f = filter(lambda i: i % 2 == 0, [0, 1, 2, 3, 4, 5, 6])
   >>> list(f)
   [0, 2, 4, 6]
   >>> list(f)
   [0, 2, 4, 6]
   >>>

   user@z_signal:~$ python3
   Python 3.5.3 (default, Sep 27 2018, 17:25:39)
   [GCC 6.3.0 20170516] on linux
   Type "help", "copyright", "credits" or "license" for more information.
   >>> f = filter(lambda i: i % 2 == 0, [0, 1, 2, 3, 4, 5, 6])
   >>> list(f)
   [0, 2, 4, 6]
   >>> list(f)
   []
   >>>
2019-05-11 10:43:51 -07:00
Greyson Parrelli
4e64242883 Bump version to 4.40.1 2019-05-10 13:08:49 -07:00
Greyson Parrelli
fcd3b501eb Revert "Enable 64-bit."
This reverts commit 67704612df.
2019-05-10 13:01:34 -07:00
Greyson Parrelli
62ed098687 Bump version to 4.40.0 2019-05-10 09:35:11 -07:00
Greyson Parrelli
2a93ddfb99 Updated language translations. 2019-05-10 09:19:39 -07:00
Alan Evans
387392f38b End align footer for long message bubble sent.
Fixes #8806
2019-05-10 12:41:15 -03:00
Alan Evans
5b298b4a04 Resize image in attempts to get it to fit into the maxImageSize bytes.
Fixes #8803
2019-05-10 12:16:19 -03:00
Alan Evans
cb78684282 Ensure push groups cannot have isForceSmsSelection set.
Fixes #8807
2019-05-10 12:13:59 -03:00
Alan Evans
67704612df Enable 64-bit. 2019-05-10 12:03:45 -03:00
Alan Evans
f3c8b51520 Web RTC M74 for 64-bit. 2019-05-10 12:03:16 -03:00
Alan Evans
b1057d63a1 Lint.
- Check for permissions.
- Fix Welsh positional format.
- Remove UIThread restriction.
- Asynchronous method does not need to be restricted to UIThread and there is no StaticFieldLeak to suppress.
- Fix or Ignore New API errors.
- Reduce severity of some errors from L10N.
2019-05-10 11:57:43 -03:00
Alan Evans
2ccdf0e396 Bring the Reproducible Builds instructions and script into repo. 2019-05-10 11:57:43 -03:00
Alan Evans
93e6ccb9e4 Replace image editor. 2019-05-10 11:57:43 -03:00
Alan Evans
196ef60a82 Update camera icons. 2019-05-09 14:38:28 -03:00
Alan Evans
478e5667b4 Update signal-service-android to 2.13.1 for 64-bit curve-25519. 2019-05-09 14:38:28 -03:00
Alan Evans
06ea000f42 Repeat count for format args of plural string.
Fixes #8724
2019-05-07 12:26:01 -03:00
Alan Evans
d1b8e77fdc Always show the SIM on the footer of a multi-SIM device, even if one SIM is disabled. 2019-05-07 12:25:11 -03:00
Alan Evans
8cf2654c5b Show reply method SMS/Signal and respect sticky.
Fixes #8792
2019-05-06 16:45:30 -07:00
Alan Evans
18531146f7 Update the sticky EventBus message to reflect changes in microphone enabled state.
Fixes #7827
2019-05-06 16:45:30 -07:00
Jeffrey Griffin
c274c1bb28 Eliminate noisy directory feedback
We observed IOExceptions loading the Contact Discovery IAS KeyStore. We will now throw an AssertionError upon any error
creating the IAS KeyStore, matching the behaviour for creation of the TrustStore used for the main Signal Service. NB: If
this assertion is hit, the user will not even be able to refresh their contacts with the old directory service.
2019-05-06 16:45:30 -07:00
Alan Evans
42a8522e98 Manually call the onPageSelected when entering page 0.
Fixes #7610
2019-05-06 16:45:30 -07:00
Greyson Parrelli
960e165c7d Bump version to 4.39.4 2019-05-06 15:51:10 -07:00
Greyson Parrelli
eab23a9e66 Fixed issue where giphy results weren't loading. 2019-05-06 15:48:43 -07:00
Greyson Parrelli
c7b626082c Bump version to 4.39.3 2019-05-06 12:31:59 -07:00
Greyson Parrelli
59f362495a Add additional checks around link preview domains.
We never make requests to non-whitelisted domains, but there were
situations where some links would redirect to non-whitelisted domains,
which would hit a final failsafe that resulted in a crash.

To prevent this, we detect bad redirects earlier and fail more
gracefully.

Fixes #8796
2019-05-06 12:25:53 -07:00
Greyson Parrelli
6c44437c6f Bump version to 4.39.2 2019-05-02 15:38:25 -07:00
Greyson Parrelli
fed8ae68e9 Updated language translations. 2019-05-02 15:32:44 -07:00
Greyson Parrelli
934a2a67bc Fix some keyboard issues in landscape. 2019-05-02 14:32:53 -07:00
Greyson Parrelli
05345b8582 Remove some unnecessary logging. 2019-05-02 14:32:53 -07:00
Greyson Parrelli
cef5de2be4 Removed unnecessary WorkManager relic. 2019-05-02 14:32:53 -07:00
Greyson Parrelli
7b4299d5da Bring back conscrypt, improve provider initialization ordering. 2019-05-02 14:32:48 -07:00
Alan Evans
ec20b0e0e3 Fallback to SIM index.
#8725
2019-05-02 18:16:59 -03:00
Greyson Parrelli
ff1531b836 Bump version to 4.39.1 2019-05-01 08:42:49 -07:00
Greyson Parrelli
1675c8a79a Updated language translations. 2019-05-01 08:42:44 -07:00
Greyson Parrelli
bb90987e7c Fix potential crash when retrieving SIM list. 2019-05-01 08:36:24 -07:00
Greyson Parrelli
ecea6abeb6 Temporary revert (again) to fix an avatar retrieval issue.
This reverts commit 77524ae1f2.
2019-05-01 08:25:14 -07:00
Greyson Parrelli
4a2f3136c6 Bump version to 4.39.0 2019-04-30 12:51:58 -07:00
Greyson Parrelli
d12b02fac5 Updated language translations. 2019-04-30 12:51:58 -07:00
Greyson Parrelli
1e564b6ad1 Fix exponential backoff retry limits. 2019-04-30 12:51:58 -07:00
Alan Evans
c77daa8226 Display carrier or number if any SIM descriptions clash.
Fixes #8725
2019-04-30 12:51:58 -07:00
Alan Evans
fa35814344 Disable transport disables all matching TransportOptions.
Fixes #8744
2019-04-30 12:51:58 -07:00
Alan Evans
48efcaa785 Do not list SIMs that are not ready.
Fixes #8426
2019-04-30 12:51:58 -07:00
Greyson Parrelli
f3f6cc87d9 Request a small chunk instead of HEAD for images of unknown size. 2019-04-30 12:51:58 -07:00
Greyson Parrelli
29cdb5290b Make headers for giphy requests random sizes. 2019-04-30 12:51:58 -07:00
Greyson Parrelli
77524ae1f2 Revert "Temporary revert to fix an avatar retrieval issue."
This reverts commit 267bc32e23.
2019-04-30 12:51:58 -07:00
Greyson Parrelli
30ba9d7e27 Improve CDN reliability. 2019-04-30 12:51:58 -07:00
Alan Evans
9652fd2844 Update MMS configs. 2019-04-30 12:51:58 -07:00
Francois Blackburn
d2ece1c1f2 Add MI 5 to hardware AEC blacklist 2019-04-30 12:51:57 -07:00
Arnt Gulbrandsen
8bdc257963 Avoid hardware echo cancellation for Fairphone FP2
The issue has as been confirmed by me with the stock ROM as of November
2018, and other users have complained for almost 18 months, see
https://forum.fairphone.com/t/fnord/28849 and
https://bugtracker.fairphone.com/project/fairphone-fairphone-os-android-6/issue/77
2019-04-30 12:51:57 -07:00
Kevin Mark
88f9ec313f Close SQL statement, preventing finalizer crashes
This will stop instances of the following from occuring in the logs
on SMS migration:

W/SQLiteCompiledSql: Releasing statement in a finalizer. Please ensure
that you explicitly call close() on your cursor: INSERT INTO sms
(address, person, date_sent, date, protocol, read, status, type,
reply_path_present,
    net.sqlcipher.database.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
        at net.sqlcipher.database.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:62)
        at net.sqlcipher.database.SQLiteProgram.<init>(SQLiteProgram.java:109)
        at net.sqlcipher.database.SQLiteStatement.<init>(SQLiteStatement.java:39)
        at net.sqlcipher.database.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1647)
        at org.thoughtcrime.securesms.database.SmsDatabase.createInsertStatement(SmsDatabase.java:767)
        at org.thoughtcrime.securesms.database.SmsMigrator.migrateConversation(SmsMigrator.java:166)
        at org.thoughtcrime.securesms.database.SmsMigrator.migrateDatabase(SmsMigrator.java:210)
        at org.thoughtcrime.securesms.service.ApplicationMigrationService$ImportRunnable.run(ApplicationMigrationService.java:159)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)

We aren't closing Statement objects before the finalizer on those
objects runs. When the GC runs, we'll get warnings like the above
which alert us to the fact that these objects are being automatically
closed for us in the finalizer, but that this is suboptimal behavior.

If we leave too many Statement (or Cursor) objects to be closed in
their finalizers, when the GC runs, it'll take longer than 10 seconds
to close them all and Android will kill the app. This 10 second limit
is hardcoded and we can only try to avoid it. A crash will look like:

java.util.concurrent.TimeoutException: net.sqlcipher.database.SQLiteCompiledSql.finalize() timed out after 10 seconds
    at java.lang.Object.wait(Native Method)
    at java.lang.Thread.parkFor$(Thread.java:1220)
    at sun.misc.Unsafe.park(Unsafe.java:299)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:810)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:844)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1173)
    at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:196)
    at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:257)
    at net.sqlcipher.database.SQLiteDatabase.lock(SQLiteDatabase.java:553)
    at net.sqlcipher.database.SQLiteCompiledSql.releaseSqlStatement(SQLiteCompiledSql.java:106)
    at net.sqlcipher.database.SQLiteCompiledSql.finalize(SQLiteCompiledSql.java:152)
    at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:202)
    at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:185)
    at java.lang.Thread.run(Thread.java:818)

I was able to replicate the above crash consistently on a
Samsung Galaxy S7 edge when importing well over 100k SMS messages.
But as soon as I attached a debugger the crash did not persist. I
assume this is because of some VM-level interactions between the two
and did not investigate further after fixing it.

I do not have access to the stack trace for issue #7953 but this
could potentially resolve it. The crash is identical to that in #7477
but this patch is for SMS migration not restoring from a backup. I
was not able to replicate the crash on restoring a >100k message
backup.
2019-04-30 12:51:57 -07:00
Michael Walker
8ad5126408 Add pinterest domain and asset domains for link preview support 2019-04-30 12:51:57 -07:00
Greyson Parrelli
1e27847015 Update link preview meta tag regex. 2019-04-30 12:51:57 -07:00
Greyson Parrelli
e67eca77ff Prevent landscape text editing from taking over the screen.
It used to be that we let Android do the default behavior of
full-screening the EditText when in landscape, but honestly I
don't know who prefers that. So I've turned it off.

Fixes #8769
2019-04-30 12:51:52 -07:00
Greyson Parrelli
ba46a9d81a Bump version to 4.38.3 2019-04-28 11:44:23 -07:00
Greyson Parrelli
49cccc6927 Update job logging. 2019-04-28 11:44:17 -07:00
Greyson Parrelli
5977e9141d Wrap transactions in try-finally. 2019-04-28 11:42:02 -07:00
Greyson Parrelli
c0982293bf Fix bug where sticky SMS setting wasn't respected.
Fixes #8783
2019-04-28 11:34:56 -07:00
Greyson Parrelli
ae6ef62160 Bump version to 4.38.2 2019-04-16 10:56:59 -04:00
Greyson Parrelli
d95b08d4fd Updated language translations. 2019-04-16 10:51:25 -04:00
Greyson Parrelli
128da6db04 Fix crash in backup restore related to sqlite_sequence.
The new JobManager stuff created a table that had an
auto-incrementing ID, which was incorrectly being backed
up and restored, causing a crash. Now we skip it on both
import and export.
2019-04-16 10:10:02 -04:00
Greyson Parrelli
2701607810 Reduce the possible number of unique jobs to avoid crash.
Some devices have a limit of 100 unique JobScheduler jobs.
Previously we allowed up to 1,000. Given that we just need
_some_ job running, I lowered the limit to 75 to give us
some head room.
2019-04-16 09:52:12 -04:00
Greyson Parrelli
4055fe183b Bump version to 4.38.1 2019-04-15 15:45:16 -04:00
Greyson Parrelli
1c47812877 Fix crash when migrating read receipt jobs.
Fixes #8764
2019-04-15 15:45:16 -04:00
Greyson Parrelli
060bed8559 Bump version to 4.38.0 2019-04-15 10:59:38 -04:00
Greyson Parrelli
4a3c173adb Migrated to new JobManager. 2019-04-15 10:56:26 -04:00
Greyson Parrelli
8cf3ba424a Trim long text before displaying if necessary.
Fixes #8759
2019-04-15 10:13:35 -04:00
Alan Evans
9c40de5bf1 Save the SMS setting on a per-conversation basis. 2019-04-15 10:13:35 -04:00
Greyson Parrelli
11a2ed0743 Increase reliability of locally logging crashes.
Exception logging tends to be race-y, so now we block and wait
for all logs to be written before continuing with the crash.
2019-04-10 12:53:55 -04:00
Alan Evans
01a9931d92 Do not use background threads for download UI events. 2019-04-10 13:13:10 -03:00
Greyson Parrelli
38bcc6c293 Long text detail view now respects text size preference.
Fixes #8747
2019-04-09 09:40:32 -04:00
Greyson Parrelli
bceb9b4972 Fixed quotes not being cleared when forwarding.
Fixes #8748
Fixes #7935
2019-04-09 09:35:47 -04:00
Alan Evans
ecdc285378 Fix unresponsive button on image send with text in landscape.
Fixes #8575
Closes #8638

Co-authored-by: Jakub Gregorek <jg@inthemeadow.net>
2019-04-08 07:45:16 -03:00
Greyson Parrelli
6d111e5f68 Bump version to 4.37.2 2019-04-04 23:18:30 -04:00
Greyson Parrelli
9aed2343c1 Attempt to resolve connectivity problems for some users. 2019-04-04 18:10:41 -04:00
Greyson Parrelli
733d54e339 Linkify links in long message view.
Fixes #8735
2019-04-04 10:09:32 -04:00
Greyson Parrelli
267bc32e23 Temporary revert to fix an avatar retrieval issue.
This reverts commit 8aa185070b.
2019-04-03 16:32:52 -04:00
Greyson Parrelli
7acb4973d8 Bump version to 4.37.1 2019-04-01 17:29:26 -04:00
Alan Evans
39ba8c2ad3 Remove armeabi from splits. 2019-04-01 17:43:10 -03:00
Alan Evans
621ac62c7e Add red flashing voice note microphone. 2019-04-01 17:42:57 -03:00
Greyson Parrelli
652306edd0 Bump version to 4.37.0 2019-03-29 09:55:09 -07:00
Alan Evans
b9b4dccff4 ABI splits. 2019-03-28 17:21:57 -03:00
Alan Evans
ce6d2d9c69 MMS image quality.
Fixes #8590
- Scale image larger within the dimensions.
- Apply a minimum dimension of 1024.
2019-03-28 15:14:06 -03:00
Alan Evans
e842f78457 Voice Note Locking.
Limit of 60 minutes, after which it's cancelled.
2019-03-28 15:04:38 -03:00
Alan Evans
cab3657ab0 ABI info for device. 2019-03-26 17:29:08 -03:00
Alan Evans
a7aa980e58 New dynamic locale system.
- Fixes #7619
2019-03-26 17:08:05 -03:00
Alan Evans
6a0a419f0c Add self to MMS group.
- Fixes #7683
- Closes #8296
2019-03-26 17:07:04 -03:00
Greyson Parrelli
94e8303022 Remove dead code from ScribbleHud/Fragment. 2019-03-22 12:47:16 -07:00
Greyson Parrelli
ccfcfa71df Enable the sending of long messages. 2019-03-22 12:28:41 -07:00
Alan Evans
cfdcd61e51 Local build quality assurance task. 2019-03-21 11:19:07 -07:00
Greyson Parrelli
b89c20ff40 Switch to 'start' and 'end' instead of 'left' and 'right'.
We can do this now that our minSdk is 19.
2019-03-21 11:19:06 -07:00
Greyson Parrelli
8caaf057e8 Remove unnecessary pre-19 code branches.
Now that our minSdk is 19, we can remove a lot of old code paths that
only ran pre-19.
2019-03-21 11:19:06 -07:00
Moxie Marlinspike
a52c295a38 Simplify access to SecureRandom
This shouldn't matter at all, but it's more "correct," and shows
my age less.
2019-03-21 11:19:06 -07:00
Moxie Marlinspike
8aa185070b Update libsignalservice to 2.13.0
- Eliminate the explicit spongycastle dependency. All access to
  primitives is done through the JCE interfaces now, which allows
  us to use a secure native-backed provider like conscrypt.

- Use conscrypt for our default security provider. This gives us
  fast TLS 1.2 and 1.3 support on all devices, even before they
  had platform support (like 4.4).

- Update minSdk to 18. Unfortunately the JCE interfaces for GCM
  primitives are JDK 7+ (!) only, which became supported by Android
  at 18.
2019-03-21 11:19:06 -07:00
Alan Evans
de60d4d37f 64-bit native utils.
* Update Application.mk.
* 64-bit libnative-utils
* New build of x86 and armeabi-v7a libnative-utils.
* Update to API19.
2019-03-21 11:19:06 -07:00
Alan Evans
6e5658431b Remove armeabi. 2019-03-21 11:19:06 -07:00
Greyson Parrelli
6df5457305 Bump minSdk to 19. 2019-03-21 11:19:06 -07:00
Greyson Parrelli
fd50b38630 Bump version to 4.36.2 2019-03-21 11:02:12 -07:00
Alan Evans
d41b24f9ae Fix "multiple substitutions specified in non-positional format" lint. 2019-03-21 11:02:12 -07:00
Greyson Parrelli
aa5e32f0ee Add back the highlight and sticker tools. 2019-03-21 11:02:07 -07:00
Greyson Parrelli
749d096931 Updated language translations. 2019-03-21 09:57:12 -07:00
Greyson Parrelli
8e86c7d81a Fix media button visibility issue on older Android versions.
Turns out setVisibility doesn't work unless you call clearAnimation()
first on older Android versions. Isn't that grand?
2019-03-21 00:11:01 -07:00
Greyson Parrelli
148cfd1b53 Fix crash when single-selecting large media. 2019-03-20 23:01:32 -07:00
Greyson Parrelli
93c1277fd0 Fix voice note button clipping. 2019-03-20 22:25:19 -07:00
Greyson Parrelli
23e069ffa8 Bump version to 4.36.1 2019-03-19 19:27:29 -07:00
Greyson Parrelli
6e7fab40ac Guard against OOB moves in media send flow. 2019-03-19 18:38:06 -07:00
Greyson Parrelli
8a7cac7c03 Switch gallery to permanent dark theme. 2019-03-19 18:38:06 -07:00
Greyson Parrelli
932e7b4af5 Fix button flicker when selecting single media item. 2019-03-19 18:38:02 -07:00
Greyson Parrelli
2f8a7fa296 Bounce the media select button when selecting media. 2019-03-19 15:42:08 -07:00
Greyson Parrelli
5e6f71cd32 Show selection order in multi-select. 2019-03-19 15:42:08 -07:00
Greyson Parrelli
ce0058864f Make BlobProvider write to disk on a background thread.
Otherwise we hit some weird blocking issues with voice note recording.
2019-03-19 15:34:04 -07:00
Greyson Parrelli
5a8753de85 Fix group string. 2019-03-19 10:34:56 -07:00
Greyson Parrelli
c646316a97 Block typing indicators from blocked contacts. 2019-03-19 09:39:19 -07:00
Greyson Parrelli
6df8988f54 Updated to WebRTC M73. 2019-03-19 09:03:02 -07:00
Greyson Parrelli
5b534c8b1a Update URL homograph rules. 2019-03-18 17:37:19 -07:00
Greyson Parrelli
ab2e85f6c7 Bump version to 4.36.0 2019-03-18 15:10:13 -07:00
Greyson Parrelli
975a121c55 Show a warning for users on API < 19.
We'll be updating minSdk to 19 in 4.37. This lets these users continue
to use the app, but they'll be warned with a persistent banner saying
that they can't receive updates.
2019-03-18 15:09:56 -07:00
Greyson Parrelli
64cf032181 Updated media send UI. 2019-03-18 15:09:56 -07:00
Alan Evans
d8a56be5e8 Gradle/Gradlew/AndroidGradlePlugin update. 2019-03-18 15:09:56 -07:00
Alan Evans
286b64274c Replace Avatar Cropper. 2019-03-18 15:09:50 -07:00
Alan Evans
0cb2404735 Lint error fixes.
* Old Gingerbread code removed.
* Add missing super call.
2019-03-18 11:14:18 -03:00
Greyson Parrelli
0a8bbf14a6 Merge camera into send flow. 2019-03-14 16:25:35 -07:00
Greyson Parrelli
eb1dd58a0b Persistent media in multi-send. 2019-03-14 16:20:36 -07:00
Alan Evans
a79df7d815 Automatic resConfig.
- Test to ensure language_entries list matches exactly the available resources.
2019-03-14 13:33:43 -03:00
Alan Evans
e0c11998c3 Make DisplayRecord take context as argument, so locale is more likely to be correct. 2019-03-13 18:28:16 -03:00
Alan Evans
de72eceecf Update help URL to avoid redirect. 2019-03-13 18:19:33 -03:00
Alan Evans
c46e53ab24 Add Esperanto and Swahili (Kiswahili) to language selection. 2019-03-13 17:45:53 -03:00
Alan Evans
2c28fa6a57 Make GIF search layout option sticky.
Fixes #7843
2019-03-12 11:41:54 -03:00
Alan Evans
f010a3ec0d Consistent Recipient to add contact Intent export. 2019-03-12 11:29:59 -03:00
Alan Evans
e390fb4fc5 Fix ShareMessage toolbar back button. 2019-03-12 11:29:59 -03:00
Greyson Parrelli
a4ce77cbcc Remove unused method. 2019-03-12 11:29:59 -03:00
Greyson Parrelli
18613e3b6f Remove generic foreground service condition from Job.
I don't think it actually helps at all, meaning it just adds
complexity.

Fixes #8677
2019-03-12 11:29:59 -03:00
Greyson Parrelli
278fdebf43 Update WorkManager to 1.0.0. 2019-03-12 11:29:59 -03:00
Greyson Parrelli
a122bb4899 Created new BlobProvider.
One unified place to create blobs for different lifespans.
2019-03-10 15:18:39 -07:00
Greyson Parrelli
22ed8caed3 Bump version to 4.35.3 2019-03-07 17:59:18 -08:00
Greyson Parrelli
8b6ecd1d2e Fixed profile screen layout on small screens.
Fixes #8670
2019-03-07 17:25:02 -08:00
Greyson Parrelli
f2703f0b7b Bump version to 4.35.2 2019-03-06 08:12:42 -08:00
Greyson Parrelli
1efb92b913 Fix issue where SMS were sometimes sent as MMS.
Fixes #8664
2019-03-06 08:12:00 -08:00
Greyson Parrelli
5ccf84f7a2 Bump version to 4.35.1 2019-03-02 21:01:15 -08:00
Greyson Parrelli
c3368f6de6 Updated language translations. 2019-03-02 20:46:40 -08:00
Greyson Parrelli
77e971cb9b Fix bug where system emoji setting was ignored in message bubbles.
EmojiTextView. It is our gift. It is our curse.
2019-03-02 19:31:28 -08:00
Greyson Parrelli
003fa1b059 Make long text attachments contain the entire message.
Instead of just containing the 'overflow', long text attachments now
contain the entire body in full.
2019-03-02 19:31:22 -08:00
Greyson Parrelli
03aa9e9712 Bump version to 4.35.0 2019-03-01 14:19:21 -08:00
Greyson Parrelli
55699e27bc Added ability to receive long messages.
Send support is in here too. We'll enable it in a future release after
enough people have updated.
2019-03-01 14:15:08 -08:00
Greyson Parrelli
bf28e109d3 Update registration UI. 2019-03-01 14:15:01 -08:00
Greyson Parrelli
6b476876d9 Lower volume of call connect/disconnect sound.
It's now closer in amplitude to the ringing sound.

Fixes #8165
2019-03-01 13:44:32 -08:00
Greyson Parrelli
fd862e575b Fix situation where search nav could get stuck.
If you navigated to the ConversationActivity again via some action (like
a shared contact invite) while searching, we don't get the toolbar close
event, and therefore the search nav would stay open. Now we just reset
it on newIntent() to be safe.
2019-03-01 13:44:32 -08:00
Greyson Parrelli
7fd6f5b3ff Fix search highlight in multi-whitespace bodies.
The way the highlight was done could get screwed up if you had multiple
whitespaces in a row. This particularly came up with messages with
multiple newlines.
2019-03-01 13:44:32 -08:00
Greyson Parrelli
42e94d8f92 Remove leftover half-height camera code. 2019-03-01 13:44:32 -08:00
Greyson Parrelli
b572fce658 Remove some unnecessary intermediate blob creation. 2019-03-01 13:44:32 -08:00
Greyson Parrelli
276e867f9a Improved address resolution for ContentProxySelector.
We can use an unresolved address to avoid all the threading stuff in
that class.
2019-03-01 13:42:10 -08:00
Greyson Parrelli
b2d4608cdb Improved handling for URLs that are composed of mixed character sets. 2019-02-24 10:00:44 -08:00
Greyson Parrelli
9d21c36ddf Bump verstion to 4.34.8
Again, no changes. Needed to resubmit to the Play Store.
2019-02-21 18:04:44 -08:00
Greyson Parrelli
983290aa5b Bump version to 4.34.7
No changes. Necessary to resubmit to Google Play.
2019-02-21 12:57:55 -08:00
Greyson Parrelli
88b9fc25d2 Bump version to 4.34.6 2019-02-20 17:23:54 -08:00
Greyson Parrelli
60c7fb0056 Fix possible NPE. 2019-02-20 17:20:12 -08:00
Greyson Parrelli
fa6da1902f Fix button spinning after failed CAPTCHA. 2019-02-19 13:13:32 -08:00
Greyson Parrelli
5cc3ac00c7 Bump version to 4.34.5 2019-02-19 09:37:30 -08:00
Greyson Parrelli
33daa21ad9 Guard against devices not supporting mandatory ContentProvider columns.
The docs specify that this column is supposed to be present, but a
crash says it wasn't, so alas, here in goes the check.
2019-02-19 09:34:24 -08:00
Greyson Parrelli
c4d1bdc44d Bump version to 4.34.4
No changes. Necessary to resubmit to the Play Store.
2019-02-18 16:03:15 -08:00
Greyson Parrelli
ca99c732f8 Bump version to 4.34.3 2019-02-18 11:47:40 -08:00
Greyson Parrelli
1f79808cf0 Remove unneccesary FCM manifest attribute.
`firebase_analytics_collection_enabled` is used for temporarily
enabling/disabling analytics.

We already use `firebase_analytics_collection_deactivated`, which is
used for permanently disabling analytics.
2019-02-18 11:46:53 -08:00
Greyson Parrelli
5c0e1100ed Fix possible NPE in conversation menu.
Would occur if someone had previously muted a conversation with
themselves.
2019-02-16 11:45:09 -08:00
Greyson Parrelli
d0b763c16e Bump version to 4.34.2 2019-02-15 19:34:19 -08:00
Greyson Parrelli
b962751c96 Fix possible IllegalArgumentException during a database migration. 2019-02-15 19:33:16 -08:00
Greyson Parrelli
94e8553b73 Fix possible NPE during conversation load. 2019-02-15 19:24:23 -08:00
Greyson Parrelli
351b625975 Bump version to 4.34.1 2019-02-15 14:21:27 -08:00
Greyson Parrelli
a2b6dbda14 Correctly sync Note to Self conversation color. 2019-02-15 14:21:27 -08:00
Greyson Parrelli
a6564f8f84 FCM improvements. 2019-02-15 14:21:23 -08:00
Greyson Parrelli
4dbe165c18 Bump version to 4.34.0 2019-02-14 21:04:01 -08:00
Greyson Parrelli
f29a42411e Update WorkManager to beta05. 2019-02-14 20:19:07 -08:00
Greyson Parrelli
02b0800b22 Support requesting a CAPTCHA during registration. 2019-02-14 20:19:07 -08:00
Greyson Parrelli
2cfa431cad Supply a reason for CDS error reporting. 2019-02-14 20:19:07 -08:00
Greyson Parrelli
fe4068afce Don't preview links if your cursor is touching them. 2019-02-14 20:19:07 -08:00
Greyson Parrelli
1c23603c25 Add the Redmi Note 5 to the hardware AEC blacklist. 2019-02-14 20:19:07 -08:00
Greyson Parrelli
c2a86fcc74 Sync self-sends to desktop.
Updated UI to show self-conversations as "Note to Self".
2019-02-14 20:19:07 -08:00
Greyson Parrelli
d42c9b5dbc Ensure the group shortstring in the action bar is up-to-date.
There were situations where adding/removing members from a group
would update the group member list, but the short string (the little
text listing the first couple members of the group) wouldn't be updated
until you left the screen and came back.
2019-02-14 20:19:06 -08:00
Greyson Parrelli
3b6429c163 Don't unnecessarily stop the ShareActivity in onPause.
1. Due to ShareActivity having noHistory=true, it will already be
ditched when you leave the activity.
2. We only need to truly finish() here if we've dropped the underlying
media.

Fixes #8591
2019-02-14 20:19:06 -08:00
Greyson Parrelli
6896f8ea15 Properly check attachment size during media send.
Prevent users from trying to send videos that exceed the size limit.

Also, this commit properly populates height/width on media shared into
the app.

Fixes #8573
2019-02-14 20:19:06 -08:00
Greyson Parrelli
a3768c7d74 Fix StickyHeader measuring.
It didn't re-measure when pulling an item from the cache, screwing stuff
up after a phone rotation. Had a workaround for it for specific screens,
but this fixes the problem at the source.

Fixes #8583
2019-02-14 20:19:06 -08:00
Greyson Parrelli
c9a0a66f18 Migrate backup passphrase to be keystore-encrypted when available. 2019-02-14 20:19:06 -08:00
Greyson Parrelli
db1ad39c6b Fix issues with bundled notifications. 2019-02-14 20:19:06 -08:00
Greyson Parrelli
9f04c28bfd Implemented conversation search.
You can now search for messages within a specific conversation.
2019-02-14 20:19:01 -08:00
Greyson Parrelli
10631d7e71 Add a gradle.properties with increased memory size. 2019-02-14 14:29:12 -08:00
Greyson Parrelli
cfff10622a Move conversation classes to their own package. 2019-02-14 14:29:12 -08:00
Greyson Parrelli
b769c7d9b6 Properly batch contact inserts.
Fixes #8580
2019-02-14 14:29:12 -08:00
Greyson Parrelli
1e0f691a56 Updated to WebRTC M72. 2019-02-14 14:28:57 -08:00
Greyson Parrelli
f0852d1d39 Bump version to 4.33.5 2019-02-07 16:54:59 -08:00
Greyson Parrelli
1ee422a012 Update link preview splash to say 'Got it'. 2019-02-07 16:43:40 -08:00
Greyson Parrelli
ca87820dd5 Updated language translations. 2019-02-07 16:20:39 -08:00
Greyson Parrelli
45ddb7e1ad Revert "Fix notification badge display."
This reverts commit a0c1446e9f.
2019-02-07 16:17:17 -08:00
Greyson Parrelli
fd46777f04 Bump version to 4.33.4
No changes. Need to create a new version to handle Play Store issues.
2019-02-06 10:27:59 -08:00
Greyson Parrelli
5bb36c15d5 Bump version to 4.33.3 2019-02-06 09:22:19 -08:00
Meteor0id
c5571e8a8d Add 'Got it' as string to be used on link preview splash screen.
"Understood" or "Got it" is a way of dismissing a splash screen of notification without any change that is applies agreeing to anything.
It replaces "OK" which was sometimes misinterpreted as "I am OK with what I just read".
2019-02-06 09:22:19 -08:00
Greyson Parrelli
b8ab1bc3b2 Updated language translations. 2019-02-06 08:39:00 -08:00
Greyson Parrelli
3683e6a9e2 Revert "Apply contact updates in batches of 50."
This reverts commit 5d9d6ac12b.
2019-02-06 00:54:03 -08:00
Greyson Parrelli
c364345e1d Add some additional FCM logging. 2019-02-06 00:53:52 -08:00
Greyson Parrelli
7da73bbc30 Updated link preview splash layout. 2019-02-06 00:34:48 -08:00
Greyson Parrelli
177322eca4 Bump version to 4.33.2 2019-02-04 13:57:49 -08:00
Greyson Parrelli
506491d13d Updated language translations. 2019-02-04 13:56:06 -08:00
Greyson Parrelli
e884911b60 Update the link preview domain whitelist. 2019-02-04 09:05:40 -08:00
Greyson Parrelli
7b20fca1ac Clearing the text field resets link preview cancellation. 2019-02-04 08:54:54 -08:00
Greyson Parrelli
e2c2e59442 Bump version to 4.33.1 2019-02-02 10:13:37 -08:00
Greyson Parrelli
be66db898c Fix possible double-cancel in CallRequestController. 2019-02-02 10:09:38 -08:00
Greyson Parrelli
5d9d6ac12b Apply contact updates in batches of 50.
If batch sizes are too large, we'll get a Binder exception.

Fixes #8580
2019-02-01 12:47:34 -08:00
Greyson Parrelli
c6d3bed8da Hide emoji button in media flows when system emoji are enabled.
Fixes #8581
2019-02-01 09:17:07 -08:00
Greyson Parrelli
e74c429695 Bump version to 4.33.0 2019-01-30 16:34:10 -08:00
Greyson Parrelli
90a37852cc Hide quoted attachments from All Media and media rails.
Fixes #8009
2019-01-30 16:34:10 -08:00
Greyson Parrelli
1763be2956 Hide call settings for groups. 2019-01-30 16:33:02 -08:00
Greyson Parrelli
9797c54a4d Removed sonar ping from calls.
People rarely understood what it meant, and the information is available
on the screen if-needed ('dialing' vs 'ringing').
2019-01-30 16:10:47 -08:00
Greyson Parrelli
c5114e2cb3 Updated to WebRTC M71. 2019-01-30 16:10:47 -08:00
Greyson Parrelli
e3b22dabce Harden notification channels.
There's odd corner cases where channels can be duplicated. This commit
adds some hard checks where we trim any dead channels, and unset any
notification channels from recipients whose notification channel isn't
present in the system settings.
2019-01-30 16:10:47 -08:00
Bas van Schaik
ba67796992 Fix invalid equals in NotificationChannels.channelExists
`DEFAULT_CHANNEL_ID` is a String, but `channel` is a NotificationChannel. Equals will therefore always return `false`. I think my fix (using `getId()`) is what was intended.
2019-01-30 16:10:47 -08:00
Greyson Parrelli
d482c60a98 Switch from GCM to FCM. 2019-01-30 16:10:47 -08:00
Greyson Parrelli
ebe8d38a91 Update WorkManager to beta03. 2019-01-30 16:10:47 -08:00
Greyson Parrelli
c76081d99c Added support for link previews. 2019-01-30 16:10:43 -08:00
Greyson Parrelli
bef9beff16 Updated Gradle to 5.1 2019-01-29 09:22:44 -08:00
Greyson Parrelli
25e82ff5e4 Fixed issue where we'd incorrectly show input shadow.
We might have also scrolled with typing indicators when we shouldn't of.

All came down to #isAtBottom() being calculated incorrectly.
2019-01-27 22:07:55 -08:00
Greyson Parrelli
13ffba1c99 Updated language translations. 2019-01-25 17:55:31 -08:00
Greyson Parrelli
a0c1446e9f Fix notification badge display.
This reverts commit 2489ea0d5b.
2019-01-21 16:43:59 -08:00
Greyson Parrelli
657b520908 Bump version to 4.32.8 2019-01-20 14:22:27 -08:00
Greyson Parrelli
51e8e8c2c8 Go back to WorkManager beta01.
Looks like there may be a rescheduling bug in beta02. Working through it
with the WorkManager devs.
2019-01-20 14:12:29 -08:00
Greyson Parrelli
1e534a2a10 Fix group avatars not sending.
Fixes #8547
2019-01-20 12:00:18 -08:00
Greyson Parrelli
9fe30524b2 Bump version to 4.32.7 2019-01-17 15:39:13 -08:00
Greyson Parrelli
e6b4249cf3 Deprecate usage of the signaling key. 2019-01-17 15:37:53 -08:00
Greyson Parrelli
57ef0e9024 Bump version to 4.32.6 2019-01-17 12:33:41 -08:00
Greyson Parrelli
9ed290b8f6 Updated language translations. 2019-01-17 12:33:41 -08:00
Greyson Parrelli
d2be554e1b Use orientation in media picker to determine width and height. 2019-01-17 12:33:41 -08:00
Greyson Parrelli
e7a807ab5b Ensure body text is carried through to the media send screen.
We were only doing it if you entered through the media rail. Now we also
do it if you enter through the gallery.
2019-01-17 11:42:01 -08:00
Greyson Parrelli
9ff8f8587b Bump version to 4.32.5 2019-01-16 14:34:36 -08:00
Greyson Parrelli
a6f31c60bd Show a toast when you've gone over the max media selection. 2019-01-16 14:31:59 -08:00
Greyson Parrelli
4643dea2ad Filter out non-media from media send screen. 2019-01-16 13:32:39 -08:00
Greyson Parrelli
f70bf9c5bd Default to 'All media' bucket for items from the rail.
This should give people a better multi-send experience when they want to
add more media.
2019-01-16 13:18:16 -08:00
Greyson Parrelli
557e6a800f Bump version to 4.32.4 2019-01-16 00:10:46 -08:00
Greyson Parrelli
17a391d3cf Updated language translations. 2019-01-16 00:06:53 -08:00
Greyson Parrelli
fc989f3820 Fix album sizing issues on skinnier devices. 2019-01-15 23:57:43 -08:00
Greyson Parrelli
2be382afab Bump version to 4.32.3 2019-01-15 15:10:18 -08:00
Greyson Parrelli
b08f81a8dc Fix bug where back stack can get stuck in the gallery. 2019-01-15 15:08:35 -08:00
Greyson Parrelli
535e00c6d0 Saving an album will now save every item.
Fixes a bug where saving would incorrectly only save the first image.
2019-01-15 14:56:27 -08:00
Greyson Parrelli
db1abf3746 Bump version to 4.32.2 2019-01-15 13:52:02 -08:00
Greyson Parrelli
66dde4415d Added an 'All media' folder in the gallery. 2019-01-15 13:38:06 -08:00
Greyson Parrelli
ce3deb4057 Update WorkManager to beta02. 2019-01-15 12:54:14 -08:00
Greyson Parrelli
2209ff2272 Use AttachmentUploadJob in PushGroupSendJob. 2019-01-15 12:43:38 -08:00
Greyson Parrelli
1502b0ae3e Add processing rules for partial US and BR phone numbers. 2019-01-15 11:57:42 -08:00
Greyson Parrelli
553669de45 Bump version to 4.32.1 2019-01-14 15:43:21 -08:00
Greyson Parrelli
4952b4470d Fix bug related to gallery selection state.
TreeSets are annoying. contains() is calculated with the comparator,
which can lead to some weird bugs. Made sure the comparator didn't think
two items with the same date were identical.

Also fixed stableId generation to avoid any potential weirdness there.
2019-01-14 15:40:38 -08:00
Greyson Parrelli
5450967d00 Ensure all Workers have a public WorkManager constructor. 2019-01-14 15:15:53 -08:00
Greyson Parrelli
37b9e4f200 Bump version to 4.32.0 2019-01-14 11:25:12 -08:00
Greyson Parrelli
254275a8e0 Updated language translations. 2019-01-14 11:25:12 -08:00
Greyson Parrelli
8434813ad6 Updated libsignal-service-java to 2.12.5 2019-01-14 11:25:12 -08:00
Greyson Parrelli
dcae8a8a2f Update WorkManager to beta01. 2019-01-14 11:25:12 -08:00
Greyson Parrelli
6fa7eca60b Implement new media send flow.
Update our media send flow to allow users to send multiple images/videos
at once. This change includes:

- New in-app media picker flow.
- Ability to caption images and videos.
- Image editing tools are made more prominent in the flow.
- Some fixes to the image editing tools.
2019-01-14 11:25:06 -08:00
Greyson Parrelli
bae55f4b2f Remove redundant km_KH mapping. 2019-01-13 19:25:40 -08:00
riyapenn-signal
7278f6db76 Update in-app language list for Welsh, Hindi, Quechua, Khmer
Languages added: 

1. Welsh Cymraeg cy
2. Hindi Hindi हिंदी hi 
3. Quechua qu_EC

Languages modified: 

1. Khmer from kh-rKH to kh
2019-01-13 19:25:40 -08:00
Greyson Parrelli
b553bb1cb0 Don't allow sending SMS unless we're the default. 2019-01-13 19:25:40 -08:00
Greyson Parrelli
3b67382f67 Remove call log permissions, use SMS Retriever API during registration.
This is to adhere to the Play Store policy updates.

See: https://play.google.com/about/privacy-security-deception/permissions/
2019-01-13 19:25:40 -08:00
Greyson Parrelli
19d5ba5c0e Upload attachments in a separate job. 2019-01-13 19:25:40 -08:00
Greyson Parrelli
96c641c2a0 Add support for Job chains. 2019-01-13 19:25:40 -08:00
Greyson Parrelli
1a50910910 Update WorkManager to alpha12. 2019-01-13 19:25:40 -08:00
Greyson Parrelli
40f9b32a75 Fix tap-to-upgrade on website releases.
Tested on Android 9.0, 7.0, and 5.1.

Fixes #7936
2019-01-13 19:08:33 -08:00
Greyson Parrelli
975d7268a1 Bump version to 4.31.8 2019-01-13 07:26:52 -08:00
Greyson Parrelli
7bda952ee5 Fix crash when DeviceName is shorter than 4 characters. 2019-01-13 07:26:16 -08:00
Greyson Parrelli
1c3052a580 Bump version to 4.31.7 2019-01-12 15:50:59 -08:00
Greyson Parrelli
7c66c4a4f7 Updated logging. 2019-01-12 13:32:24 -08:00
Greyson Parrelli
c6f3a66cad Support encrypted linked device names. 2019-01-12 13:32:24 -08:00
Greyson Parrelli
4ab02f5b9c Bump version to 4.31.6 2018-12-11 13:37:57 -08:00
Greyson Parrelli
2ab2b2306d Fixed build issues caused by Google jcenter fiasco.
Google removed a bunch of binaries from jcenter that they shouldn't
have, breaking everyone's builds. So now we have manually add repos for
the missing binaries in the meantime.
2018-12-11 13:34:16 -08:00
Greyson Parrelli
3a7f01e16a Updated language translations. 2018-12-11 13:21:54 -08:00
Greyson Parrelli
e5a2cea6b0 Fix voice note seeking issue.
On some devices, pausing+resuming (or seeking) would restart playback
from the beginning, but show a progress bar further up. This seems to
have been caused by same race condition-y thing where we were seeking
multiple times in rapid succession. Now we'll only play once, and things
seem to be fine now.

Also removed usage of some deprecated methods.

Fixes #8432
2018-12-11 13:05:36 -08:00
Greyson Parrelli
be215b3b1e Bump version to 4.31.5 2018-12-06 23:53:51 -08:00
Greyson Parrelli
2d5c2d24e5 Updated language translations. 2018-12-06 23:53:13 -08:00
Greyson Parrelli
038238a333 Allow multiple attachments to download at once.
Not only will this be faster, but it serves as a mitigation
for the times when WorkManager gets 'stuck'.

Fixes #8427
2018-12-06 23:29:55 -08:00
Greyson Parrelli
bfdad2f47c Updated logging. 2018-12-06 12:43:45 -08:00
Greyson Parrelli
2489ea0d5b Revert "Fix notification badge display."
This reverts commit caf93b9203.
2018-12-06 12:14:45 -08:00
Greyson Parrelli
053f071f41 Bump version to 4.31.4 2018-12-04 18:16:00 -08:00
Greyson Parrelli
caf93b9203 Fix notification badge display.
Fixes #7580
2018-12-03 15:32:13 -08:00
Greyson Parrelli
f0bfd7224f Handle having a null sender certificate at send time.
Fixes #8425
2018-12-03 13:16:29 -08:00
Greyson Parrelli
f13becc50b Bump version to 4.31.3 2018-12-01 10:39:48 -08:00
Greyson Parrelli
4b88f7b845 Unsubscribe from typing observers when forwarding messages. 2018-12-01 10:39:48 -08:00
Greyson Parrelli
a81cc685b2 Fix crash where toolbar was updated off of the main thread. 2018-12-01 10:22:05 -08:00
Greyson Parrelli
b6098a26b4 Update typing indicator intro strings. 2018-12-01 09:55:21 -08:00
Greyson Parrelli
d6abf89a7a Filter out typing indicators from ourself. 2018-12-01 09:51:28 -08:00
Greyson Parrelli
dd55fe90bc Fix typing experience upgrade version.
Because of the production hotfix, we need to up this version to be
higher than what is currently in prod.
2018-11-28 09:29:19 -08:00
Greyson Parrelli
5a53268534 Update typing indicator intro screen. 2018-11-27 17:45:58 -08:00
Greyson Parrelli
1f9a65e389 Bump version to 4.31.2 2018-11-27 12:51:20 -08:00
Greyson Parrelli
81055e61a6 Update WorkManager to 1.0.0-alpha11. 2018-11-27 12:35:41 -08:00
Greyson Parrelli
8a1a47e773 Fix MediaPreview NPE. 2018-11-27 09:32:56 -08:00
Greyson Parrelli
193d82789f Bump version to 4.31.1 2018-11-26 11:50:55 -08:00
Greyson Parrelli
7f09d1d0d7 Updated language translations. 2018-11-26 11:50:55 -08:00
Greyson Parrelli
187d7b3e3a Fix the caption database migration. 2018-11-26 11:50:55 -08:00
Greyson Parrelli
5d1fcdaded Fix typing indicator animation.
The Android animators were getting out of sync when frames were dropped
(despite my best efforts), so now we just manually render each animation
frame as a function of time, so it never gets screwed up.

Fixes #8388
2018-11-26 09:33:31 -08:00
Greyson Parrelli
36b24d0a20 Rotate sender cert at send time if it's expired. 2018-11-26 07:52:59 -08:00
Greyson Parrelli
f9d7cf0e19 Bump version to 4.31.0 2018-11-21 01:55:30 -08:00
Greyson Parrelli
47a10a0288 Added support for multi-image receive. 2018-11-21 01:55:30 -08:00
Greyson Parrelli
e665252b86 Add more logging to GenericForegroundService. 2018-11-21 01:55:30 -08:00
Greyson Parrelli
a3411072ba Remove MasterSecret job.
It's no longer necessary.
2018-11-21 01:55:30 -08:00
Greyson Parrelli
776b0e23ae Add support for typing indicators. 2018-11-21 01:55:25 -08:00
Greyson Parrelli
3f25fb7d5f Handle voice note media playback with ExoPlayer.
There are several (popular) phone models out there that have bugs in
their MediaPlayer implementation that cause them to be unable to play
voice notes. By moving to ExoPlayer, an application-level media player,
we should avoid most of these headaches and stardardize playback.

Fixes #7748
2018-11-19 11:36:08 -08:00
Greyson Parrelli
053e6fc223 Bump version to 4.30.7 2018-11-17 10:00:55 -08:00
Greyson Parrelli
a2ea115650 Initialize jobs in the try block.
In the case where we add new fields to a Job's InputData, we want to
make sure that initialize() is called in the try block so that if it
fails, it simply fails the job (allowing the user to retry with the new
field) instead of crashing.
2018-11-17 09:56:52 -08:00
Greyson Parrelli
3f7e9cb46f Bump version to 4.30.6 2018-11-15 12:50:03 -08:00
Greyson Parrelli
cefe50e8a9 Updated language translations. 2018-11-15 12:49:56 -08:00
Greyson Parrelli
ff9d5df0e0 Dark theme support for emoji variation selector. 2018-11-15 11:43:38 -08:00
Greyson Parrelli
3716d69b0b Dismiss emoji variation popup when keyboard is dismissed.
Fixes #8372
2018-11-15 10:17:07 -08:00
Greyson Parrelli
d5be43cc85 Bump version to 4.30.5 2018-11-14 17:23:03 -08:00
Greyson Parrelli
481ff5c81e Updated language translations. 2018-11-14 17:21:43 -08:00
Greyson Parrelli
3e26060e99 Updated libsignal-service-java to 2.12.2 2018-11-14 16:25:16 -08:00
Greyson Parrelli
d93bfbf693 Prevent SendJobs from sending already-sent messages.
This is to guard against behavior WorkManager has where it may
re-enqueue a job that has already been completed (if, for instance, it
was preempted).

Fixes #8268
2018-11-14 16:20:55 -08:00
Greyson Parrelli
a7e15dc21e Removed unused asset. 2018-11-14 09:18:45 -08:00
Greyson Parrelli
bb566cb11f Bump version to 4.30.4 2018-11-13 20:04:25 -08:00
Greyson Parrelli
28081abe1c Split the 'people' emoji spritesheet into multiple chunks.
The aim of this is to help performance by breaking up the single massive
spritesheet into smaller ones. This will limit the amount of data that
needs to be kept in memory to render emoji.

(Hopefully) Fixes #8357
2018-11-13 19:29:51 -08:00
Greyson Parrelli
e7c00a3066 Fix issue where we may oversend SMS messages.
Because SMS sending is split over two jobs, there's no max retry limit
respected if we find out about the failure in SmsSentJob -- it's
requeued as a new job with a fresh attempt counter.

This commit carries a retry count between the two jobs. It also verifies
that we have service before attempting to send a message at all.

Relates to #8268
2018-11-13 15:07:33 -08:00
Greyson Parrelli
446585ad68 Fix emoji variation selector on older devices.
Weird platform-specific bug was preventing the display of the
PopupWindow.
2018-11-13 11:19:29 -08:00
Greyson Parrelli
4ebca9ddde Register RotateSenderCertificateListener in the manifest. 2018-11-13 10:35:02 -08:00
Greyson Parrelli
4c6655bd9a Bump version to 4.30.3 2018-11-09 12:37:27 -08:00
Greyson Parrelli
cbc7288242 Updated language translations. 2018-11-09 12:37:27 -08:00
Greyson Parrelli
78627ecb08 Updated libsignal-service-java to 2.12.1 2018-11-09 12:37:24 -08:00
Greyson Parrelli
bf9582c97e Only set UNRESTRICTED mode if recipients have a non-null verifier.
Otherwise we could send UD messages to people with non-UD linked
devices.
2018-11-06 09:58:45 -08:00
Greyson Parrelli
1ab3d57378 Fix some places where we were using the Android Logger.
We pretty much always want to be using our own logger.
2018-11-06 09:22:25 -08:00
Greyson Parrelli
b36d196873 Bump version to 4.30.2 2018-10-31 14:22:58 -07:00
Greyson Parrelli
e31029da89 Update recipient's sealed sender status in more places. 2018-10-31 11:18:35 -07:00
Yassine El Khadiri
787bcf7752 Fix backup MAC checking.
if(MessageDigest.isEqual(ourMac, theirMac) was always returning false
since ourMac was of length 32 and theirMac was of length 10.
2018-10-31 11:17:29 -07:00
Greyson Parrelli
8c3d50c6dc Ignore messages without content. 2018-10-31 08:26:45 -07:00
Greyson Parrelli
532431b0ad Guard against notifying for errors on non-existent SMS threads.
All of the other send jobs do this already, just didn't do it here.
2018-10-31 08:19:33 -07:00
Greyson Parrelli
cfeee25488 Use correct link for Sealed Sender blog post.
Fixes #8324
2018-10-30 14:12:34 -07:00
Moxie Marlinspike
608b7ef89a Bump version to 4.30.1 2018-10-30 09:21:31 -07:00
Moxie Marlinspike
4063ef39a4 Update release config 2018-10-30 09:20:54 -07:00
Greyson Parrelli
eeb2e2e3af Bump version to 4.30.0 2018-10-30 09:07:57 -07:00
Greyson Parrelli
2573900c30 Updated language translations. 2018-10-30 09:07:57 -07:00
Greyson Parrelli
2acab563d9 Support for sealed sender - Part 2 2018-10-30 08:48:08 -07:00
Moxie Marlinspike
5f31762220 Support for sealed sender - Part 1 2018-10-30 08:48:08 -07:00
Greyson Parrelli
b7b9554364 Prevent multiple instances of the same job running concurrently.
There are rare corner cases where a Job could be preempted by the
JobScheduler and then be rescheduled before the preempted job finished
running. This could create weird race conditions with bad consequences.

To fix this, we create a fun locking system that prevents two jobs with
the same UUID from running at the same time.
2018-10-30 08:48:07 -07:00
Greyson Parrelli
f15fb904bf Fix desktop double notification bug.
There were situations where we were posting two notifications for messages
when you had an 'active desktop'. This removes that.
2018-10-30 08:48:07 -07:00
Greyson Parrelli
86e4221182 Use a unique notification icon for backups. 2018-10-27 23:34:18 -07:00
Greyson Parrelli
dfe8b25dd7 Use a unique notification icon for the persistent background connection. 2018-10-27 23:32:28 -07:00
Greyson Parrelli
53050b3845 Fix issue with group avatar display.
Some legacy code was making the contact photo visible when it shouldn't
be.
2018-10-27 23:12:25 -07:00
Greyson Parrelli
6ce278114f Ensure profile photo in ConversationList is accurate.
Fixes #8270
2018-10-26 11:05:14 -07:00
Greyson Parrelli
48ff9673b9 Allow the selection of fitzpatrick emoji. 2018-10-26 11:05:10 -07:00
Greyson Parrelli
1999d09901 Updated emoji set.
Includes display support for more genders, and more notably, skin tones.
These are not currently selectable in the UI, but they will be rendered
properly when other clients send them.
2018-10-24 17:11:17 -07:00
Greyson Parrelli
f93a79ae37 Bump version to 4.29.7 2018-10-24 17:05:23 -07:00
Greyson Parrelli
fac56be499 Fix the build by listing google repo first.
Apparently jcenter() is lame and it broke our build. Listing the google
repo first fixes everything.
2018-10-24 16:57:19 -07:00
Greyson Parrelli
638012f3d0 Bump version to 4.29.6 2018-10-24 10:58:42 -07:00
Greyson Parrelli
bf452dfa92 Slightly shorten time before we show a foreground notification for pushes.
There's some ANRs, not many, that are likely caused by us riding the
5-second ANR timeout a little too closely. Giving us a little buffer to
see if that helps.
2018-10-24 10:58:06 -07:00
Greyson Parrelli
2b14c98eb0 Do not call bluetooth state listener after service is destroyed. 2018-10-24 10:43:08 -07:00
Greyson Parrelli
f164ac90db Disallow punctuation in icon initials. 2018-10-24 09:57:48 -07:00
Greyson Parrelli
14abbb1bbb Bump version to 4.29.5 2018-10-22 13:04:19 -07:00
Greyson Parrelli
91db26437d Fix camera scaling issues on some phones.
Some phones, notably the Pixel 3, had some problems with scaling after
taking photos. This fixes it by using the takePicture API instead of
pulling the bitmap from the TextureView.

Fixes #8292
2018-10-22 01:12:05 -07:00
Greyson Parrelli
76054a9e33 Ignore events after BluetoothStateManager is destroyed.
Fixes crash.
2018-10-21 13:03:28 -07:00
Greyson Parrelli
ae9c53bdf8 Ensure jobs have a Context during onAdded().
Fixes a crash.
2018-10-20 22:52:14 -07:00
Greyson Parrelli
0dd7b39bb1 Fix recipient prefrence display problem on Android P.
Android P's new ringtone selector is a whole new activity that can cause
RecipientPreferenceActivity to go through the full onCreate() flow after
the ringtone selection. This could cause a race between setting the
preference and reading the preference from the notification channel.
Just threw them on a serial executor to guarantee ordering.
2018-10-20 22:42:35 -07:00
Greyson Parrelli
4a0ea0c51c Handle contexts more consistently in RecipientPreferences.
Fixes a crash that was happening on the Pixel 3.
2018-10-20 22:22:07 -07:00
Greyson Parrelli
668e8dee5d Catch more camera exceptions.
Some devices will simply fail to open the camera with a runtime
exception. In this case, all we can do is catch it and report the error.
2018-10-19 15:57:34 -07:00
Greyson Parrelli
8ec3cf6a43 Bump version to 4.29.4 2018-10-18 09:52:47 -07:00
Greyson Parrelli
a287408a7a Only start the screen lock timeout when the app is backgrounded. 2018-10-18 09:40:32 -07:00
Greyson Parrelli
78124ef224 Bump version to 4.29.3 2018-10-17 14:01:44 -07:00
Greyson Parrelli
45e0bb281f Turn MessageRetrievalService into IncomingMessageObserver.
Due to an Android P bug, we basically need to stop calling
startService() in onResume()/onPause(). That means I had to turn
MessageRetrieval service into a singlton instead of a service. I also
moved the offending KeyCachingService calls into static methods that
didn't have to start the service.
2018-10-17 13:58:47 -07:00
Greyson Parrelli
7a6d863ff7 Bump version to 4.29.2 2018-10-16 22:55:35 -07:00
Greyson Parrelli
feb9e1d513 Post startService() in onPause() as a possible fix to an Android P bug.
We already did it for onResume(), and while it fixed the crash there,
the crash just moved to onPause(). Let's see if the same magic works.
2018-10-16 22:54:29 -07:00
Greyson Parrelli
1a5c1a4b42 Bump version to 4.29.1 2018-10-16 11:53:48 -07:00
Greyson Parrelli
e41ed92f49 Updated language translations. 2018-10-16 11:53:08 -07:00
Greyson Parrelli
7e485b8095 Post startService() in onResume() as a possible fix to an Android P bug.
Got confirmation that the crash we're seeing is a bug, and this might be
a possible workaround.
2018-10-16 11:47:58 -07:00
Greyson Parrelli
92773b1a12 Update delivery icon tint in conversation list. 2018-10-16 11:18:49 -07:00
Greyson Parrelli
7cadb0d35a Properly set the document download icon tint. 2018-10-16 10:58:19 -07:00
Greyson Parrelli
e1f572e1f4 Update GCM foreground notification icon.
Using the default Signal icon can confuse people into thinking they're
message notifications.
2018-10-15 16:56:24 -07:00
Greyson Parrelli
ead323c1af Don't unnecessarily stack GCM message processing.
If we already have two active processing GCM messages, there's no
benefit to a third. In fact, enqueuing additional ones will likely only
end up showing the foreground notification unnecessariliy.
2018-10-15 10:37:30 -07:00
Greyson Parrelli
20c059280c Refactor OrderEnforcer. 2018-10-12 09:30:01 -07:00
Greyson Parrelli
50eb8f2322 Bump version to 4.29.0 2018-10-11 11:30:18 -07:00
Greyson Parrelli
15f418f2cc Updated language translations. 2018-10-11 11:30:06 -07:00
Greyson Parrelli
b133546ca6 Bump targetSdkVersion to 26. 2018-10-11 09:55:46 -07:00
Greyson Parrelli
5219d79e27 Remove unnecessary start of KeyCachingService. 2018-10-11 09:55:46 -07:00
Greyson Parrelli
89f97f57cb Update our boot receiver to schedule a message pull.
Previously we were starting a background service, which isn't allowed
for targetSdk 26. This will do the same thing but at a time decided by
the system.
2018-10-11 09:55:46 -07:00
Greyson Parrelli
4c63428b71 Ensure GenericForegroundService is started with startForegroundService.
If we don't, we run the risk of the app crashing if the service is
started in the background.
2018-10-11 09:55:46 -07:00
Greyson Parrelli
704715de8f Fix message details delivery status icon tint (again). 2018-10-11 09:55:33 -07:00
Greyson Parrelli
0d48f10806 Fix issue where a Job had null JobParameters. 2018-10-10 09:00:14 -07:00
Greyson Parrelli
275ca9e3ba Remove the ability to set a color for a group.
No longer applicable given that we're adding back per-person colors in
groups.
2018-10-09 15:34:08 -07:00
Greyson Parrelli
710fa4a6f0 Switch the conversation color back to incoming messages. 2018-10-09 15:34:04 -07:00
Greyson Parrelli
b1d653a230 Bump version to 4.28.1 2018-10-08 10:20:47 -07:00
Greyson Parrelli
1b736e9e04 Ensure notifications are processed after receiving GCM message.
It's unreliable to run these tasks on WorkManager, as there's no
scheduling guarantees.
2018-10-08 10:00:15 -07:00
Greyson Parrelli
1c197ad93d Reset attachment transfer state if auto-download requirements are not met. 2018-10-07 14:21:33 -07:00
Greyson Parrelli
a1ba5003d3 Fix some dark theme color consistency issues.
Fixes #8253
2018-10-05 17:21:26 -07:00
Greyson Parrelli
f26c6f890f Fix non-contact icon in recipient preferences being too small.
Relates to #8252
2018-10-04 11:35:19 -07:00
Greyson Parrelli
eb11d5ceda Make avatar color in toolbar match conversation color.
Relates to #8252
2018-10-04 11:27:12 -07:00
Greyson Parrelli
43ebcfdee5 Added more contrast to shared contact button color in dark theme.
Relates to #8252
2018-10-04 11:12:49 -07:00
Greyson Parrelli
d9272c3b33 Fix message details delivery status icon tint.
Fixes #8251
2018-10-04 11:01:46 -07:00
Greyson Parrelli
1d7f7b6c38 Do not auto-assign Steel as a color for contacts/groups.
Should be reserved for non-contacts, but selectable in the color picker.

Fixes #8247
2018-10-04 09:22:24 -07:00
Greyson Parrelli
07d7af6e75 Initialize WorkManager ourself.
This gives us more control over when it happens, as well as lets us set
things like the debug level. Also let's us get rid of the synchronized
block we had in Application#onCreate().
2018-10-04 09:09:04 -07:00
Greyson Parrelli
4da1af9a7b Use the correct save icon in the ScribbleHud. 2018-10-03 18:13:21 -07:00
Greyson Parrelli
0840175d6f Remove shutter sound on camera capture.
This sound isn't supposed to play when you have notification sound off,
but apparently some Huawei phones will play it anyway. Until we can
figure out a better way to handle it, we're just removing it.
2018-10-03 18:11:50 -07:00
Greyson Parrelli
b6e40ea812 Bump version to 4.28.0 2018-10-03 15:33:00 -07:00
Greyson Parrelli
c81bc22943 Fix avatar location in a group conversation. 2018-10-03 14:25:23 -07:00
Greyson Parrelli
547b7a3c6f Migrate legacy color palette.
We don't store non-user-selected colors in the database. That means that
when we update the palette, we still have to hash based off of the legacy
palette when generating a color if we want to migrate to a
similar-looking color.

Unfortunately, because the new palette is smaller, some colors are
"overloaded", meaning that when we hash based off of the legacy palette,
some colors will be more/less common than others. To fix this, we simply
persist all current colors in the database, then switch our hashing list
to what we really want.
2018-10-03 14:25:17 -07:00
Greyson Parrelli
5eec3c9541 Add hairline border to avatars. 2018-10-03 14:24:00 -07:00
Greyson Parrelli
f725dd5a7e Show profile avatar in toolbar. 2018-10-03 14:24:00 -07:00
Greyson Parrelli
a3cba66450 Update fallback avatars. 2018-10-03 14:24:00 -07:00
Greyson Parrelli
bab92fca7b Move unread indicator to be above the avatar. 2018-10-03 14:23:59 -07:00
Greyson Parrelli
c37c1dffd4 Allow setting the color for a group. 2018-10-03 14:23:59 -07:00
Greyson Parrelli
127505af0b Implement new color palette. 2018-10-03 14:23:59 -07:00
Greyson Parrelli
cfd20d23e8 Fix double onClick() notifications in preferences.
Fixes #8241
2018-10-03 11:31:07 -07:00
Greyson Parrelli
e4b56d4e40 Show foreground notification for jobs when network is restricted.
Occasionally a job may be run when the app is in a network-restricted
mode, like a form of doze. When this happens, jobs can timeout due to
lack of network access, causing a cascade of job delays. This is
particularly bad in the case of message retrieval.

To prevent this, if a job that normally requires network detects that no
network is available when running, then we start a foreground
notification.
2018-10-03 10:00:42 -07:00
Greyson Parrelli
c86c2c51bb Bump version to 4.27.3 2018-10-02 12:53:29 -07:00
Greyson Parrelli
5a623810cb Broaden exception handling around Camera#startPreview().
Some devices will randomly throw RuntimeExceptions here due to hardware
issues. We were already doing broader catch statement in CameraView, so
I moved it here as well.
2018-10-02 12:47:07 -07:00
Greyson Parrelli
444e01deae Improve key presence checking in SafeData.
This isn't a perfect check either, but it should be safer and more
consistent than using static "invalid values".
2018-10-02 12:31:12 -07:00
Greyson Parrelli
d25ebdc818 Fix indentation in preference fragments.
Unfortunately, while there does exist an XML property to disable the
indentation, it's bugged for category headings, so we have to do this
silly thing where we strip the padding in the adapter. Hopefully they'll
fix the bug and we can move to use the sanctioned property.

See: https://issuetracker.google.com/issues/111662669

Fixes #8233
2018-10-02 12:08:01 -07:00
Greyson Parrelli
24e82abf80 Don't report contact discovery accuracy if it encountered an error.
Otherwise we're double-reporting. Also made the sanitize method more
accurate.
2018-10-02 09:16:37 -07:00
Greyson Parrelli
cfa13867e5 Allow null for profileAvatar in RetrieveProfileAvatarJob. 2018-10-02 08:43:18 -07:00
Greyson Parrelli
34770a2333 Fixed Camera capture crash on API <= 19.
On older versions of Android, TextureView#getBitmap() needs to be called
on the main thread. On mid range phones, this is ~50ms. Normally that'd
be bad, but the UI isn't doing anything at that point anyway.

Fixes #8232
2018-10-01 23:53:33 -07:00
Greyson Parrelli
2c5fa155ae Fix re-enabling tab switching in MediaOverview.
We were being inconsistent in how we were handling exiting multiselect,
and it wasn't behaving properly when you left by clicking the 'x'. Now
it's all handled centrally.

Fixes #8234
2018-10-01 23:38:07 -07:00
Greyson Parrelli
bc6941589c Bump version to 4.27.2 2018-10-01 16:15:16 -07:00
Greyson Parrelli
12afdad291 Log Job retryable exceptions. 2018-10-01 16:14:45 -07:00
Greyson Parrelli
4799d30077 Update the Dockerfile.
We updated our build tools and stuff, so we have to update the
Dockerfile. Took this opportunity to also update the version of
Ubuntu we were using as the base.
2018-10-01 16:12:10 -07:00
Greyson Parrelli
fafad0d555 Fix the command line build. 2018-10-01 15:39:05 -07:00
Greyson Parrelli
3f4133b163 Bump version to 4.27.1 2018-10-01 12:49:41 -07:00
Greyson Parrelli
68746bcecb Move targetSdk back to 25.
It was accidentally bumped to 26.
2018-10-01 12:47:47 -07:00
Greyson Parrelli
0fbb4ac333 Bump version to 4.27.0 2018-10-01 12:39:14 -07:00
Greyson Parrelli
f2e4f626c1 Updated language translations. 2018-10-01 12:38:57 -07:00
Greyson Parrelli
2f530dc970 Remove CameraView usage of JobManager.
WorkManager flat-out can't handle anonymous implementations of Worker
classes due to it using reflection to instantiate them.
2018-10-01 12:12:50 -07:00
Greyson Parrelli
87e6aa48bb Schedule jobs with WorkManager.
Should help solve most of our pressing targetSdk=26 migration issues.
2018-10-01 12:12:50 -07:00
Greyson Parrelli
d10a44f8eb Suppress some noisy logs. 2018-10-01 12:12:50 -07:00
Greyson Parrelli
6359961a82 Ensure numbers are properly formatted before giving them to contact discovery service.
We were sending "Unknown" addresses, which would cause the service to
choke.
2018-10-01 12:12:12 -07:00
Greyson Parrelli
946f76a442 Fix layout problems in conversation item footer. 2018-09-27 12:25:30 -07:00
Greyson Parrelli
616912d85f Prefer local state in dial click listener. 2018-09-27 11:45:56 -07:00
Greyson Parrelli
bd38b96095 Long-press timestamps in message details to copy. 2018-09-27 11:34:43 -07:00
Greyson Parrelli
12d9d7741b Clean up batch saving.
- Post a better string for when batch saving completes successfully
- Exit multi-select after saving
2018-09-27 10:35:56 -07:00
FeuRenard
91a119393c Allow batch saving in media overview 2018-09-27 10:35:56 -07:00
FeuRenard
c82afd8944 Allow selecting all media in overview 2018-09-27 10:35:56 -07:00
Greyson Parrelli
84c71fce16 Disable tab switching in media overview during multiselect.
Multiselect only applies to items in the "media" tab, so people
shouldn't be able to switch tabs during multiselect.
2018-09-27 10:35:56 -07:00
Greyson Parrelli
a0ab252bc9 Add preliminary contact discovery service support. 2018-09-27 10:35:56 -07:00
Greyson Parrelli
08ace15f95 Implemented new camera capture flow.
A new, fullscreen camera capture flow that easily allows you to capture
and edit a photo before sending it. Replaces the current half-screen
camera button.
2018-09-27 10:35:56 -07:00
Greyson Parrelli
e9a38bab1e Turned SingleUseBlobProvider into MemoryBlobProvider.
Keep the single-use behavior, but allow the creation of multi-use memory
blobs that can be deleted when we're done with them. Will help out with
having URI's for temporary images during the camera capture flow.
2018-09-27 10:35:56 -07:00
Greyson Parrelli
e63773e5c8 Added OrderEnforcer class to schedule ordered tasks. 2018-09-27 10:35:56 -07:00
Greyson Parrelli
bcebf58b76 Added a new Stopwatch class to easily log timings. 2018-09-27 10:35:56 -07:00
Unknown
2209e68ae0 Changed URL of the user forum. 2018-09-27 10:29:30 -07:00
Greyson Parrelli
6a0b89feaa Bump version to 4.26.2 2018-09-25 10:01:39 -07:00
Greyson Parrelli
6eb8693546 Don't block messages from unknown groups.
We were incorrectly considering unknown groups to have been "left".
2018-09-25 10:00:14 -07:00
Greyson Parrelli
c5f53b23fa Bump version to 4.26.1 2018-09-19 16:47:33 -07:00
Greyson Parrelli
11127c0d97 Clear external cache upon upgrade. 2018-09-19 16:41:51 -07:00
Greyson Parrelli
1af930437a Bump version to 4.26.0 2018-09-18 17:44:18 -07:00
Greyson Parrelli
94bfebeef1 Updated language translations. 2018-09-18 17:43:29 -07:00
Greyson Parrelli
45c4eafbd7 Add the ability to block groups.
This also fixes the situation where we block group-leave messages,
preventing blocked contacts from leaving groups.

Fixes #7970

Also, this forced us to upgrade libsignal-service, which fixes the
websocket timeout issues. Thanks to @dpapavas!

Fixes #6644
2018-09-18 15:26:50 -07:00
Greyson Parrelli
741b775d3e Ensure external camera blob is deleted. 2018-09-17 20:29:21 -07:00
Greyson Parrelli
e09c99102e Clear Glide disk cache after image deletion. 2018-09-17 19:17:36 -07:00
Greyson Parrelli
1d4020ffc6 Disable forwarding for shared contacts.
Forwarding of shared contacts currently just creates an empty draft.
You can't preview a shared contact before you send, which would make the
forwarding flow inconsistent across media types. So it's easier to just
hide it for now.

Fixes #8195
2018-09-16 22:50:59 -07:00
Greyson Parrelli
5d11e321a8 Fix setting global notification sound to 'None'.
Fixes #8206
2018-09-16 22:29:55 -07:00
Greyson Parrelli
9dd3e50ebd Don't set subscriptionId for quick-reply push messages.
This could cause us to think push messages were actually sent with
a SIM. We also now prevent rendering SIM info on push messages in
the conversation view.

Fixes #8176
2018-09-08 10:08:22 -07:00
Greyson Parrelli
ad7dd7584e Fixed document display in media overview in dark theme.
Shoutout to @aleb2000 for working on this as well!

Fixes #8151
2018-09-08 08:23:33 -07:00
Greyson Parrelli
c1a827f6d4 Update WebRTC to M69. 2018-09-08 07:48:20 -07:00
Greyson Parrelli
440ad70d79 Allow submitting a debug log during registration. 2018-09-08 07:48:20 -07:00
Greyson Parrelli
a1b2887bf3 Fixed off-by-one crash when navigating to message from FTS.
Related to #8145
2018-09-08 07:48:20 -07:00
Greyson Parrelli
da60cac833 Fix PersistentBlobProvider problems with external storage.
If the user has an external SD card set as their default storage
(notably on a Huawei device, like the Huawei Mate 10 Lite), then
PersistentBlobProvider will try to write a file to the SD card, but
would fail to generate a URI for it due to us missing a line in our
FileProvider setup. This just adds that missing entry.

Special thanks to @aleb2000 for digging into this!

Fixes #8144
Fixes #7726
2018-09-08 07:48:20 -07:00
Greyson Parrelli
db9bfb4b2f Update ExoPlayer to 2.8.4 2018-09-08 07:48:20 -07:00
Greyson Parrelli
c3bdc48ee3 Create placeholder ContentProviders for database observations.
Required for the API 26 migration.

See https://developer.android.com/about/versions/oreo/android-8.0-changes#ccn
2018-09-08 07:48:20 -07:00
Greyson Parrelli
1c75f375c3 Bump version to 4.25.10 2018-09-07 17:59:33 -07:00
Greyson Parrelli
7c5e1db6a2 Fix NPE in MultiDeviceContactUpdateJob.
Fixes #8180
2018-09-07 17:52:50 -07:00
Greyson Parrelli
82c0ea792a Fix animation crash.
Shoutout to @bomba1990 for fixing this around the same time as me :)

Fixes #8182
2018-09-07 17:52:50 -07:00
Greyson Parrelli
70eecb754e Address bugs in notification channel backup restore. 2018-09-07 17:49:15 -07:00
Greyson Parrelli
ad036b0d6a Fix backup restore issues from restoring newer Signal backups.
Fixes #8184
2018-09-07 16:08:45 -07:00
Greyson Parrelli
15b4517e35 Prevent restoring newer backups into older versions of Signal.
Relates to #8184
2018-09-07 15:54:38 -07:00
Greyson Parrelli
d2a8abe769 Bump version to 4.25.9 2018-09-04 18:12:13 -07:00
Greyson Parrelli
8d43fb850d Make group notifications use the latest sender's ringtone. 2018-09-04 18:10:47 -07:00
Greyson Parrelli
11d34512a0 Fix double notifications in O+. 2018-09-04 18:10:42 -07:00
Greyson Parrelli
604e5d788e Bump version to 4.25.8 2018-09-04 11:13:54 -07:00
Greyson Parrelli
73b18fc1dd Fix NotificationChannel backup import.
We were recreating the channels before the database upgrade. We
have to do it after.

Fixes #8174
2018-09-04 10:57:33 -07:00
Greyson Parrelli
d9ba6962c7 Fixed NPE during channel update. 2018-09-03 17:48:55 -07:00
Greyson Parrelli
5cc91274d1 Bump version to 4.25.7 2018-08-31 12:01:46 -07:00
Greyson Parrelli
3da1a3e270 Restore notification channels after backup. 2018-08-31 12:00:46 -07:00
Greyson Parrelli
e840dc6687 Move notification preferences back in-app for O+.
Fixes #8147
2018-08-31 11:10:54 -07:00
Greyson Parrelli
3f9ddaf409 Update the Android Transifex links in CONTRIBUTING.md. 2018-08-30 08:21:55 -07:00
Joshua Lund
005188735a Update the Transifex links in CONTRIBUTING.md. 2018-08-30 08:18:34 -07:00
Greyson Parrelli
a6e4114151 Bump version to 4.25.6 2018-08-27 10:31:21 -07:00
Greyson Parrelli
5d91a94252 Fix shortcut images being too large.
We were hitting the transaction limit size. This change scales down
shortcut icons to be at most 300x300, which comes out to ~360kb, which
should be safely under the limit of 1mb.

Fixes #8139
2018-08-25 10:40:58 -07:00
Greyson Parrelli
25db207e24 Bump version to 4.25.5 2018-08-24 12:13:39 -07:00
Greyson Parrelli
ab58eab9f4 Fix potential crash with recipient preferences. 2018-08-24 12:00:02 -07:00
Greyson Parrelli
96c39ec100 Updated language translations. 2018-08-24 11:53:40 -07:00
Greyson Parrelli
c5309ce11e Bump version to 4.25.4 2018-08-22 16:30:54 -07:00
Greyson Parrelli
cedab7f504 Fix migration of group names when creating Notification Channels. 2018-08-22 14:19:37 -07:00
Greyson Parrelli
ca2efcac8a Added safeguards during NotificationChannel creation.
We were getting an IllegalArgumentException during channel creation on
some Samsung phones. Stack trace didn't give me much more than that, so
just adding in some additional safeguards that make sense based on
reading AOSP.
2018-08-22 13:19:59 -07:00
Greyson Parrelli
f1efe2b589 Use correct in-thread message tone on O+.
We manually play the ringtone when in-thread notifications are enabled,
but we weren't using the sound specified by the channel in the system
settings. This fixes that problem by reading the NotificationChannel
setting.
2018-08-22 11:58:41 -07:00
Greyson Parrelli
54715e9c43 Bump version to 4.25.3 2018-08-21 11:16:48 -07:00
Greyson Parrelli
e1f8e87327 Fix log submission OOM, improve log scrolling.
We were getting a TransactionTooLargeException when giving an
EditText a very large (1.5MB+) text block. This has been resolved
by switching to a RecyclerView to show the text line-by-line. As a
side-effect, this improves scroll performance on lower-end devices.

Also, I added a button to jump to the bottom of the log because I
really wanted one :)

Fixes #8124
2018-08-20 01:24:36 -07:00
Greyson Parrelli
88d94cad92 Substantially improve Scrubber performance.
Previously, we were making a new copy of the entire source string after
every scrubbed substitution. In the case of our new, larger log files,
this was very slow. It's been changed so we only ever create one new
copy.

In practice, on a Moto E (2014), scrubbing a 1.5MB log went from
>4000ms to ~100ms.
2018-08-19 23:19:08 -07:00
Greyson Parrelli
7370bbacea Fix inline animation toggle initial transition.
Fixes #8116
2018-08-17 16:07:13 -07:00
Greyson Parrelli
e9b85a10a6 Add per-contact notification channels.
Fixes #8119
Fixes #8121
Fixes #8122
2018-08-17 15:51:01 -07:00
Greyson Parrelli
e23fd9d491 Bump version to 4.25.2 2018-08-15 13:41:02 -07:00
Greyson Parrelli
c49b0348bd Add failsafe for invalid shortcuts.
Some launchers may create broken shortcuts, so we just want to have
a smooth fallback in that scenario.

Fixes #8109
2018-08-15 12:48:04 -07:00
Greyson Parrelli
3c6b8bcf9b Hide inline attachment button when attachment present. 2018-08-15 12:35:41 -07:00
Greyson Parrelli
a6473bc922 Link priority setting to message channel setting on Oreo+
When using notification channels, us setting priority actually has
no effect. So instead of having a non-functional setting, we've
routed the notification priority setting to go to the system
notification channel settings page for our Messages channel.
2018-08-15 12:11:10 -07:00
Greyson Parrelli
10a790df88 Fix notifications triggering too often. 2018-08-14 20:19:25 -07:00
Greyson Parrelli
b79748bbb1 Change lock status channel name to 'lock status'. 2018-08-14 16:59:21 -07:00
Greyson Parrelli
7eeafee1c2 Bump version to 4.25.1 2018-08-14 13:28:00 -07:00
Greyson Parrelli
eabaead700 Revert "Fingerprint unlock UX improvements"
This reverts commit 8441ac4091.

Fixes #8106
2018-08-14 13:04:33 -07:00
Greyson Parrelli
d581525a61 Fix Log secret reading.
Accidentally typed '>' instead of '>='.

Fixes #8107
2018-08-14 15:09:24 -04:00
Greyson Parrelli
f9adb4e455 Bump version to 4.25.0 2018-08-13 18:38:59 -04:00
Greyson Parrelli
d79564021f Remove extra space below notification text.
Special thanks to @dwong

Fixes #7905
2018-08-13 18:38:59 -04:00
Greyson Parrelli
2acbea014b Fix videos losing their extension after forwarding.
Special thanks to @signalien

Fixes #7783
2018-08-13 18:38:59 -04:00
Greyson Parrelli
2882ef6d9f Reset register button status after an error.
Fixes #8052
2018-08-13 18:38:59 -04:00
art1fa
8441ac4091 Fingerprint unlock UX improvements 2018-08-13 18:38:59 -04:00
Greyson Parrelli
20c896413b Stop linkifying addresses.
Address linkification on Android is pretty busted, and the docs
acknowledge it (see Linkify#MAP_ADDRESSES). Safest thing to do
at the moment is remove it. Looks like we may be able to get
better address linkification on API >= 28, but adding it will
be more involved.

Fixes #7730
2018-08-13 18:38:59 -04:00
Greyson Parrelli
13c72779af Visually note quotes for messages you don't have.
We will now show a small footer under quotes for messages that you
don't have locally.

Also fixes #7850
2018-08-13 18:38:59 -04:00
Greyson Parrelli
4d565990c9 Add drop shadow under attachment drawer. 2018-08-13 18:38:59 -04:00
Greyson Parrelli
5cdf5499d0 Clean up shortcut code. 2018-08-13 18:38:59 -04:00
Leonard Ehrenfried
c3c44e324b Allow users to add conversation shortcuts to the home screen. 2018-08-13 18:38:59 -04:00
Greyson Parrelli
c7da83a702 Show attachment button while composing text.
Previously, we'd only show the attachment button when the user had
yet to enter any text. To add an attachment after text was entered,
you'd have to go to the three-dot menu. Now we just show a little
attach button in the text area.

I also took the opportunity to clean up other button paddings and
stuff in the compose area so things look better and react to text
sizes more predictably.
2018-08-13 18:38:59 -04:00
Greyson Parrelli
dbd42c4af2 Add notification channel support.
Bucket our notifications into channels. Required to target API 26.
2018-08-13 18:38:53 -04:00
Greyson Parrelli
d0db6aa509 Added more logging around message sending and attachment downloads. 2018-08-06 10:50:06 -04:00
Greyson Parrelli
43068e0613 Reduce usage of Log.w() 2018-08-06 10:50:06 -04:00
Greyson Parrelli
a498176043 Switch logs to use new Log class. 2018-08-06 10:50:06 -04:00
Greyson Parrelli
acb40c6133 Added new logger.
Added a new logger that persists logs for a longer duration to the
user's cache directory. Logs are encrypted. The new logs are sent
in addition to the user's logcat output.
2018-08-06 10:50:06 -04:00
Greyson Parrelli
b7d83c7a1f Make libpaste a source dependency. 2018-08-06 10:50:06 -04:00
Greyson Parrelli
1028da116f Bump version to 4.24.8 2018-08-06 10:47:44 -04:00
Greyson Parrelli
c8571d7bc7 Use correct timestamp for footer collapse.
Fixes #8071
2018-08-06 10:34:02 -04:00
Greyson Parrelli
f6951b9ae0 Bump version to 4.24.7 2018-08-03 14:09:50 -04:00
Greyson Parrelli
d42cecc32a Fix timer issue with sync messages from desktop.
Related to #8068
2018-08-03 14:08:16 -04:00
Greyson Parrelli
7d210c8e0d Bump version to 4.24.6 2018-08-02 17:15:18 -04:00
Greyson Parrelli
c5014f9471 Fix quote crash when we decode an image of 0 length.
Fixes #7983
2018-08-02 15:57:30 -04:00
Greyson Parrelli
6db3f249c6 Populate contact name when adding shared contact.
Fixes #8016
2018-08-02 15:16:51 -04:00
Greyson Parrelli
5a1ef31b49 Fix crash with moveToLastSeen() 2018-08-02 11:57:10 -04:00
Greyson Parrelli
8ca11756be Bump version to 4.24.5 2018-07-27 16:32:46 -04:00
Greyson Parrelli
76428bd19b Fix issue with author names getting cut off. 2018-07-27 16:31:39 -04:00
art1fa
faea8fd2ec Apply message bubble paddings to both top and bottom
Batch selecting messages now feels better. Fixes #8035.
2018-07-27 16:15:37 -04:00
Greyson Parrelli
79830049c4 Fix emoji vertical positioning.
Fixes #8023
2018-07-27 16:01:52 -04:00
Greyson Parrelli
1e895e960f Fix various padding and alignment issues. 2018-07-27 14:00:11 -04:00
Greyson Parrelli
a3115c14ac Use proper target for Glide bitmap requests.
Fixes #8042
2018-07-27 09:12:54 -04:00
Greyson Parrelli
c33363d0bd Bump version to 4.24.4 2018-07-26 12:58:25 -04:00
Greyson Parrelli
44856ca8cd Updated language translations. 2018-07-26 12:40:48 -04:00
Greyson Parrelli
67190774cc Jump to the oldest unread message after loading a draft. 2018-07-25 13:10:35 -04:00
Greyson Parrelli
d5a9efa96a Reduce letter spacing on Preview text. 2018-07-25 09:58:43 -04:00
Greyson Parrelli
d5753bc306 Fix spacing issue between short clustered group chats.
For short messages in a cluster, the contact photo was sometimes taller
than the actual bubble, leading to extra weird space. So instead we use
a container to hold the width of the cell, and set the avatar to be GONE
instead of INVISIBLE.
2018-07-25 01:16:48 -04:00
Greyson Parrelli
e96a02ab35 Fix next/prev message detection with fastRecords.
The previous way we were getting the next/previous record didn't take into
consideration that some records aren't in the cursor -- some are in the
fastRecords map. We now use the proper position to get the next/previous
message.
2018-07-25 00:24:49 -04:00
Greyson Parrelli
ec43c3ae5a Bump version to 4.24.3 2018-07-24 20:47:43 -04:00
Christian Ascheberg
0bb44f2034 Improve disappearing message time strings
Fixes #7501
2018-07-24 20:35:51 -04:00
Moxie Marlinspike
fbd3f3db3f Update webrtc to M68 2018-07-24 17:06:43 -07:00
Greyson Parrelli
d82e91ca20 Fix message button in conversation settings.
Switching to use our convenience methods for start texts and calls.

Fixes #8026
2018-07-24 17:15:03 -04:00
Greyson Parrelli
c7fb1d79c4 Properly show group message header after a date divider. 2018-07-24 16:33:45 -04:00
Greyson Parrelli
0ced767ef2 Use person's name in call update text. 2018-07-24 16:33:05 -04:00
Greyson Parrelli
39b27a9d7a Properly map hashed legacy colors to the new color palette.
Fixes #8021
2018-07-24 12:53:36 -04:00
Greyson Parrelli
6a1fd8b1c6 Increase difference between read/unread conversations in list.
Updating to match the design.
2018-07-24 12:34:21 -04:00
Greyson Parrelli
d8ddb142a9 Fixed bug in onMeasure() overflow safeguard.
Fixes #8008
2018-07-23 07:54:24 -07:00
Greyson Parrelli
fbbf9dede8 Bump version to 4.24.2 2018-07-20 19:05:13 -07:00
Greyson Parrelli
214658b99e Fix recording not resetting properly after a send on older API's.
Apparently onAnimationEnd is not a reliable event on some Android
versions, so I've moved to instead using a simple postDelayed() that is
the same length as the animation.
2018-07-20 19:02:19 -07:00
Greyson Parrelli
415fe3463d Don't collapse outgoing footers for pending or failed messages. 2018-07-20 18:45:18 -07:00
Greyson Parrelli
6234e56e78 Allow outgoing messages to collapse footers. 2018-07-20 18:35:04 -07:00
Greyson Parrelli
f82b2c0d3f Prevent author name from making media messages too wide.
The media size traditionally determines the bubble size, but the author
could make it wider, which would lead to rendering issues. In the case
of media attachments (images, videos, and shared contacts), we restrict
the width of the author name. When there's a number+profile name combo,
we split the space 50/50 between the two.
2018-07-20 18:24:52 -07:00
Greyson Parrelli
a4214300ec Fix crash with conversations with "uknown contact" header.
We weren't accounting for ConversationAdapter header position when
getting the next and previous record in a conversation.
2018-07-20 17:50:54 -07:00
Greyson Parrelli
6a090bd5f1 Some visual tweak fixes.
- Use correct color action bar in contact name edit activity.
- Fix compose text height to match send button height.
2018-07-20 16:37:34 -07:00
Greyson Parrelli
c9bb3dd469 Remove now-unnecessary thumbnail onMeasure(). 2018-07-20 16:16:19 -07:00
Greyson Parrelli
6fd10042fb Move expiration timer to be next to the date. 2018-07-20 16:05:14 -07:00
Greyson Parrelli
aa25f39fe9 Fix footer icon tints. 2018-07-20 15:40:13 -07:00
Greyson Parrelli
860047c2d3 Remove CornerMaskingView. 2018-07-20 14:24:04 -07:00
Greyson Parrelli
d0eaee60e9 Add additional safeguards for picking an expiration timer frame.
Fixes #8010
2018-07-20 14:08:58 -07:00
Greyson Parrelli
d303a88803 Fix quote dismiss button not showing up.
Fixes #8006
2018-07-20 14:03:03 -07:00
Greyson Parrelli
f4ef586681 Bump version to 4.24.1 2018-07-18 16:54:49 -07:00
Greyson Parrelli
8f551c8b32 Fix various redesign issues with Android 4.x.
In particular, there were many issues with drawing corners.
Unfortunately, there's no pretty way to get masking working on every
Android version, so we have to switch back to using custom backgrounds
and then using multiple masking methods depending on Android version.

Also, I had to remove attr references in drawables. They crash on 4.x.
2018-07-18 16:53:36 -07:00
Greyson Parrelli
d3e194aefe Bump version to 4.24.0 2018-07-18 09:40:20 -07:00
Jonathan Fung
85d963047e Adding a long press icon description for the Search icon
Fixes #7836
2018-07-18 09:04:42 -07:00
floesche
df9833472f Add z5 compact (E5823) to AEC blacklist
Following fixes for other models to reduce echo on callee side during Signal call. 

The problem has been reported for this model for example in #6241
2018-07-18 08:53:27 -07:00
Greyson Parrelli
99f7133afe Updated language translations. 2018-07-18 08:34:21 -07:00
Greyson Parrelli
1c023b5218 Remove unused resources. 2018-07-17 12:06:50 -07:00
Greyson Parrelli
bf692e8da3 Throttle background contact syncs to once every 6 hours.
Unfortunately, there's apps out there that trigger contact changes
very frequently. Because we listen to the system for contact
changes to tell us when to sync, that could result in us sending
an abundance of contact syncs to linked desktop instances.

This throttles contact sync requests using the following methodology:

- By default, throttle contact syncs to 6 hrs while the app is
  backgrounded.
- If a sync is throttled in the background, we set a dirty flag and
  will execute the sync the next time the app is foregrounded.
- Syncs explicitly requested by desktop are never throttled.
2018-07-17 12:06:50 -07:00
RiseT
7960a5785d Export some strings from shared contact details activity 2018-07-17 12:06:50 -07:00
Greyson Parrelli
8579c30909 Styling improvements and code cleanup. 2018-07-17 12:06:42 -07:00
Greyson Parrelli
845fcf0864 Remove ability to set group conversation colors (for now). 2018-07-17 09:54:13 -07:00
Greyson Parrelli
24b062d8dd Improve the look of message bubbles. 2018-07-17 09:53:52 -07:00
Greyson Parrelli
7cfcb62c25 Added colors and styles. 2018-07-12 10:59:29 -07:00
Greyson Parrelli
b02dda405c Use NetworkBackoffRequirement for group messages. 2018-07-12 10:59:10 -07:00
Moxie Marlinspike
bc60cba2b8 Fix default SMS app intent >= N
Fixes #7964
2018-07-10 10:14:35 -07:00
Greyson Parrelli
4df1743ed1 Bump version to 4.23.4 2018-07-09 14:57:43 -07:00
Greyson Parrelli
e3bf91b99b Get rid of old references to @drawable/icon.
Fixes #7957
2018-07-09 14:56:31 -07:00
Greyson Parrelli
d06b129156 Bump version to 4.23.3 2018-07-06 09:54:15 -07:00
Greyson Parrelli
f074c7e5b7 Fixed FAB sometimes blocking shared contact toggle.
Fixes #7968
2018-07-06 09:52:28 -07:00
Greyson Parrelli
e334f1e035 Bump verison to 4.23.2 2018-07-05 10:08:40 -07:00
Greyson Parrelli
84e2fcad54 Update UI of toggling shared contact photo. 2018-07-05 10:05:54 -07:00
Greyson Parrelli
42236d6c3d Bump version to 4.23.1 2018-07-03 17:18:23 -07:00
Greyson Parrelli
6ce8516b93 Make contact photos optional when sharing contacts.
Previously, if you had a contact photo for a user, we'd always send it
Now you can choose whether or not it is sent.
2018-07-03 17:16:50 -07:00
Greyson Parrelli
7237e919be Bump version to 4.23.0 2018-07-02 18:22:22 -07:00
Greyson Parrelli
67407ec667 Hard-code migration for full-text search. 2018-07-02 18:10:11 -07:00
Ryan Koesters
8be0fd0867 Remove reference to Pixelapse in BUILDING.md.
Pixelapse ceased functioning in November 2016.
2018-07-02 17:58:26 -07:00
RiseT
e75822c6fd Remove unused strings
- Removed unused strings
- Removed some obsolete header comments
- Removed some whitespace
2018-07-02 17:56:07 -07:00
RiseT
6a465e6589 Update locales per 2018-06-23
Translation completion >= 90%, with the exception of Irish (80%), but they've been waiting for a rather long time.

Added:
- Irish
- Kurdish
- Telugu
- Ukrainian
2018-07-02 17:49:29 -07:00
b0m0x
2290549349 add Mi A1 to hardware AEC blacklist
See #7635
2018-07-02 17:45:55 -07:00
Greyson Parrelli
bf07048d7b Use earlier read timestamp when syncing read status with desktop.
Previously, we'd always use the value desktop gave us. However, if we
have an earlier read time locally, we want to use that instead.
2018-07-02 17:39:10 -07:00
Greyson Parrelli
3134837d56 Remove plaintext backup import option.
We have our own secure backup solution built into the app now.
No need to support plaintext backups.
2018-07-02 17:11:13 -07:00
Greyson Parrelli
5d8ada0219 Update SQLCipher. 2018-07-02 16:57:06 -07:00
Greyson Parrelli
c7066c0796 Cast to MmsMessageRecord in ConversationFragment#handleForwardMessage.
Was causing a crash for MMS messages.

Fixes #7951
2018-07-02 08:56:11 -07:00
unknown
69ea116b2b Updated authenticator icons (Fixes #7908) 2018-06-29 14:38:36 -07:00
Greyson Parrelli
18756aedf6 Remove the ability to save backups to the external SD card.
The directory we were previously saving backups to on the external SD
card is actually deleted upon app uninstall and/or clearing the app's
data. There's also no reliable way to write to the root of an external
SD card (that isn't comically inconvenient), so for now it's safer if we
just move back to getting the regular 'ol standard external storage
directory (which is likely internal storage, despite its name).

Fixes #7845
2018-06-29 14:10:45 -07:00
Greyson Parrelli
290b184491 Enable shared contact sending. 2018-06-29 11:08:13 -07:00
Greyson Parrelli
707ca53a23 Bump version to 4.22.4 2018-06-28 12:54:32 -07:00
Greyson Parrelli
0d386d3c14 Fix progress bar showing for self-sends.
For self-sends, we were never marking attachments as uploaded. I made is
so that happens now, but to prevent it for showing for already-sent
messages, we also don't show controls for self-send conversations.
2018-06-28 12:07:23 -07:00
Greyson Parrelli
8e186f7c62 Bump version to 4.22.3 2018-06-27 09:48:42 -07:00
Greyson Parrelli
708cd5335d Updated language translations. 2018-06-27 09:47:58 -07:00
Greyson Parrelli
fd6d947df3 Fix ClassCastException in ThreadDatabase.
I casted too deep. Forgot about NotificationMmsMessageRecord.
2018-06-27 09:43:02 -07:00
Greyson Parrelli
6a9d19e73d Bump version to 4.22.2 2018-06-25 19:42:11 -07:00
Greyson Parrelli
c33c74960e Update libwebrtc to M67. 2018-06-25 19:41:35 -07:00
Greyson Parrelli
f11f99366d Bump version to 4.22.1 2018-06-25 14:32:02 -07:00
Greyson Parrelli
8af076a796 Restore res/values-be/strings.xml 2018-06-25 14:28:54 -07:00
Greyson Parrelli
28dc477b54 Bump version to 4.22.0 2018-06-25 12:18:39 -07:00
Greyson Parrelli
7fb53edc3c Updated language translations. 2018-06-25 12:18:04 -07:00
Greyson Parrelli
381547d668 Fix crash with formatting emails in recipient settings.
Fixes #7868
2018-06-22 13:24:36 -07:00
Greyson Parrelli
f72f75ee61 Show a link for privacy policy. 2018-06-22 13:09:43 -07:00
Greyson Parrelli
b39a7ac939 Add expiration time to group update requests. 2018-06-22 11:29:16 -07:00
Greyson Parrelli
b5d4cac90a Send/receive expiration times for group updates.
This particularly helps with the bug where people who were newly added
to a group wouldn't receive an expiration timer until the first message
was sent.
2018-06-22 11:01:55 -07:00
Greyson Parrelli
20cc6f4d0e Return registration permission string to previous value. 2018-06-22 10:59:53 -07:00
riyapenn-signal
b9c337d0b7 Updated for small copy change 2018-06-22 10:59:53 -07:00
riyapenn-signal
3654856be5 Updated strings.xml to include minor copy changes
- Permission prompt to include text about backups
- Updated support email
- Updated domain to signal.org in a link
2018-06-22 10:59:53 -07:00
Greyson Parrelli
4f72f4c649 Remove unused string. 2018-06-22 10:59:53 -07:00
Greyson Parrelli
dae655fd01 Fix conversation snippet for contact shares.
Previously, contact shares would be displayed as "Media Message". Now
it'll show the same as it does in a notification, namely
"{contact-emoji} {contact-name}".
2018-06-22 10:59:53 -07:00
Greyson Parrelli
933be54035 Update scheduling of ServiceOutageDetectionJob.
Previously, we were running this job in PushSendJob#onCanceled().
However, with the new retry logic, this won't happen for 24 hours.

Instead, we now schedule the job in PushSendJob#onRetry().
2018-06-22 10:59:53 -07:00
2-4601
f1d8fd8838 Add devices to hardware AEC blacklist
- Moto G4
- Nokia 5 (TA-1053)

Alleviates #7635
2018-06-22 10:59:53 -07:00
Greyson Parrelli
a50edc3d25 Keep retrying message sends for 24 hours.
Previously, we retried based on a count. Now we've added the ability to
keep retrying for a specified time, using exponential backoff to
throttle attempts.
2018-06-22 10:59:53 -07:00
Greyson Parrelli
cddb8082f4 Remove unnecessary maven repo. 2018-06-22 10:59:53 -07:00
Greyson Parrelli
62c42a3513 Fix disappearing message corner case.
We never properly registered the ExpirationListener, meaning we were
relying on the wait-notify loop of ExpirationManager to delete things.
This normally works, but fails when your phone goes to sleep. So I
properly registered the receiver, and then added a failsafe to re-run
the ExpirationManager if we're about to render an expired message.

Fixes #7906
2018-06-22 10:59:53 -07:00
Greyson Parrelli
42f1baaf61 Imported JobManager as a source dependency.
We have to make some changes, and it's gotten to the point where
maintaining it as a separate library is more hassle than it's worth,
especially with Google releasing WorkManager as the preferred job
scheduling library.
2018-06-22 10:59:53 -07:00
Greyson Parrelli
5f99470226 Allow searching for words with apostrophes.
Previously, because apostrophes were 'banned' characters, searching for
them wouldn't work. That meant you couldn't find words like "I'm". Now
we just replace the apostrophe with a space and things "just work"
because of the nature of SQLite tokenization and prefix queries.
2018-06-22 10:59:53 -07:00
Greyson Parrelli
afec9e8cb0 Improve highlighting in search results.
Previously, we didn't support highlighting search results that had
tokens in the middle of the matches, which is a possibility with FTS.
Now we do more robust highlighting, as well as highlight matches in
phone numbers.
2018-06-22 10:59:53 -07:00
Greyson Parrelli
89fd7dda23 Break FTS queries into multiple prefix queries.
Previously, we made each full-text search query a single prefix query.
That means that the query "do c" would turn into "do c*". That means it
would match "do cat" but not "dog cat".

Now, we make each token a prefix query. So "do c" would turn into
"do* c*". That means it would match both "do cat" and "dog cat".
2018-06-22 10:59:53 -07:00
Greyson Parrelli
3563efc7de Update search query results when messages disappear.
Previously, if a message disappeared while looking at it in the search
results, it'd still stick around. Now they'll disappear from the results
in real-time.
2018-06-22 10:59:53 -07:00
Greyson Parrelli
febf3c249e Bump version to 4.21.6 2018-06-22 10:39:16 -07:00
Greyson Parrelli
ea4ac9db30 Fixed issue where self-sends didn't auto download.
1) There was an issue where we wouldn't auto-download group syncs.
2) There was another issue where we didn't show the download controls
   for messages you sent yourself.

Fixed #7920
2018-06-22 10:37:07 -07:00
Greyson Parrelli
e6277c0544 Bump version to 4.21.5 2018-06-21 19:10:04 -07:00
Greyson Parrelli
71a34dac5f Fix backup/import issue with expiring messages.
There was an issue where we were backing up group receipts and attachments
that were for expiring messages (which are already excluded from the backup).

This commit excludes these items from the backup, and for backups made
before this change, this commit also deletes these invalid entries at
the end of the restore process.

We also do a little database migration to cleanup any bad state that may
have been imported in the past.
2018-06-21 19:07:27 -07:00
Greyson Parrelli
61b2da9c8a Fix NPE during busy call. 2018-06-21 18:47:14 -07:00
Greyson Parrelli
d6ac17d0ee Bump version to 4.21.4 2018-06-20 13:25:53 -07:00
Greyson Parrelli
3a85c966d0 Fix false-positive outage detection.
Turns out that there's some weird quasi-state when you come out of
airplane mode, that if you do an InetAdress lookup, it returns some
weird IPv6-looking garbage address. Going to retry in that scenario
instead of assuming an outage.
2018-06-20 13:24:33 -07:00
Greyson Parrelli
f8747748f9 Bump version to 4.21.3 2018-06-20 07:33:25 -07:00
Greyson Parrelli
cc1350ba5b Updated language translations. 2018-06-20 07:32:24 -07:00
Greyson Parrelli
bb7a33ed8e Bump version to 4.21.2 2018-06-18 16:33:00 -07:00
Greyson Parrelli
fe4ce88439 Revert "Upgrade SQLCipher to respect a max window size."
This reverts commit dace93abb3.
2018-06-18 16:24:35 -07:00
Greyson Parrelli
2c7769ae26 Bump version to 4.21.1 2018-06-18 14:33:44 -07:00
Greyson Parrelli
542e962be9 Fixed crash when ScribbleView failed to save.
Previously, if an operation failed, we set the result to "null".
However, this was a mistake. Setting the result at all assumes success.
Instead, we need to set an exception so the ListenableFuture knows that
the operation failed.
2018-06-18 14:33:44 -07:00
Greyson Parrelli
e65cd2636b Bump version to 4.21.0 2018-06-18 14:33:44 -07:00
Greyson Parrelli
2c17b54ef9 Show a banner in the event of a service outage.
We will now determine if there has been a service outage and render a
banner at the top of the conversation list if we detect that there has
been one.
2018-06-18 14:32:45 -07:00
Greyson Parrelli
0999359454 Improve the image editor.
A variety of improvements to the image editor, such as:

- New, fullscreen styling
- Smoother lines
- Better text and sticker handling
- Improved color picker with a history pallette
- New highlighter tool
2018-06-18 14:32:45 -07:00
Greyson Parrelli
dace93abb3 Upgrade SQLCipher to respect a max window size.
Previously, SQLCipher's memory usage would grow indefinitely, up until
it hit the end of the cursor. We've now switched to a release where the
memory  used by the cursor can be bounded.
2018-06-18 14:32:45 -07:00
Greyson Parrelli
eed2c6ec4c Added adaptive icon support.
Also moved our non-adaptive app icon into the mipmap folders, which is
where they should be.

Fixes #7607
2018-06-18 14:32:45 -07:00
Greyson Parrelli
df2c5d38b0 Don't notify new users if there is a pending SQLCipher migration.
If a user is upgrading to use the SQLCipher database (which happened
back in 4.16, so this only applies to relatively dormant users who are
just getting back into the app) and received a new "user X joind signal"
message, then it could screw up the migration. So we're just dropping
these notifications that happen in this narrow window.
2018-06-18 14:32:45 -07:00
Greyson Parrelli
a6b6775aa1 Bump version to 4.20.9. 2018-06-18 14:11:50 -07:00
Greyson Parrelli
79857b98b3 Fix bug with quoted reply notifications. 2018-06-18 14:08:47 -07:00
Greyson Parrelli
0c3535cff8 Bump version to 4.20.8 2018-06-14 11:13:04 -07:00
Greyson Parrelli
626e6930a5 Fix search header rendering after rotation.
The sticky header cache was keeping views across rotations, causing them
to render incorrectly afterwards. I added a method to invalidate the
header layouts after rotation.

Fixes #7890.
2018-06-14 10:50:21 -07:00
Greyson Parrelli
44f5cc9070 Annotate methods in AttachmentUtil as @WorkerThread. 2018-06-11 11:08:25 -07:00
Greyson Parrelli
e45a4b86d8 Bump version to 4.20.7 2018-06-11 10:48:24 -07:00
Greyson Parrelli
30be732ae8 Don't auto-download attachments from unknown contacts. 2018-06-11 10:47:27 -07:00
Greyson Parrelli
643dd0b679 Bump version to 4.20.6 2018-06-06 20:14:05 -07:00
Greyson Parrelli
2b45b3caa2 Fixed export and restore of FTS tables.
First, FTS index contents do not need to be exported. They will be recreated naturally.

Second, we can't export the secret FTS tables, or SQLite will think it's corrupted.
2018-06-06 20:12:17 -07:00
Greyson Parrelli
b7282589de Fixed issue with backup and restore when creating new tables.
Fixes #7863
2018-06-06 09:07:38 -07:00
Greyson Parrelli
6bc7f2a5a4 Fix NPE in FTS when snippet is null. 2018-06-06 08:08:52 -07:00
Greyson Parrelli
3731e2a74a Fix jumbomoji rendering and EmojiTextView resizing.
Fixed an issue where jumbomoji were not properly being rendered
when using system emoji. Also fixed an issue where the text
content wasn't properly being recalculated when the view is
resized.

Fixes #7875
2018-06-06 07:57:03 -07:00
Greyson Parrelli
bb40f38124 Bump version to 4.20.5 2018-05-29 13:42:21 -04:00
Greyson Parrelli
f0e5aa312e Allow EmojiTextView to redraw after changing emoji setting.
Also just fixed some minor formatting issues.
2018-05-28 17:20:28 -04:00
Greyson Parrelli
ceafb0d130 Reduce emoji flickering and other ellipsize woes.
1. Switch to using default text rendering if there's no emoji present in
the string.

2. Reduce redudant redraws by skipping of setText() calls for identical
strings.

Together, these two changes should reduce the vast majority of
flickering we see with EmojiTextView ellipsizing.
2018-05-24 13:32:56 -04:00
Moxie Marlinspike
70c2a863cc Correctly store backup
Fixes #7831
2018-05-24 09:57:16 -07:00
Greyson Parrelli
d813275f42 Increase number of recent conversations shown when sharing.
Intended to reduce the pain of #7202.
2018-05-24 10:25:58 -04:00
Greyson Parrelli
5650a02cfb Sort search results exclusively by date.
I think I was initially lured into searching by rank because it gives
the illusion of providing the "best match". However, in practice, FTS
never gives back "bad" matches with low ranks -- all of the results it
returns will contain your query in some form (most commonly a direct
substring, but they do take some liberties if you have multiple tokens
in your queries). Given that, in general, more recent search results are
in fact more relevant, we can sort by date exclusively and get a better
ordering overall.
2018-05-24 09:39:57 -04:00
Greyson Parrelli
0503c9eea5 Prevent replies on action messages.
Fixes #7829
2018-05-23 15:16:42 -04:00
Greyson Parrelli
abae419853 Flatten multiline text snippets in search results.
If a search result snippet spans two lines, we only show the first line.
For the purpose of display, we first remove all newlines in order to
make the full snippet visible.
2018-05-23 14:32:46 -04:00
Greyson Parrelli
71ccbf2a1b Secondarily sort search results by date.
This should help with getting back search results that more closely
match user intention.
2018-05-23 14:17:43 -04:00
Greyson Parrelli
92a64f59a4 Switch search to use the existing header.
Probably best to not try out any possible new design changes just yet.
Let's stick with what we have.
2018-05-23 11:06:07 -04:00
Greyson Parrelli
6d56447de2 Bump version to 4.20.4 2018-05-23 08:36:25 -04:00
Greyson Parrelli
e189fff856 Fixed some cursor-related bugs in Search. 2018-05-23 08:32:46 -04:00
Greyson Parrelli
8fc63c4d78 Bump version to 4.20.3 2018-05-23 08:28:50 -04:00
Greyson Parrelli
e6e8416aec Use correct recipient for message search results.
Previously, we'd always use the recipient of the message record, which
was incorrect for messages sent to groups. Now we always use the
recipient for the matching thread record.

Fixes #7823
2018-05-23 08:22:08 -04:00
Greyson Parrelli
a792a6e6ae Fixed ThumbnailView sizing problems.
Glide will use the dimensions of the target ImageView as the dimensions
for the image it's loading. This caused problems in the case of
ThumbnailView, as we were constantly changing the ImageView dimensions,
meaning Glide may not have the most recent values (it may be called in
between measure calls, for instance).

To solve this, we now will always override the default image dimensions
when we load an image. If no dimensions are present, we will default to
the layout_width and layout_height of the ThumbnailView.

Fixes #7810
2018-05-22 17:03:51 -04:00
Greyson Parrelli
07e8ae716c Fix EmojiTextView regression.
Using the singleLine attribute will make the TextView report that the
lineCount is always 1, regardless of actual text length. This breaks our
manual ellipsize calculation. Because you can't actually read the
singleLine attribute at runtime, I've switched relevant usages of
singleLine to use maxLines=1 (relevant usages are EmojiTextViews where
singleLine was set and ellipsize was set to 'end').

Fixes #7744
2018-05-22 14:20:50 -04:00
Greyson Parrelli
0b1b568893 Fix notifications for replies.
Notifications for replies will no longer display as a "Media Message" if
they do not contain media. Instead, they will just contain the reply
text.

Fixes #7798
2018-05-22 13:12:13 -04:00
Greyson Parrelli
3a827d1c48 Fix dark theme in search.
Fixed #7821
2018-05-22 12:37:00 -04:00
Moxie Marlinspike
622b3afce0 Update build instructions 2018-05-22 08:25:44 -07:00
Moxie Marlinspike
107f6b4277 Bump version to 4.20.2 2018-05-22 07:17:49 -07:00
Moxie Marlinspike
32b608ff2f Updated language translations 2018-05-22 07:17:24 -07:00
Greyson Parrelli
eb42b7b26a Bump version to 4.20.1. 2018-05-21 19:59:56 -04:00
Greyson Parrelli
93effc8890 Disable contact sending. 2018-05-21 19:57:50 -04:00
Greyson Parrelli
5d75f11cbc Bump version to 4.20.0. 2018-05-21 17:19:03 -04:00
Greyson Parrelli
0449647cf9 Implemented full-text search.
You can now use the search bar on the conversation list to find
conversations, messages, and contacts.
2018-05-21 16:36:59 -04:00
Greyson Parrelli
c0b75c2ef5 Disable shared contact sending.
Sending shared contacts isn't backwards-compatible, so we want to have a
few releases where receiving is enabled, but not sending. That way, when
we enable sending, most users should be able to properly receive the
shared contact messages.
2018-05-21 15:45:22 -04:00
Greyson Parrelli
ca260a92e3 Convert vCard attachments to Shared Contacts.
When you share a vCard from an external app (like the Contacts app) into
Signal, we'll now convert it to a pretty Shared Contact message and
allow you to choose which fields of the contact you wish to send.
2018-05-21 15:45:22 -04:00
Greyson Parrelli
e6c16cf28d Allow editing of contact names.
Took care to properly format CJK names.
2018-05-21 15:45:22 -04:00
Greyson Parrelli
54dbffaf30 Added ability to share contacts.
The "contact" option in the attachments tray now brings you through an
optimized contact sharing flow, allowing you to select specific fields
to share. The contact is then presented as a special message type,
allowing you to interact with the card to add the contact to your system
contacts, invite them to signal, initiate a signal message, etc.
2018-05-21 15:45:22 -04:00
Greyson Parrelli
17dbdbd0a9 Handle quote position task finishing after fragment detaches.
There's a chance that the AsyncTask that retrieves a quoted message's
position could finish after the fragment is detached, which would cause
a crash. I've changed it so if this case occurs, the result is ignored.

Also, I noticed that when searching the message table, if a quote can't
be found, we'd end up traversing the entire table. To prevent this from
taking forever on large message tables, I've limited it to searchin only
what is currently present in the adapter.

Fixes #7756
2018-05-21 15:45:22 -04:00
Greyson Parrelli
ca8fecea9c Clean up camera flipping, handle having missing cameras.
Did a refactor to better organize the camera flipping code. Also, I
wanted to make sure we handle the cases where the user doesn't have two
cameras (or no cameras, for that matter). In these cases, we just don't
show the appropriate buttons.
2018-05-21 15:45:22 -04:00
Niklas Hambüchen
f1c79eaebf Add button to flip camera (front vs rear). Fixes #6279 2018-05-21 15:45:22 -04:00
Moxie Marlinspike
6c1a1fb9ad Use cache directory on removable storage for backups if present
Fixes #7692
2018-05-21 15:45:22 -04:00
Moxie Marlinspike
35d158cfee Treat Permissions "not now" as a denial
Fixes #7713
2018-05-21 15:45:22 -04:00
Moxie Marlinspike
a5047cb17b Fix for sender's expiring messages in group with unregistered user
Fixes #7719
2018-05-21 15:45:22 -04:00
Moxie Marlinspike
5006b36e2d Show lock notification immediately after setting is toggled
Fixes #7659
Closes #7678
2018-05-21 15:45:22 -04:00
Moxie Marlinspike
c6e20f715b Merge pull request #7782 from jlund-signal/contributing-updates
Update the contribution guidelines.
2018-05-20 05:18:43 -07:00
Joshua Lund
fcc9c2778d Update the contribution guidelines. 2018-05-10 10:52:00 -06:00
Moxie Marlinspike
e20b973872 Add local backup listener to manifest 2018-05-06 23:52:36 -07:00
Moxie Marlinspike
7951df09ad Bump version to 4.19.3 2018-04-26 17:48:43 -07:00
Greyson Parrelli
f580edaf91 Fix voice recording UI when replying to a message.
Just had to relayer some of the views so the recording UI positions
correctly lined up at the bottom.
2018-04-26 17:43:35 -07:00
Greyson Parrelli
102941c18c Fix QuoteView measuring when voice notes are present.
Fixes #7740
2018-04-26 17:41:37 -07:00
Moxie Marlinspike
0c8b2b23da Bump version to 4.19.2 2018-04-26 09:33:35 -07:00
Moxie Marlinspike
aa33be6b03 Updated language translations 2018-04-26 09:33:03 -07:00
Greyson Parrelli
43622e603d Save replies in drafts.
Previously, quotes were not saved to drafts, meaning they would be lost
when leaving the conversation or app. Now, a QuoteId (which represents
the necessary data to restore the QuoteModel) is serialized and stored
in the DraftDatabase.

Fixes #7716
Closes #7729
2018-04-26 09:19:22 -07:00
RiseT
7100030c22 Export string conversation_context__menu_reply_to_message
Additionally changed from "Reply" to "Reply to message" as other
related strings are more comprehensive as well.

Closes #7732
2018-04-25 10:41:26 -07:00
Greyson Parrelli
63a3b1acb9 Also make author text EmojiTextView. 2018-04-24 12:18:33 -07:00
Greyson Parrelli
6fbbc9d078 Render emoji's properly in quote bubbles.
Unfortunately, the change wasn't as simple as just switching to use our
EmojiTextView. That view only supported single-line text. I added
support for multi-line text.

Fixes #7704.
2018-04-24 12:18:33 -07:00
Greyson Parrelli
cbe394025d Fix reply-to colors in dark mode to increase contrast.
Fixes #7705
2018-04-20 17:35:48 -07:00
RiseT
29af1669e1 Export strings from registration_call_me_view
Export strings from webrtc_call_screen

Closes #7543
2018-04-19 18:03:45 -07:00
Nicholas Rizzio
e6f76159b0 Export "creating backup" string
Closes #7656
2018-04-19 17:59:31 -07:00
Henning Dodenhof
e0603abdd3 Use FileProvider for update file handling
Fixes #7654
Closes #7658
2018-04-19 13:30:21 -07:00
Moxie Marlinspike
2a1ce859c4 Add Moto G (5S) Plus to hardware AEC blacklist
For #7635
2018-04-19 10:58:39 -07:00
Moxie Marlinspike
8452fc6c58 Correctly avoid displaying about category in groups
Fixes #7702
2018-04-19 10:53:37 -07:00
Moxie Marlinspike
2ac0179d65 Handle odd sized buffers on backup import decrypt
Fixes #7701
2018-04-18 21:20:06 -07:00
Moxie Marlinspike
8b74e9a075 Bump version to 4.19.1 2018-04-18 10:40:49 -07:00
Moxie Marlinspike
afbf6a91bb Bump version to 4.19.0 2018-04-18 10:15:00 -07:00
Moxie Marlinspike
8e2ae6c288 Updated language translations 2018-04-18 10:12:56 -07:00
Greyson Parrelli
fa99e8f0d0 Updated reply-to UI.
All UI components are now properly styled and functioning according to
spec.
2018-04-16 17:33:26 -07:00
Moxie Marlinspike
d567534609 replies 2018-04-16 17:33:26 -07:00
Moxie Marlinspike
8bec5a96f5 Make delivery receipts work correctly on CDMA networks
Fixes #7646
2018-04-16 17:33:26 -07:00
Moxie Marlinspike
d8a6fcf979 Retain latest 2 instead of latest 5 backups
Fixes #7650
2018-04-16 17:33:26 -07:00
Moxie Marlinspike
4669c45ff7 Perpetuate the original sin of dark theme
Fixes #7614
2018-04-16 17:33:26 -07:00
Moxie Marlinspike
2c405d1769 Delete raw contacts that are marked for deletion
Fixes #7628
2018-04-16 17:33:26 -07:00
Moxie Marlinspike
821957137a Check for context liveness to prevent NPE
Fixes #7633
2018-04-16 17:33:26 -07:00
Greyson Parrelli
b8fbc91f33 Only show copy if text is selected, remove newlines from copied text.
We now check if _any_ text is selected when doing a batch selection
to determine if we should show the copy option. Also, previously it
was putting in empty lines for messages that don't have any text. I
changed it so empty messages have no effect on the text that is copied.

Fixes #7472
2018-04-16 17:33:26 -07:00
FeuRenard
404610fbcd Pass correct address from media overview to preview
Fixes #7384
Closes #7387
2018-04-16 17:33:26 -07:00
Moxie Marlinspike
3f3d7f549b Make an attempt to store/retrieve backups from removable storage
Fixes #7521
2018-04-16 17:33:26 -07:00
Moxie Marlinspike
7dd8baba5a Add permission callback to preference fragment 2018-04-16 17:33:26 -07:00
Moxie Marlinspike
eb0af13887 Fix location URL encoding
Fixes #7604
2018-04-16 17:33:26 -07:00
Moxie Marlinspike
72310ed3c6 Group member dialog tap takes you to recipient preference
Fixes #7463
2018-04-16 17:33:26 -07:00
Moxie Marlinspike
e86a9ce7eb Add phone number and direct dial to recipient preferences 2018-04-16 17:33:26 -07:00
Moxie Marlinspike
c2c180e38d Bump version to 4.18.3 2018-04-12 17:19:44 -07:00
Moxie Marlinspike
0b0853a223 Clear cache on update 2018-04-12 17:19:18 -07:00
Moxie Marlinspike
c573d5703b Bump version to 4.18.2 2018-04-09 09:10:05 -07:00
Moxie Marlinspike
8da8867bac Update language translations 2018-04-09 09:09:58 -07:00
Moxie Marlinspike
ccc3ff4aac Fix for Glide image caching issue
Fixes #7630
2018-04-09 09:03:42 -07:00
Moxie Marlinspike
ca471b1408 Explicitly remove messages.db journal
Fixes #7636
2018-04-05 03:50:33 -07:00
Moxie Marlinspike
c3882e9d51 Bump version to 4.18.1 2018-04-04 05:09:55 -07:00
Moxie Marlinspike
3bceb0d8ec Delete old message DB 2018-04-04 05:09:43 -07:00
Moxie Marlinspike
0753ff85ed Default snippet type to 0 if it's null
Fixes #7551
2018-04-03 08:59:19 -07:00
Moxie Marlinspike
5f7c30e840 Remove some old tests
Fixes #7458
2018-04-03 00:53:29 -07:00
Moxie Marlinspike
b9f99f9941 Manually calculate length of attachments if they're super old
Fixes #7560
2018-04-02 10:03:26 -07:00
Moxie Marlinspike
2c82b3610d Mark DB current after backup upgrade process
Fixes #7596
2018-04-02 06:27:50 -07:00
Moxie Marlinspike
c0da061072 Bump version to 4.18.0 2018-03-31 02:21:35 -07:00
Moxie Marlinspike
90f2398219 Updated language translations 2018-03-31 02:20:53 -07:00
Greyson Parrelli
18039bc3f4 Show groups when searching for contacts.
Currently, if you're searching for a contact to start a conversation
with or send a share to (via the Android sharing system), groups do not
appear. With this change, groups will now appear when searching, located
under their own  heading.

Fixes #7202.
Closes #7577
2018-03-31 02:14:02 -07:00
Greyson Parrelli
5dc5503896 Fixed 'All Media' toolbar color mismatch.
In landscape, you'd see that the tabs were a different color from the
toolbar. This has been corrected so they're all the same color now.

Fixes #7578
Closes #7579
2018-03-31 02:14:02 -07:00
Greyson Parrelli
a573ab7c76 Setup alternate domain front.
In preparation for Google shutting down domain fronting.

Closes #7584
2018-03-31 02:14:02 -07:00
Greyson Parrelli
ea374735e1 Render images in a conversation true-to-size.
Previously, we were always rendering images as squares. Instead of doing
that, we now render them as close to true-to-size as possible (within
reasonable min/max width/height boundaries).
2018-03-31 02:14:02 -07:00
Moxie Marlinspike
9f8b4cf892 Populate incoming attachments with width and height from message 2018-03-31 02:14:02 -07:00
Moxie Marlinspike
3c30db7edf No longer generate image thumbnails manually
Delete manually calculated image thumbnails
2018-03-31 02:14:02 -07:00
Moxie Marlinspike
95d76638dc Simple encrypted glide disk cache 2018-03-31 02:14:02 -07:00
Greyson Parrelli
7e1e666172 Strip EXIF metadata from all JPEG images.
Strip all EXIF metadata from all JPEGs by re-encoding the JPEG. This
will keep all of the necessary visual effects of the tags (by encoding
them directly in the image data) while stripped the EXIF tags
themselves.
2018-03-31 02:14:02 -07:00
Greyson Parrelli
10e5b24cfd Allow batch deletion of media.
It is now possible to batch-delete media in the "media overview" screen.
You can long press to enter multi-select mode. Then a delete button
appears on the menu bar. After pressing delete, you will get a
confirmation, and if the user confirms, the items will delete while a
progres dialog shows.
2018-03-31 02:14:02 -07:00
Greyson Parrelli
0c768a24e4 Allow deletion of media through preview.
When viewing a media in the media preview, you can delete it by pressing
a delete button on the action bar. It will then ask you to confirm your
choice. If you confirm, it will delete the attachment from the database
and from disk. If it was the only attachment for that message, the
message itself will also be deleted.
2018-03-31 02:14:02 -07:00
Joshua Lund
a8cf5b8efa Update the issue template.
Closes #7581
2018-03-31 02:01:26 -07:00
Moxie Marlinspike
f48f4a8812 Bump version to 4.17.5 2018-03-20 11:36:38 -07:00
Moxie Marlinspike
d6610f0dd0 Add profile avatars to backup
Fixes #7450
2018-03-19 14:10:21 -07:00
Moxie Marlinspike
261296e41b Don't crash direct share service if avatar photo is missing
Fixes #7541
2018-03-19 13:17:57 -07:00
Moxie Marlinspike
26a16bf0ca Bump version to 4.17.4 2018-03-15 16:48:22 -07:00
FeuRenard
9c0129c4b0 Allow skipping registration PIN intervals on success
Closes #7517
Closes #7518
2018-03-15 12:14:43 -07:00
Moxie Marlinspike
b168e14985 Move salt outside the loop 2018-03-15 10:18:14 -07:00
Moxie Marlinspike
73233c01ba Fix backup NPE
Fixes #7526
2018-03-14 23:40:01 -07:00
Moxie Marlinspike
90006e81db Add salt to backup header 2018-03-14 10:28:41 -07:00
Greyson Parrelli
f544b7d7b4 Reduce image stutter by using subsampling more often.
Fixes #7208.
2018-03-13 13:25:41 -07:00
Moxie Marlinspike
5f12696bed Bump version to 4.17.3 2018-03-13 09:45:43 -07:00
Moxie Marlinspike
41d06fc8c2 Simplify reminder interval lookup
Fixes #7513
2018-03-13 09:39:56 -07:00
Moxie Marlinspike
aff65abe91 Hide keyboard after backup passphrase entered
Fixes #7508
2018-03-13 09:28:27 -07:00
Moxie Marlinspike
64afce5f66 Switch to parameterized statements for backup
Fixes #7507
2018-03-13 09:27:58 -07:00
Moxie Marlinspike
52ca295131 Bump version to 4.17.2 2018-03-11 17:34:16 -07:00
Moxie Marlinspike
6b5da7f8cf Disable registration lock reminders for <=KK devices
Fixes #7500
2018-03-11 17:30:31 -07:00
Moxie Marlinspike
43d7e99a50 Don't offer backup restore on reregistration
Fixes #7502
2018-03-11 17:12:42 -07:00
平民·寻梦(Pingmin Fenlly Liu)
cc288d1e43 Just update to the new repo path "github.com/signalapp"
Closes #7469
2018-03-11 17:06:22 -07:00
FeuRenard
150601c51e Replace '1' with '%d' in plural strings
Fixes #7470
Closes #7471
2018-03-11 17:05:01 -07:00
RiseT
375ebeb661 Update Transifex locales as per 2018-03-01
Remove:
- Kannada

Add (>= 90% of strings translated):
- Burmese
- Galician
- Khmer
- Lithuanian
- Thai

Closes #7490
2018-03-11 17:03:31 -07:00
junitas
7f7aab044c Escape single quotes in SQLite entries for message backups
Fixes #7491
Closes #7497
2018-03-11 17:00:53 -07:00
Moxie Marlinspike
fd7a3190f8 Bump version to 4.17.1 2018-03-10 11:19:05 -08:00
Moxie Marlinspike
c8dd62cecf Make it possible to set a zero value for screen lock timeout
Fixes #7485
2018-03-09 15:27:20 -08:00
Moxie Marlinspike
11ce4ee807 Actually increment event count 2018-03-09 14:29:15 -08:00
Moxie Marlinspike
40d14698b8 Fix NPE introduced by #6886 2018-03-09 11:14:37 -08:00
Moxie Marlinspike
34ed55d3ac Post backup progress event for every item
Fixes #7483
2018-03-09 11:03:18 -08:00
Moxie Marlinspike
954b2f22f6 Don't immediately prompt for registration lock pin after reregistration
Fixes #7484
2018-03-09 10:41:43 -08:00
Moxie Marlinspike
b39820dcb6 Clarify Registration Lock reminder
Fixes #7484
2018-03-09 10:40:29 -08:00
Moxie Marlinspike
1a24885110 Fix issue "home button" issue with screen lock
Fixes #7475
2018-03-09 10:25:29 -08:00
Moxie Marlinspike
29fcce23b1 Prevent double screen lock intent from firing
Fixes #7475
2018-03-08 17:41:27 -08:00
Moxie Marlinspike
a2d04f4806 Prevent us from sql injecting ourselves on backup/restore
Fixes #7478
2018-03-08 16:39:57 -08:00
Moxie Marlinspike
9fb67b9f03 Bump version to 4.17.0 2018-03-08 08:49:26 -08:00
Moxie Marlinspike
46e5d64857 Updated language translations 2018-03-08 08:45:28 -08:00
Moxie Marlinspike
9c63c6045d Export string 2018-03-07 12:13:58 -08:00
Moxie Marlinspike
3c0bbfe6f0 s/External Storage/Storage 2018-03-07 12:10:38 -08:00
Andy Staudacher
61a7062030 Remove obsolete workaround for DE/FI/SK shortcodes
libphonenumber supports these since December 2015 / January 2016.
Most of these changes went into libphonenumber-7.2.2 (Dec 15, 2015),
the last changes related to this into libphonenumber-7.2.4 (Jan 28, 2016).
This was about adding EU-wide helplines 116xxx (http://ec.europa.eu/digital-agenda/en/116-helplines).
See: https://github.com/googlei18n/libphonenumber/blob/master/java/release_notes.txt

Closes #6130
2018-03-07 09:59:43 -08:00
Sam Lanning
69f180a5ec Fix some potential integer overflows for expiration time
In a number of locations in the code, there were conversions of message
expiration times from seconds to milliseconds, and then assigned to `long`
contexts. However these conversions were being done as integer multiplication
rather than long multiplication, meaning that there was a potential for
overflows.

Specifically, the maximum value that could be represented before overflowing
was (2^31 / 1000 / 60 / 60 / 24) days = 24.8 days (< 1 month). Luckily the
current allowed timeouts are all less than that value, but this fix would
remove the artificial restriction, effectively allowing values of 1000x greater
(68 years), at least for android.

Related #5775
Closes #7338
2018-03-07 09:55:24 -08:00
Andrew Gaul
10c1ee70e8 Make some inner classes static
Closes #7370
2018-03-07 09:51:05 -08:00
Win Ribeka
c5e495bfe5 Adding task affinity to the share activity. Fixes #7312.
Closes #7371
2018-03-07 09:44:11 -08:00
FeuRenard
0efda2df91 Make toast after saving attachment translatable
Closes #7374
2018-03-07 09:41:33 -08:00
art1fa
4bdb2acd29 Batch selection mode improvements
Simplified and now the same for conversation and conversation list.

Added also some styling.

Closes #7410
2018-03-07 09:38:51 -08:00
Moxie Marlinspike
56c95d1d1b Extract string resource 2018-03-07 09:36:15 -08:00
Moxie Marlinspike
d44bfc3ce3 s/password/passphrase 2018-03-07 09:34:41 -08:00
FeuRenard
527e39eee8 Don't save white space drafts
Fixes #7308
Closes #7383
2018-03-07 09:33:57 -08:00
Moxie Marlinspike
2beb1dd8d9 Layout adjustments 2018-03-07 09:08:13 -08:00
Marek Sebera
694a5de2c3 Send m-notifyresp-ind (NotifyRespInd) for retrieved MMS on Lollipop API 2018-03-06 17:34:31 -08:00
art1fa
feee09cd28 Fix color in toolbars 2018-03-06 10:14:23 -08:00
art1fa
6dd8300c73 Add standard elevation to Toolbars 2018-03-06 10:14:23 -08:00
art1fa
4281097828 Decrease back button padding / margin 2018-03-06 10:00:44 -08:00
art1fa
1e62934220 Reduce avatar size in ConversationView 2018-03-06 10:00:44 -08:00
junitas
4b5d7bbfa4 Ignore swipe events for ConversationListItemInboxZero
Fixes #7423
2018-03-06 09:35:13 -08:00
Moxie Marlinspike
f5f1305af8 Update libpastelog to 1.1.2 2018-03-05 20:17:55 -08:00
Moxie Marlinspike
110d33ddf8 Support for Registration Lock PINs 2018-03-05 16:13:56 -08:00
Moxie Marlinspike
d28dc670ea Migrate to Android fingerprints and auth for Signal screen lock 2018-03-05 16:11:49 -08:00
Moxie Marlinspike
3970a30e14 Add chunk IV to chunk MAC 2018-03-05 16:11:49 -08:00
Moxie Marlinspike
24e573e537 Support for full backup/restore to sdcard 2018-03-05 16:11:49 -08:00
Moxie Marlinspike
9f6b761d98 Migrate sessions into database 2018-03-05 16:11:49 -08:00
Moxie Marlinspike
9f3c04dfb5 Migrate prekeys into database 2018-03-05 16:11:49 -08:00
Moxie Marlinspike
6239508b39 Clean file names for belt and suspenders 2018-03-05 16:11:49 -08:00
Moxie Marlinspike
71c7ef5b5e Support for custom call ringtone selection and per-chat ringtones 2018-03-05 16:11:49 -08:00
Moxie Marlinspike
35a6ec707f Update libpastelog to 1.1.1 2018-03-01 18:19:34 -08:00
Moxie Marlinspike
8eb8f9e724 Bump version to 4.16.9 2018-02-28 10:47:49 -08:00
Moxie Marlinspike
bebdbe2aaa Remove master secret requirement from SMS received job
Fixes #7444
2018-02-28 10:45:50 -08:00
Moxie Marlinspike
eaf11744c7 Bump version to 4.16.8 2018-02-26 14:03:49 -08:00
Moxie Marlinspike
18aa202695 Really really delay SMS processing until sqlcipher migration completes
Blocking the SMS job on the screen lock isn't enough, since then
the job races against the migration.

Fixes #7390
2018-02-26 14:02:12 -08:00
Moxie Marlinspike
a0a9e412b4 Correctly lock screen when locked from conversation list
Fixes #7441
2018-02-26 10:47:41 -08:00
Moxie Marlinspike
9ebd8682b5 Bump version to 4.16.7 2018-02-24 11:12:11 -08:00
Moxie Marlinspike
028c6edd8a Manually calculate attachment offsets
The CipherInputStream skip() method is pretty non-functional

Fixes #7438
2018-02-24 11:09:26 -08:00
Moxie Marlinspike
4324f0b7ec Update libpastelog 2018-02-24 11:09:05 -08:00
Moxie Marlinspike
c940e984f0 Bump version to 4.16.6 2018-02-22 13:14:56 -08:00
Moxie Marlinspike
43bb1d2290 Updated language translations 2018-02-22 13:13:36 -08:00
Moxie Marlinspike
7318236286 Delay processing SMS messages until after sqlcipher migration
When screen lock passphrase is enabled

Fixes #7390
2018-02-21 18:49:52 -08:00
Moxie Marlinspike
a40d7158de Bump version to 4.16.5 2018-02-05 17:38:05 -08:00
Moxie Marlinspike
0bbe83f8f2 Don't copy column to sqlcipher db if it doesn't exist there
Fixes #7386
2018-02-05 17:32:24 -08:00
Moxie Marlinspike
2b651ee323 Prevent NPE in #7375 2018-02-05 12:08:40 -08:00
Moxie Marlinspike
3be45f093c Bump version to 4.16.4 2018-02-04 11:26:54 -08:00
Moxie Marlinspike
9d5d43cf3a Wait to process messages until after migration when screenlocked
Fixes #7390
2018-02-04 11:26:02 -08:00
Moxie Marlinspike
751cc0e86a Bump version to 4.16.3 2018-02-02 16:32:05 -08:00
Moxie Marlinspike
01c3244f75 Specify supported ABIs 2018-02-02 16:31:49 -08:00
Moxie Marlinspike
f17c144a60 Bump version to 4.16.2 2018-02-01 19:36:29 -08:00
Moxie Marlinspike
93ca2ad8cf Fix new conversation activity crash 2018-02-01 19:36:09 -08:00
Moxie Marlinspike
a4aac62bcb Bump version to 4.16.1 2018-02-01 19:23:29 -08:00
Moxie Marlinspike
3633d805c8 More MasterSecret cleanup 2018-02-01 19:22:48 -08:00
Moxie Marlinspike
59092e2ec0 No need for an encrypted serializer any longer 2018-02-01 18:33:12 -08:00
Moxie Marlinspike
e6a069af6d Remove unnecessary body model 2018-02-01 18:29:09 -08:00
Moxie Marlinspike
23aee53c7d Add determinte progress and foreground service for sqlcipher migration 2018-02-01 16:01:24 -08:00
Moxie Marlinspike
bdd4b456c4 Have stream generate random value 2018-02-01 15:42:28 -08:00
Moxie Marlinspike
c004ead940 Bump version to 4.16.0 2018-02-01 10:25:27 -08:00
Moxie Marlinspike
69d18dfa6a Update libsignal-service to latest 2018-01-31 19:29:19 -08:00
Moxie Marlinspike
7b353a94d8 Trigger DB schema change on application DB update Activity 2018-01-31 17:49:08 -08:00
Moxie Marlinspike
5496f5baac Deprecate encrypted storage DB types 2018-01-30 17:45:12 -08:00
Moxie Marlinspike
f36b296e2e Migrate from SQLite and ciphertext blobs to SQLCipher + KeyStore 2018-01-30 17:27:05 -08:00
Moxie Marlinspike
d1819b6361 Bump version to 4.15.5 2018-01-23 14:01:28 -08:00
Moxie Marlinspike
970e24ef26 Bump version to 4.15.4 2018-01-23 13:44:33 -08:00
Moxie Marlinspike
799b9c2074 Adjust media preview viewpager swipe direction for rtl 2018-01-23 13:43:37 -08:00
Moxie Marlinspike
14644077e7 Change media preview swipe direction based on entry point
Fixes #7354
2018-01-23 12:52:24 -08:00
Moxie Marlinspike
9939461d9e Bump version to 4.15.3 2018-01-22 11:38:54 -08:00
Moxie Marlinspike
0403cbfd65 Updated language translations 2018-01-22 11:38:29 -08:00
Moxie Marlinspike
24e6605024 Reverse media order in ViewPager
Fixes #7354
2018-01-22 09:32:27 -08:00
Moxie Marlinspike
be0ddb9756 Bump version to 4.15.2 2018-01-18 10:18:58 -08:00
Moxie Marlinspike
bc64230a65 Switch to HackyViewPager for media preview
Fixes #7344
Fixes #7335
2018-01-18 10:16:35 -08:00
Moxie Marlinspike
763fa0dd21 Catch exception on image decoding error in notification 2018-01-18 10:11:33 -08:00
Moxie Marlinspike
e60715587f Update service lib to 2.7.0 2018-01-18 10:01:41 -08:00
Moxie Marlinspike
47194e7079 Bump version to 4.15.1 2018-01-16 12:08:46 -08:00
Moxie Marlinspike
95ebae5d5f Support onStop/onStart media display in the correct position
Fixes #7330
Fixes #7329
2018-01-16 12:06:55 -08:00
Moxie Marlinspike
fe02b3f8d3 Catch exception from misconfigured MMSC
Fixes #7339
2018-01-16 11:32:51 -08:00
Moxie Marlinspike
94e2b9e66e Make video player in media player control a view stub 2018-01-16 11:21:58 -08:00
Moxie Marlinspike
d3bf6a1c59 Bump version to 4.15.0 2018-01-09 09:55:31 -08:00
Moxie Marlinspike
97244e8624 Updated language translations 2018-01-09 09:55:24 -08:00
Moxie Marlinspike
551470123d Update glide to 4.5.0 2018-01-08 17:04:39 -08:00
Moxie Marlinspike
b307980d8c Perform a contact sync with every directory refresh 2018-01-04 11:56:55 -08:00
Moxie Marlinspike
8bba45f396 Add swipe gestures to media view
Fixes #2355
Closes #6632
2018-01-04 11:11:49 -08:00
Moxie Marlinspike
34424a9b3e Fix crash when signal messages disabled in group conversation
Fixes #6419
Closes #6803
2017-12-25 15:57:33 -08:00
Joshua Lund
c4991e857d Update the API level in the build documentation. 2017-12-25 14:42:30 -08:00
vpo
05daa71977 Adjust permission request dialog colors in dark theme
Fixes #7252
Closes #7292
2017-12-25 14:39:43 -08:00
Moxie Marlinspike
da8cea9878 Update glide to 4.4 2017-12-21 17:43:24 -08:00
Moxie Marlinspike
419ef2c6f8 Update support library to 27.0.2 2017-12-21 16:38:55 -08:00
Moxie Marlinspike
a798f97aa3 Update to webrtc M64 2017-12-21 16:37:07 -08:00
Moxie Marlinspike
b17451b867 Bump version to 4.14.10 2017-12-20 11:46:14 -08:00
Moxie Marlinspike
feaea32cdd Updated language translations 2017-12-20 11:46:04 -08:00
Moxie Marlinspike
6dcec7c2c5 Fix service calls that won't foreground 2017-12-20 11:27:57 -08:00
Moxie Marlinspike
512dc19471 Fix dynamic permissions problem for MMS messages 2017-12-20 11:21:00 -08:00
Moxie Marlinspike
425d6b8adf Fix crash for dynamic permissions + background directory load 2017-12-20 11:10:12 -08:00
Moxie Marlinspike
81cd20062c Bump version to 4.14.9 2017-12-19 14:48:40 -08:00
Moxie Marlinspike
4acedd2a4b Fix notification ringtone problems
Default ringtone was often showing up as a call tone

Silent wasn't working correctly globally
2017-12-19 14:42:00 -08:00
Moxie Marlinspike
d782d3006b Per-recipient ringtones can't be file based 2017-12-19 11:01:55 -08:00
Moxie Marlinspike
9c77ffc2a4 The webrtc busy state could be idle, but system dialer connected 2017-12-19 10:57:34 -08:00
Moxie Marlinspike
0ec1ae4ed3 Request needed permissions for thread search 2017-12-19 10:54:06 -08:00
Moxie Marlinspike
6d7553563f Bump version to 4.14.8 2017-12-16 10:54:29 -08:00
Moxie Marlinspike
f22186e6f4 Debounce call screen answer button
Fixes #7274
2017-12-15 15:27:23 -08:00
Moxie Marlinspike
4de14a5dc1 Only use startForegroundService for initial service construction 2017-12-15 09:45:00 -08:00
Moxie Marlinspike
71727e1474 Bump version to 4.14.7 2017-12-13 10:30:01 -08:00
Moxie Marlinspike
f72e35bf42 Fix typo that requests SMS permission for media/group message
Fixes #7271
2017-12-13 10:29:19 -08:00
Moxie Marlinspike
a8040b00cf Bump version to 4.14.6 2017-12-12 11:17:24 -08:00
Moxie Marlinspike
303b98b7c2 Register and unregister receiver with same context
Fixes #7267
2017-12-12 11:16:40 -08:00
Moxie Marlinspike
13434d620c Bump version to 4.14.5 2017-12-11 09:56:15 -08:00
Moxie Marlinspike
d5215b3593 Avoid potentially unregistering bluetooth twice 2017-12-11 09:52:03 -08:00
Moxie Marlinspike
62489846e3 Bump version to 4.14.4 2017-12-08 15:22:08 -08:00
Moxie Marlinspike
f315b1db80 Make save attachment task toast location instead of snackbar 2017-12-08 15:21:46 -08:00
Moxie Marlinspike
f100137e0f Synchronize and copy Recipient.getParticipants 2017-12-08 14:38:01 -08:00
Moxie Marlinspike
37092eee01 Externalize strings 2017-12-08 14:36:56 -08:00
Moxie Marlinspike
261d187567 Don't perform multi-device contact update without contact perms 2017-12-08 14:36:36 -08:00
Moxie Marlinspike
907a1767f4 Bump version to 4.14.3 2017-12-07 11:58:44 -08:00
Moxie Marlinspike
bf70f830f3 Update language translations 2017-12-07 11:58:11 -08:00
Moxie Marlinspike
b58c87a56b Only notify when address is in contacts 2017-12-07 11:53:17 -08:00
Moxie Marlinspike
27d3dc918e s/External Storage/Storage 2017-12-06 11:59:29 -08:00
Moxie Marlinspike
7ba0f4b279 Bump version to 4.14.2 2017-12-05 12:08:51 -08:00
Moxie Marlinspike
23e9b3a61e Fix colors in all images toolbar
Fixes #7242
2017-12-05 12:07:37 -08:00
Moxie Marlinspike
06e0d7d72d Appease the linter 2017-12-05 11:52:03 -08:00
Moxie Marlinspike
27e11e9627 Make sure we have SEND_SMS permission before sending an SMS
Fixes #7246
2017-12-05 11:35:15 -08:00
Moxie Marlinspike
8686691a5a Fix missing recipient calculation for system contact
Fixes #7244
2017-12-05 10:27:34 -08:00
Moxie Marlinspike
8b3a3d163f Don't check subscription info on dual sim devices wihout permission
Fixes #7239
2017-12-02 12:23:14 -08:00
Moxie Marlinspike
6d0b8bd737 Bump version to 4.14.1 2017-12-01 14:05:50 -08:00
Moxie Marlinspike
53e87562c1 Updated language translations 2017-12-01 14:05:21 -08:00
Moxie Marlinspike
02c422cb26 Some old group avatar IDs can be 0
Fixes #7235
2017-12-01 13:56:56 -08:00
Moxie Marlinspike
3523952ef9 As of 'N' we can no longer offer external ringtone selection
1. Replace custom ringtone picker with system Intent, since we
   don't need it anymore. Fixes #7174

2. Make sure 'silent' ringtone selection is stored appropriately
   Fixes #7115 Closes #7141

3. Replace any existing file:// notification URIs with the system
   default Fixes #7234
2017-12-01 12:55:24 -08:00
Moxie Marlinspike
4cb2ac7b27 Use FileProvider for external camera capture Uri on L+
Fixes #7237
2017-12-01 11:06:37 -08:00
Moxie Marlinspike
4932171bbf Bump version to 4.14.0 2017-11-30 14:25:06 -08:00
Moxie Marlinspike
81c7cb1a87 Updated language translations 2017-11-30 14:24:54 -08:00
Moxie Marlinspike
2b80e98bf1 Update dockerfile 2017-11-30 14:06:21 -08:00
Moxie Marlinspike
8cd5ff5fa1 Mark directory retrieved on registered update 2017-11-30 13:30:15 -08:00
Moxie Marlinspike
6f10de5e30 Fix trying to launch a dialog from an application context 2017-11-30 13:05:16 -08:00
Moxie Marlinspike
c58d5c32bb Remove request for permission that doesn't exist < O 2017-11-30 13:04:11 -08:00
scienmind
7b2b5742c7 Update readme.md and contributing.md to use signal.org URLs
Closes #7217
2017-11-30 11:05:16 -08:00
Moxie Marlinspike
0dbcb1a49b Support for adaptive icons
Closes #6887
Fixes #6511
2017-11-30 10:59:10 -08:00
Moxie Marlinspike
e7a9893e94 Fix string typo 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
0f35bc6fd9 Increase targetSdkVersion to 25 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
acfc9d75e0 Use startForegroundService instead of startService on Android 8 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
d9ab1a93f8 Fix problem with creating group and empty avatar 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
c2dbb34b25 Extract string resource 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
ed508a8def Be more explicit with mastersecret passing 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
d5cb804f90 Switch from PACKAGE_REPLACED to MY_PACKAGE_REPLACED
As part of the Oreo 'no more implicit intents' thing
2017-11-30 10:26:41 -08:00
Moxie Marlinspike
c8104a91a4 Remove dead code 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
4c8e259b56 Update compileSdk to 27 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
7a5846a6d4 Move more system contact info into recipient database
1) Move contact URI, contact photo URI, and custom label
   into recipient database, so there are no longer any
   contact DB queries during Recipient object loading.

2) Use a SoftHashMap so that any referenced Recipient objects
   can't get kicked out of the cache.

3) Don't load Recipient objects through the provider during sync.
   This was a super expensive thing to do, and blew up the cache.

4) Only apply changes to Recipient objects during sync if they
   are in the cache. Otherwise, there should be no outstanding
   references, and the changes are fine going exclusively to
   the DB.
2017-11-30 10:26:41 -08:00
Moxie Marlinspike
64c8b4b2ef Support for selective permissions 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
99a26e2bcc Don't invalidate entire recipient cache when contact data changes 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
886298674e Adjust inbox zero empty state 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
e9a82502b9 Fix up converstion list empty state look 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
f855e161d9 Ensure notifications for new users won't be generated first fetch 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
66e1be1aeb Don't invalidate entire recipient cache when contact data changes 2017-11-30 10:26:41 -08:00
Moxie Marlinspike
8f6440ce17 Bump version to 4.13.7 2017-11-29 21:56:25 -08:00
Moxie Marlinspike
73c75a9b34 Don't delete GCM id during registration if it never existed
Fixes #7229
2017-11-28 14:33:22 -08:00
Moxie Marlinspike
f916dcd5de Bump version to 4.13.6 2017-11-27 09:48:56 -08:00
Moxie Marlinspike
1ea913cea6 Updated language translations 2017-11-27 09:48:47 -08:00
Moxie Marlinspike
a350106f7d Don't check DB workaround if push group
Fixes #7225
2017-11-27 09:44:50 -08:00
Moxie Marlinspike
17f8a81a56 Bump version to 4.13.5 2017-11-25 09:52:59 -08:00
Moxie Marlinspike
7eb089c9de Temporary fix for Signal contact displaying as SMS for N seconds
The whole recipient pipeline needs to be changed more subsantially,
particularly given the way directory discovery works with it. This
will temporarily solve the problem though.
2017-11-25 09:50:36 -08:00
Moxie Marlinspike
6ff0a62338 Bump version to 4.13.4 2017-11-20 19:13:13 -08:00
Moxie Marlinspike
ba5febd222 Fix some emoji rendering issues related to obsolete images
1) The "obsolete" images like "swimmer" need to alias to
"man_swimming" so that they can be rendered correctly.

2) There are a whole bunch of emoji-data elements
(like white_frowning_face) that have "unified" code points which
have changed to include a "terminator."

Fixes #7212
2017-11-20 19:11:26 -08:00
Moxie Marlinspike
e1026785f7 Bump version to 4.13.3 2017-11-20 11:22:29 -08:00
Moxie Marlinspike
9004474748 Updated language translations 2017-11-20 11:21:57 -08:00
Moxie Marlinspike
c1b2098bd9 Fix race condition that would display end call button over answer
Fixes #7211
2017-11-20 11:17:50 -08:00
Moxie Marlinspike
efb9ba6496 Bump version to 4.13.2 2017-11-19 18:48:20 -08:00
Moxie Marlinspike
19d49ed281 Add slight drop shadow to slide up / slide down answer button text 2017-11-19 18:47:24 -08:00
Moxie Marlinspike
4ecb65a262 Lighten conversation list item dividers in light theme 2017-11-19 18:39:32 -08:00
Moxie Marlinspike
d3c72fa697 Avoid green background on item below archived conversation list item 2017-11-19 18:34:03 -08:00
Moxie Marlinspike
80042ae3aa Display action mode over toolbar
Fixes #7198
2017-11-19 18:19:01 -08:00
Moxie Marlinspike
58f1e68961 Update emoji
Fixes #6637
Fixes #7206
2017-11-19 18:11:25 -08:00
Moxie Marlinspike
be6a51b123 Hide photo/mic options on whitespace entry
Fixes #7204
2017-11-19 16:53:12 -08:00
Moxie Marlinspike
08c72ed874 Don't show group ID in recent contact selection list
Fixes #7201
2017-11-19 16:46:12 -08:00
Moxie Marlinspike
86bd2351bc Replace answer/decline button and action for incoming calls
Fixes #7199
2017-11-19 16:32:22 -08:00
Moxie Marlinspike
e14a97cf68 Bump version to 4.13.1 2017-11-16 15:34:29 -08:00
Moxie Marlinspike
cf81815bf6 Add recent chats to top of share list 2017-11-16 15:21:46 -08:00
Moxie Marlinspike
c5a9f27c31 Catch some activity not found exceptions for expired builds 2017-11-16 12:31:42 -08:00
Moxie Marlinspike
de812d3f0f Extract string resources 2017-11-16 12:28:29 -08:00
Moxie Marlinspike
e31ce39967 Fix background on attachment manager 2017-11-16 12:26:23 -08:00
Moxie Marlinspike
2da47c3bb3 Fix share list crash and update look/feel
Fixes #7195
2017-11-16 12:22:09 -08:00
Moxie Marlinspike
0960ff1fa9 Bump version to 4.13.0 2017-11-15 16:38:07 -08:00
Moxie Marlinspike
749eeb87b2 Update language translations 2017-11-15 16:37:58 -08:00
Moxie Marlinspike
e37c06c563 Show dialog if another device registered with same number 2017-11-15 16:29:00 -08:00
Moxie Marlinspike
909c0c544c Make sure thread preview text is to left of unread indicator 2017-11-15 15:49:45 -08:00
Moxie Marlinspike
40004b5be3 Updated language translations 2017-11-14 20:52:58 -08:00
Moxie Marlinspike
b42e91134b Remove inset divider from last recyclerview element 2017-11-14 12:09:19 -08:00
Moxie Marlinspike
682abbf66b Add unread count to synthesized cursor 2017-11-14 11:47:15 -08:00
Moxie Marlinspike
1986e58c5f Remove unused resources
According to Android Studio
2017-11-14 11:43:25 -08:00
Moxie Marlinspike
b88069f396 Revert "Remove unused resources"
AS seems to have miscalculated

This reverts commit 344af622b7.
2017-11-14 11:29:20 -08:00
Moxie Marlinspike
344af622b7 Remove unused resources
Or so says Android Studio
2017-11-14 11:15:03 -08:00
Moxie Marlinspike
ad9a995ffa Correctly display cropped profile image
Fixes #7191
2017-11-14 10:50:17 -08:00
Moxie Marlinspike
21ddc1dbba Fix profile crash
Fixes #7192
2017-11-14 10:50:17 -08:00
Moxie Marlinspike
534dec282f Brighten light theme
1) Brighten background color

2) Add unread indicator in conversation list

3) Eliminate some conversation list overdraw
2017-11-14 10:50:17 -08:00
Moxie Marlinspike
03573df00f Add inset dividers in conversation list
Closes #7074
2017-11-14 10:50:17 -08:00
Moxie Marlinspike
6b94d0679c Remove unused resource 2017-11-14 10:50:17 -08:00
Moxie Marlinspike
1cee253b41 Fix contact list search cursor color 2017-11-14 10:50:17 -08:00
Moxie Marlinspike
40caf20188 Make sure nav drawable is mutable before tinting 2017-11-14 10:50:17 -08:00
Nicholas Rizzio
99ea6f9812 Remove the last references to BitHub and Coinbase
Closes #7176
2017-11-14 10:50:17 -08:00
Moxie Marlinspike
405ee3b741 Improve search bar visibility 2017-11-14 10:50:17 -08:00
Moxie Marlinspike
9a75f49aa1 Add an empty state for search 2017-11-14 10:50:17 -08:00
Moxie Marlinspike
9c50057909 Add an empty state for archived 2017-11-14 10:50:17 -08:00
Moxie Marlinspike
bb878f8a67 Adjust Conversation List toolbar to match RecyclerView alignment 2017-11-14 10:50:17 -08:00
Moxie Marlinspike
3097c2855e Add empty state for conversation list 2017-11-14 10:50:17 -08:00
Moxie Marlinspike
90ff0e58b0 Update registration flow 2017-11-14 10:50:17 -08:00
Moxie Marlinspike
e56e55363d Add some debug logging 2017-11-14 10:49:54 -08:00
Moxie Marlinspike
50ae2dd1b8 Fix multi device race condition
Fixes #7175
2017-11-12 13:54:37 -08:00
Moxie Marlinspike
60f4e245e9 Bump version to 4.12.3 2017-11-06 15:53:01 -08:00
Moxie Marlinspike
9c1e846049 Update circular progress button dep to be compat w/ build tools 2017-11-06 15:52:18 -08:00
Moxie Marlinspike
0593de85df Update Dockerfile to support new build tools 2017-11-06 09:25:07 -08:00
Moxie Marlinspike
e245281b69 Update Android plugin to 3.0.0 2017-11-06 09:20:52 -08:00
Moxie Marlinspike
ad6ae10a41 Fix scaling issue when loading emoji sprites
Fixes #5973
// FREEBIE
2017-11-06 08:11:36 -08:00
Moxie Marlinspike
1c680a2c64 Update libwebrtc to M63
// FREEBIE
2017-11-03 18:01:18 -07:00
Moxie Marlinspike
648b2f24f6 Bump version to 4.12.2
// FREEBIE
2017-11-03 12:56:11 -07:00
Moxie Marlinspike
42ef64aebe Updated language translations
// FREEBIE
2017-11-03 12:55:45 -07:00
Moxie Marlinspike
9f0252dfb9 Update domain fronting cert store with new Google roots
// FREEBIE
2017-11-03 12:05:57 -07:00
Moxie Marlinspike
bcdf3bf311 Fix for scribbles on Android 8
Fixes #6998
// FREEBIE
2017-11-03 11:32:18 -07:00
Moxie Marlinspike
3e9bfcb3fd Delete "external" persistent blobs on cleanup
Also switch external persistent blog directory to cache

Fixes #6909
// FREEBIE
2017-11-03 10:53:37 -07:00
Moxie Marlinspike
3ed82c1726 Glide -> glideRequests in GiphyAdapter
// FREEBIE
2017-11-02 18:12:06 -07:00
Moxie Marlinspike
90203e4872 Bump version to 4.12.1
// FREEBIE
2017-11-01 15:57:00 -07:00
Moxie Marlinspike
d93ba54f0e Bump version to 4.12.0
// FREEBIE
2017-11-01 15:56:55 -07:00
Moxie Marlinspike
f4e8ecf740 Update Dockerfile for compileSdk 26
// FREEBIE
2017-11-01 15:56:49 -07:00
Christian Ascheberg
69e656af76 Add back a way to access quick contact from conversation
Closes #7051
// FREEBIE
2017-11-01 15:56:46 -07:00
Greg Cooksey
23a23ebd72 CreateProfileActivity uses DynamicTheme
Fixes #6981
Closes #6997
// FREEBIE
2017-11-01 15:56:46 -07:00
Christian Ascheberg
fdd070c1dd Do not show sent checkmark for verification status changes
Fixes #6743
Closes #7041
// FREEBIE
2017-11-01 15:56:46 -07:00
Nicholas Rizzio
0ab9b56a18 Add a space between group member names
Fixes #7059
Closes #7060
// FREEBIE
2017-11-01 15:56:46 -07:00
haffenloher
3df9112cf8 Fix synced sent media messages expiring too fast
Fixes #6928
Closes #7135
2017-11-01 15:56:46 -07:00
Moxie Marlinspike
9a8d058051 Update to glide 4.3.0
// FREEBIE
2017-11-01 15:56:44 -07:00
Moxie Marlinspike
6d88710a88 Update to libsignal-service 2.6.11
// FREEBIE
2017-11-01 15:56:31 -07:00
Moxie Marlinspike
e056bd1aa2 Update giphy connectivity strategy for glide
// FREEBIE
2017-11-01 15:51:38 -07:00
Moxie Marlinspike
e7937fd424 Cache external address formatter for better performance
// FREEBIE
2017-10-11 17:47:12 -07:00
Moxie Marlinspike
b80408bcb4 Use Glide for all contact photo caching
// FREEBIE
2017-10-11 17:47:12 -07:00
Moxie Marlinspike
10f224ede5 Update to glide 4.x
// FREEBIE
2017-10-11 17:47:12 -07:00
Moxie Marlinspike
17dd681dc8 Run all AsyncTasks on thread pool executor
Should Fix #7002
2017-10-23 13:03:32 -07:00
Moxie Marlinspike
263846bba0 Fix mms group migration for those who haven't encountered it yet
Fixes #7091
// FREEBIE
2017-10-23 09:52:34 -07:00
Moxie Marlinspike
0bcf46bacd Remove lingering bithub reference 2017-10-18 12:39:33 -07:00
Moxie Marlinspike
4bf91aa86a Bump version to 4.11.5
// FREEBIE
2017-10-16 11:04:26 -07:00
Moxie Marlinspike
7a8bd0597a Correctly load group avatars in RecipientPreferencesActivity
Fixes #7102
// FREEBIE
2017-10-16 10:16:15 -07:00
Moxie Marlinspike
e87aa85bae Bump version to 4.11.4
// FREEBIE
2017-10-15 10:12:39 -07:00
Moxie Marlinspike
5711adb2c9 Fix profile out of memory errors on low mem devices
Fixes #7094
// FREEBIE
2017-10-15 10:00:03 -07:00
Moxie Marlinspike
4bd3094bad Fix problem where recycled group avatar icons have stale listener
Fixes #7089
// FREEBIE
2017-10-13 09:51:37 -07:00
Moxie Marlinspike
671023d0c8 Bump version to 4.11.3
// FREEBIE
2017-10-10 10:05:19 -07:00
Moxie Marlinspike
afa0807827 Updated language translations
// FREEBIE
2017-10-10 10:04:45 -07:00
Moxie Marlinspike
4e45d53bd9 Scroll on list post
Fixes #7054

// FREEBIE
2017-10-10 10:00:24 -07:00
Moxie Marlinspike
d40fea9423 Catch Glide exception when loading avatar image
Workaround for #7016
// FREEIBE
2017-10-10 09:18:00 -07:00
Moxie Marlinspike
c15d1a3bce Update pipe when injecting message sender
// FREEBIE
2017-10-10 09:14:53 -07:00
Moxie Marlinspike
77c232760c No documents found -> No documents
// FREEBIE
2017-10-09 10:38:36 -07:00
Moxie Marlinspike
655be5adf4 Fix RingtoneManager cursor crash on some devices
Fixes #7055
// FREEBIE
2017-10-08 18:46:09 -07:00
Moxie Marlinspike
445f3c234c Connect "mark all read" to sync and read receipts
Fixes #7069
// FREEBIE
2017-10-08 18:09:46 -07:00
Moxie Marlinspike
5be1a5e3d5 Fix "no media" text alignment in conversation gallery
Fixes #7066
// FREEBIE
2017-10-08 17:46:35 -07:00
Moxie Marlinspike
a382694b1f Don't hide keyboard when back arrow tapped in Conversation Activity
Fixes #7065
// FREEBIE
2017-10-08 17:44:18 -07:00
Moxie Marlinspike
12020a3f86 Fix vector drawable problems < Android 5.0
Fixes #7056
// FREEBIE
2017-10-08 17:42:45 -07:00
Moxie Marlinspike
9fa4ba126b Fix non-collapsing layout when scrolled from horiz recyclerview
Fixes #7042
// FREEBIE
2017-10-08 17:36:35 -07:00
Moxie Marlinspike
5a607918d2 Name message retrieval service thread
// FREEBIE
2017-10-08 11:34:24 -07:00
Moxie Marlinspike
d0570ef7cb Fix media preview crash
Fixes #7050
// FREEBIE
2017-10-05 17:20:28 -07:00
Moxie Marlinspike
d24fb8c855 Bump version to 4.11.2
// FREEBIE
2017-10-04 15:25:11 -07:00
Moxie Marlinspike
ac282ccf70 Display contact color in background for generated avatars
Fixes #7028
// FREEBIE
2017-10-04 15:24:04 -07:00
Moxie Marlinspike
42f613e722 Be more explicit with running on main thread
// FREEBIE
2017-10-04 14:56:31 -07:00
Moxie Marlinspike
99b2149deb Fixed avatar icons not rendering in contact selection view
// FREEBIE
2017-10-04 14:47:29 -07:00
Moxie Marlinspike
0a3ede7c32 Fix expiring messages timer colors in dark theme
Fixes #5759
// FREEBIE
2017-10-04 14:08:56 -07:00
Moxie Marlinspike
5ad7e3b48a Make avatar in conversation activity tappable
Fixes #7025
// FREEBIE
2017-10-04 14:04:04 -07:00
Moxie Marlinspike
5270dad789 Fix screen security preference migration
// FREEBIE
2017-10-04 12:37:53 -07:00
Moxie Marlinspike
10e305d204 Remove elevation
Helps #6894

// FREEBIE
2017-10-04 12:35:17 -07:00
Moxie Marlinspike
cee3858e2e Fix mysteriously missing string content
// FREEBIE
2017-10-04 12:27:45 -07:00
Moxie Marlinspike
b430be9759 Fix color for shared media in dark theme
ugh dark theme

Fixes #7024
// FREEBIE
2017-10-04 12:26:03 -07:00
FeuRenard
d71fb4c958 Adjust dark themed NoActionBar activities
// FREEBIE
2017-10-04 11:50:55 -07:00
Veeti Paananen
eb456ef2b0 Fix implicit locale string formatting bugs
Depending on the phone language the default format may use Arabic
numerals, etc. when not desired.

Bug: fixes #7006
Closes #7040
2017-10-04 11:36:43 -07:00
Moxie Marlinspike
9a876a3672 Show "you" in MediaPreviewActivity
Fixes #7038
// FREEBIE
2017-10-04 11:35:16 -07:00
Moxie Marlinspike
677c7732cf Update incognito keyboard string
Fixes #7037
// FREEBIE
2017-10-04 11:21:03 -07:00
Moxie Marlinspike
4ebf97550c Fix unlocked icon color in dark theme
Fixes #7036
// FREEBIE
2017-10-04 11:15:02 -07:00
Moxie Marlinspike
8a99d9b126 Bump version to 4.11.1
// FREEBIE
2017-10-03 19:11:25 -07:00
Moxie Marlinspike
4dfaec977f Fix string reference
// FREEBIE
2017-10-03 19:11:02 -07:00
Moxie Marlinspike
ba849bce2c Add support for incognito keyboard preference
Closes #6985
// FREEBIE
2017-10-03 18:57:23 -07:00
Moxie Marlinspike
5de89d4f26 Correctly disable preferences in group conversation preferences
Fixes #7031
// FREEBIE
2017-10-03 17:05:52 -07:00
Moxie Marlinspike
b7340cc356 Don't show voice notes in conversation documents overview
Fixes #7029
// FREEBIE
2017-10-03 16:43:31 -07:00
Moxie Marlinspike
b3147aad55 Make "Shared media" string translatable
// FREEBIE
2017-10-03 16:29:11 -07:00
Moxie Marlinspike
9287b00317 Make conversation settings menu item work
Fixes #7023
// FREEBIE
2017-10-03 16:27:12 -07:00
Moxie Marlinspike
d7d6f38cb6 Enable censorship circumvention in Qatar
// FREEBIE
2017-10-03 14:08:41 -07:00
Moxie Marlinspike
b34eb08088 Fix look of default group photo in conversation preferences view
Fixes #7022
// FREEBIE
2017-10-03 14:01:02 -07:00
Moxie Marlinspike
9389fe47bd Fix call screen FAB being off-center
Fixes #7021
// FREEBIE
2017-10-03 13:32:08 -07:00
Moxie Marlinspike
a929bf91f1 Show profile name in call screen
Fixes #7020
// FREEBIE
2017-10-03 13:29:49 -07:00
Moxie Marlinspike
04fcb9c531 Bump version to 4.11.0
// FREEBIE
2017-10-03 10:43:13 -07:00
Moxie Marlinspike
c09d2951b1 Fix preference compat crash
Fixes #7018
// FREEBIE
2017-10-03 10:43:06 -07:00
Moxie Marlinspike
2c1337b33e Make early receipts work in group messages
For both conversation item view and message details view

// FREEBIE
2017-10-02 14:54:55 -07:00
Moxie Marlinspike
856a4d2860 Process configuration request messages
// FREEBIE
2017-10-02 12:39:44 -07:00
Moxie Marlinspike
b3f0888a2e Synchronize read receipt configuration from splash screen
// FREEBIE
2017-10-02 12:15:45 -07:00
Moxie Marlinspike
e388524a2f Update Dockerfile
// FREEBIE
2017-10-02 11:56:55 -07:00
Moxie Marlinspike
edc00d858b Updated language translations
// FREEBIE
2017-10-02 11:20:16 -07:00
Moxie Marlinspike
182d571e1b Fix experience upgrade strings for notification
// FREEBIE
2017-10-02 10:45:43 -07:00
Moxie Marlinspike
e145875164 Fix json serialization for group message error
Fixes #6919
// FREEBIE
2017-10-02 10:35:49 -07:00
Moxie Marlinspike
2e56a0aa70 Fix typo
// FREEBIE
2017-10-02 09:58:08 -07:00
Moxie Marlinspike
4c2269175b Improve profile upload animation
// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
893cf9c01d Add support for setting empty profile names
// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
285947eb66 Show per-member delivery/read status on message info in groups
// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
2b4064f3b7 Add splash screen for read receipts
// FREEBIE
2017-10-01 22:36:52 -07:00
Brian St. Pierre
6e6bfaa932 set MMS default characterset to utf-8.
Fixes #6374
Closes #6965
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
8d08f3969a Switch from secure indicator to insecure indicator
Instead of cluttering Signal messages with a little padlock,
let's highlight the insecurity of SMS messages instead.

// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
8ce914a344 Refactor media overview activity to display documents
// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
c6b2e785a5 Reorganize conversation media activity to have sticky headers
// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
5189fbf686 Bump minSdk to API 14
The Android v4 and v7 support libraries now only support a minSdk
of v14. This means that they are both essentially a v14 support
library now.

In order to bump compileSdk to 26, we'll have to update the support
library, which will break < v14 compatibility. Android is
essentially forcing all applications to break compatibility with
devices older than API 14.

// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
b47665aa44 Fix migration typo
// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
d0e781ccb4 Sync read receipt configuration to sibling devices
// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
e5e0bc2333 Reorganize preference widgets
// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
4828a8a274 Add conversation media photo rail to recipient preferences
// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
a1c276f70b Update to V7 PreferencesCompat library
// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
cb9bc9659b Support for read receipts
// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
65124fd1f2 Redesign conversation and conversation preferences layouts
Remove avatars from conversation items unless in a group chat.

// FREEBIE
2017-10-01 22:36:52 -07:00
Moxie Marlinspike
30916d8e19 Bump version to 4.10.12
// FREEBIE
2017-09-25 09:33:02 -07:00
Moxie Marlinspike
009c01fd7e Move experience upgrade after passphrase and registration
// FREEBIE
2017-09-25 09:32:44 -07:00
Moxie Marlinspike
a39d9bf132 Fix for RTL layout detection crash on < API 17
Fixes #6987
// FREEBIE
2017-09-25 09:05:41 -07:00
Moxie Marlinspike
185d22809e Bump version to 4.10.11
// FREEBIE
2017-09-19 11:03:53 -07:00
Moxie Marlinspike
74779adc34 Use correct open helper for old directory database
// FREEBIE
2017-09-19 11:03:18 -07:00
Moxie Marlinspike
b5ad2fc744 Bump version to 4.10.10
// FREEBIE
2017-09-15 10:37:04 -07:00
Moxie Marlinspike
260383ac21 Fix problem with direct share
Fixes #6968
// FREEBIE
2017-09-15 10:36:33 -07:00
Moxie Marlinspike
b6aedd330e Disable signal messaging if unregistered
Fixes #6963
// FREEBIE
2017-09-14 16:46:12 -07:00
Moxie Marlinspike
989ec6a40a Bump version to 4.10.9
// FREEBIE
2017-09-13 17:26:56 -07:00
Moxie Marlinspike
c7e972026c Updated language translations
// FREEBIE
2017-09-13 17:26:43 -07:00
Moxie Marlinspike
5a0f671aa4 Fix not sending group info request messages
Fixes #6962
// FREEBIE
2017-09-13 17:19:59 -07:00
Moxie Marlinspike
b7109e9ebb Fix for NPE if MMS notification has no transaction ID
// FREEBIE
2017-09-13 16:38:02 -07:00
Moxie Marlinspike
93395c3ff4 Include own profile key in normal contact sync
// FREEBIE
2017-09-12 22:49:30 -07:00
Moxie Marlinspike
2e5b0bcee2 Bump version to 4.10.8
// FREEBIE
2017-09-11 14:18:17 -07:00
Moxie Marlinspike
40d7826fb9 Fix <= KitKat bug that prompts for MMS configuration
Fixes #6954
2017-09-11 13:04:20 -07:00
Moxie Marlinspike
77fb541090 Bump version to 4.10.7
// FREEBIE
2017-09-10 11:48:57 -07:00
Moxie Marlinspike
0f65bf08b8 Align info graphic with text
Fixes #6949
// FREEBIE
2017-09-10 11:48:27 -07:00
Moxie Marlinspike
962944a974 Add some annotations
// FREEBIE
2017-09-10 11:21:51 -07:00
Moxie Marlinspike
08948fe05a Don't create groups for 1:1 MMS conversations
Fixes #6947
// FREEBIE
2017-09-10 11:13:53 -07:00
Moxie Marlinspike
f3d943270c Be more conservative with handlers and references
Expiring message timers could end up leaking references and
executing work even after their conversation item was no longer
visible

Maybe fixes #6898

// FREEBIE
2017-09-09 23:46:48 -07:00
Moxie Marlinspike
6a10c69df8 Bump version to 4.10.6
// FREEBIE
2017-09-08 11:49:26 -07:00
Moxie Marlinspike
f335a65d32 Stop Thread.interrupt() from being called
// FREEBIE
2017-09-08 11:48:44 -07:00
Moxie Marlinspike
79a88f378b Avoid NPE if capture file isn't available
// FREEBIE
2017-09-08 11:38:07 -07:00
Moxie Marlinspike
afed60f870 Handle recipient modification callbacks on main thread
// FREEBIE
2017-09-08 11:36:09 -07:00
Moxie Marlinspike
989ea4042c MMS group includes the sender
Fixes #6942
// FREEBIE
2017-09-08 11:19:57 -07:00
Moxie Marlinspike
0bd9606666 Bump version to 4.10.5
// FREEBIE
2017-09-07 20:45:26 -07:00
Moxie Marlinspike
5173921ce0 Fix bad MMS group creation logic
Fixes #6939
Fixes #6938

// FREEBIE
2017-09-07 20:41:34 -07:00
Moxie Marlinspike
032eaa4389 Fix crash on conversation list search
Fixes #6936
// FREEBIE
2017-09-07 13:52:58 -07:00
Moxie Marlinspike
962fb60ffb Don't synchronize MMS groups to sibling devices
Fixes #6934
// FREEBIE
2017-09-07 11:12:57 -07:00
Moxie Marlinspike
6d1f4bc2f0 Bump version to 4.10.4
// FREEBIE
2017-09-06 17:59:20 -07:00
Moxie Marlinspike
844ffdad54 Add padding to finish button for non-english languages
Fixes #6930
// FREEBIE
2017-09-06 17:58:01 -07:00
Moxie Marlinspike
6455c66a0b Fix bug that prevented selecting insecure SMS
Fixes #6929

// FREEBIE
2017-09-06 17:54:32 -07:00
Moxie Marlinspike
af265bc3c2 Bump version to 4.10.3
// FREEBIE
2017-09-06 16:16:51 -07:00
Moxie Marlinspike
2890490ab4 Support cameras that don't return data intent
Fixes #6926

// FREEBIE
2017-09-06 16:16:01 -07:00
Moxie Marlinspike
bcff186b10 Add self to MMS groups when migrating
Fixes #6925
// FREEBIE
2017-09-06 16:08:20 -07:00
Moxie Marlinspike
967c374213 Display error when camera doesn't return image
Partial #6926
// FREEBIE
2017-09-06 16:03:08 -07:00
Moxie Marlinspike
e172b84603 Fix crash on displaying unknown contact header
Fixes #6924

// FREEBIE
2017-09-06 15:49:10 -07:00
Moxie Marlinspike
bdb67725c5 Add additional debug information for mysterious stack trace
Related #6923

// FREEBIE
2017-09-06 13:56:09 -07:00
Moxie Marlinspike
d6aeeaef2c Bump version to 4.10.2
// FREEBIE
2017-09-06 10:55:04 -07:00
Moxie Marlinspike
612ad49a8b Updated language translations
// FREEBIE
2017-09-06 10:54:27 -07:00
Moxie Marlinspike
29b561fe41 Fix group conversation items glitching to use conversation recipient
// FREEBIE
2017-09-06 10:31:48 -07:00
Moxie Marlinspike
56c720cd4f Bump version to 4.10.1
// FREEBIE
2017-09-06 00:30:50 -07:00
Moxie Marlinspike
19be527370 Fix recursive experience upgrade activity problem
// FREEBIE
2017-09-06 00:29:49 -07:00
Moxie Marlinspike
efc4a5ab9d Fix problem with prefetched recipient details
Don't use a cached recipient if we have a prefetched recipient
detail object and the cached recipient is still in progress
and without a name

// FREEBIE
2017-09-06 00:11:11 -07:00
Moxie Marlinspike
79f8cf8e35 Bump version to 4.10.0
// FREEBIE
2017-09-05 22:16:13 -07:00
Moxie Marlinspike
26c7a68a66 Updated language translations
// FREEBIE
2017-09-05 22:15:05 -07:00
Moxie Marlinspike
7197d513a3 Add target for 'who can see this' profile link
// FREEBIE
2017-09-05 12:52:50 -07:00
Moxie Marlinspike
5cccea5846 Revert "Change default charset to UTF-8"
This reverts commit 86eb14b7bb.
2017-09-05 12:43:21 -07:00
Moxie Marlinspike
258910504c BH seems to be broken.
Wasn't really ever super effective or useful in the end anyway.
2017-09-04 14:59:51 -07:00
Christian Bundy
86eb14b7bb Change default charset to UTF-8
This resolves #6374 where the character set is set to
`CharacterSets.MIMENAME_ANY_CHARSET` but the character set being
 used is _actually_ UTF-8.

Fixes #6374
Closes #6892
2017-09-04 14:58:25 -07:00
Moxie Marlinspike
2add02c62f Add splash screen for setting profiles
// FREEBIE
2017-09-03 19:45:43 -07:00
Moxie Marlinspike
3e3ae5f865 Adjust profile key sharing based on sync messages
// FREEBIE
2017-08-28 17:57:07 -07:00
Moxie Marlinspike
62c738ee58 Update libsignal-service to 2.6.5
// FREEBIE
2017-08-28 17:56:49 -07:00
jdaminato94
6945ecf81d Keep screen on when viewing a video
Fixes #6642
Closes #6837

// FREEBIE
2017-08-28 10:45:32 -07:00
Markus Brenneis
66062f200a Work around SmsMessage.calculateLength NPE on broken ROMs
//FREEBIE
2017-08-28 10:43:14 -07:00
marcoscezar
37a5622525 Display appropriate registration error msg w/ bad verification code
Fixes #6551
2017-08-28 10:38:35 -07:00
Moxie Marlinspike
d0cd2621ca Only process messages if a body is present
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
51c1e4485f Support for profile key syncing to sibling devices
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
beed9d8034 Add length limit feedback when setting profile name
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
3e22c37425 Allow conversation subtitle to support emoji
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
638a9576f8 Add censorship circumvention endpoints for CDN
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
6bfe05323e Update recipient preference style
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
64ad9ec9dd Add group profile sharing logic
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
f17af19d09 Access all RecipientDatabase settings directly from Recipient
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
d1790dfe17 Rename RecipientPreferences -> RecipientSettings
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
8e6ca53023 Rename RecipientPreferencesDatabase -> RecipientDatabase
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
6924f0519e No need for a RecipientFactory any longer
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
6af836735b Remove unnecessary logging
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
1252b3ca00 Don't display unknown sender footer for group messages
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
1b2f52209d Display unknown sender footer for unknown senders
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
5942e93a33 Share profile key when initiating a conversation
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
c11f2eddf5 Display user profile information in settings activity
Allow for editing

// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
df99deb480 Insert profile creation into registration flow, fix capture
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
e7c20499ec Display profile name in when appropriate
Display in conversation list, conversation actionbar, group
messages, and group members list when address is not in system
contacts

// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
77a216b705 Support for retrieving and storing profile information
Initial support for sharing profile keys

// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
1893047a78 Profile creation activity
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
da94fd5f9e Join group information into conversation list query
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
159fdb317f Store system contacts display name in recipient preferences db
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
f61c52aace Consolidate user "capability" enums to a single value
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
5a5e47f2df Move "directory" information into RecipientPreferencesDatabase
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
a02f223a96 Join recipient preferences into thread query for faster lookup
// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
375207f073 Switch MMS groups to use the group database infrastructure
Eliminate the concept of 'Recipients' (plural). There is now just
a 'Recipient', which contains an Address that is either an individual
or a group ID.

MMS groups now exist as part of the group database, just like push
groups.

// FREEBIE
2017-08-28 10:30:50 -07:00
Moxie Marlinspike
81682e0302 Bump version to 4.9.9
// FREEBIE
2017-08-23 10:46:41 -07:00
mcloo
60eaade6b0 Fix plaintext export XML name escaping
Fixes #6830
Closes #6861
2017-08-22 15:22:03 -07:00
Benedikt Constantin Radtke
54396a3a9c Fix group info request responses
GroupRecords have a list of Addresses, not Strings.

Fixes #6881
Closes #6882
2017-08-22 15:19:39 -07:00
Moxie Marlinspike
8d473f4f50 Bump version to 4.9.8
// FREEBIE
2017-08-10 12:31:32 -07:00
Moxie Marlinspike
a80fe178ea Canonicalize addresses during import from system SMS database
// FREEBIE
2017-08-10 12:30:13 -07:00
Moxie Marlinspike
422b4c345b Catch IllegalArgumentException thrown internally on some devices
// FREEBIE
2017-08-10 12:17:05 -07:00
Moxie Marlinspike
c0ec531daa Bump version to 4.9.7
// FREEBIE
2017-08-07 12:41:26 -07:00
Moxie Marlinspike
47901e4198 Disallow alpha chars in country code field
// FREEBIe
2017-08-07 12:40:40 -07:00
Moxie Marlinspike
25a30d63a5 A blocked contact doesn't necessarily have to be a number
// FREEBIE
2017-08-07 12:27:34 -07:00
Moxie Marlinspike
1c3ba4b675 Bump version to 4.9.6
// FREEBIE
2017-08-04 09:30:54 -07:00
Moxie Marlinspike
c5a7d320f7 Don't query contacts DB if we have nothing to query
// FREEBIE
2017-08-04 09:28:20 -07:00
Moxie Marlinspike
8de9261081 MMS addresses can be email addresses
Fixes #6853
// FREEBIE
2017-08-04 09:22:58 -07:00
Moxie Marlinspike
f41e9c181c Bump version to 4.9.5
// FREEBIE
2017-08-03 13:01:38 -07:00
Moxie Marlinspike
cb4303ac23 Handle migration case where recipient_ids is completely empty
No idea how a DB is in that state, but apparently it's possible

Fixes #6850
// FREEBIE
2017-08-03 09:32:56 -07:00
Moxie Marlinspike
9a78615991 Switch regexp matcher to find() in order to handle alpha addresses
Any address with an alpha character anywhere in it should be used
as-is.

Fixes #6849

// FREEBIE
2017-08-03 09:24:08 -07:00
Moxie Marlinspike
dc61c67856 Bump version to 4.9.4
// FREEBIE
2017-08-02 13:08:19 -07:00
Moxie Marlinspike
7f46e99f9c Use SIM country code when registered number is unavailable
Convert directory operations to Addresses

Fixes #6845
// FREEBIE
2017-08-02 12:51:46 -07:00
Moxie Marlinspike
4838fade6c Fix typo
// FREEBIE
2017-08-02 11:15:58 -07:00
Moxie Marlinspike
1e934f6146 Escape addresess in thread and recipient pref migrations
For clients that have not yet migrated

// FREEBIE
2017-08-02 11:08:38 -07:00
Moxie Marlinspike
aacf50316d Escape addresses in thread, recipient pref, and group databases
Fixes #6847
// FREEBIE
2017-08-02 11:04:10 -07:00
Moxie Marlinspike
3d29445373 Bump version to 4.9.3
// FREEBIE
2017-08-02 08:15:21 -07:00
Moxie Marlinspike
24c48afd2e Fix typo in migration constraint resolution
Fixes #6846

// FREEBIE
2017-08-02 08:02:15 -07:00
Moxie Marlinspike
ae93038d66 Bump version to 4.9.2
// FREEBIE
2017-08-01 18:46:16 -07:00
Moxie Marlinspike
9a55632202 During migration, support recipient id of "-1"
Fixes #6843
// FREEBIE
2017-08-01 18:45:13 -07:00
Moxie Marlinspike
6ff9d3cc72 Bump version to 4.9.1
// FREEBIE
2017-08-01 14:53:07 -07:00
Moxie Marlinspike
6ed549cfb2 If two recipient ids get canonicalized to the same thing, drop one
There's not a great way for me to know which of them is the "real"
entry, which means that I could be deleting the wrong one. In the
case of recipient "preferences," it's hopefully not a huge loss,
and there aren't any other great options.

Fixes #6838

// FREEBIE
2017-08-01 14:52:03 -07:00
Moxie Marlinspike
8a5c89244a Be more liberal with migration addresses.
Anything alpha is an address as-is.

// FREEBIE.
2017-08-01 14:46:38 -07:00
Moxie Marlinspike
a67d0b18ff Be more liberal with external address formatting
A string like "bonbon" should just be "bonbon". That is apparently
a valid SMS source address.

// FREEBIE
2017-08-01 14:04:51 -07:00
Moxie Marlinspike
abea2d0bdf Fix for MediaOverviewActivity NPE
// FREEBIE
2017-08-01 10:00:55 -07:00
Moxie Marlinspike
5f9a3b7930 Only lookup contact address by number if address is a phone number
// FREEBIE
2017-08-01 09:57:50 -07:00
Moxie Marlinspike
4229c21bdc Fix NPE on contact update request
Fixes #6840

// FREEBIE
2017-08-01 08:57:26 -07:00
Moxie Marlinspike
45ecca69d3 Bump version to 4.9.0
// FREEBIE
2017-07-31 15:39:44 -07:00
Moxie Marlinspike
8c7ffe73f3 Updated language translations
// FREEBIE
2017-07-31 15:38:57 -07:00
Moxie Marlinspike
0ae60da68b Fix some bugs that would mis-label threads in migration
// FREEBIE
2017-07-31 14:04:47 -07:00
Moxie Marlinspike
737810475e Remove the Canonical Address Database
This was a holdover from Signal's origins as a pure SMS app.
It causes problems, depends on undefined device specific behavior,
and should no longer be necessary now that we have all the
information we need to E164 all numbers.

// FREEBIE
2017-07-31 12:02:29 -07:00
Moxie Marlinspike
e452862813 Catch unsatisfied link error on start if webrtc so isn't found
// FREEBIE
2017-07-21 16:29:03 -07:00
Moxie Marlinspike
5be246ec8f Fix NPE for SMS pdus that could potentially be null
// FREEBIE
2017-07-21 16:11:55 -07:00
Moxie Marlinspike
72afb33c1b Add Moto G5 to hardware AEC blacklist
For #6241
// FREEBIE
2017-07-21 16:03:31 -07:00
Moxie Marlinspike
0b39224d88 getMemoryClass -> getLargeMemoryClass
Fixes #6812

// FREEBIe
2017-07-21 16:01:32 -07:00
Moxie Marlinspike
82b5b35d3b Eliminate MediaNetworkRequirement style attachment job handling
// FREEBIE
2017-07-21 15:59:27 -07:00
Moxie Marlinspike
b5259f6847 Bump version to 4.8.1
// FREEBIE
2017-07-12 18:17:39 -07:00
AndHell
10de144b77 Trim message text to prohibit sending empty whitespace messages
Closes #6788
2017-07-12 18:15:49 -07:00
Moxie Marlinspike
f62fa2dc4e Updated language translations
// FREEBIE
2017-07-12 18:10:34 -07:00
Moxie Marlinspike
18f6196388 Update to libsignal-service 2.5.16
// FREEBIE
2017-07-12 18:05:27 -07:00
Moxie Marlinspike
c36db03a3a Prevent audio control click handler feedback loops
Fixes #6356
Fixes #6406
Fixes #6169

Closes #6800
// FREEBIE
2017-07-12 16:18:54 -07:00
Moxie Marlinspike
9dd508b6f5 Track pending incoming ice updates in addition to outgoing
// FREEBIE
2017-07-12 11:15:28 -07:00
Moxie Marlinspike
34443b059c Revert "We can now send trickle ice candidates immediately"
Need to hold off on this for some iOS changes.

This reverts commit 338f8de787.
2017-07-12 10:59:10 -07:00
Moxie Marlinspike
666f648c59 Bump version to 4.8.0
// FREEBIE
2017-07-07 11:13:09 -07:00
Moxie Marlinspike
54bab07483 Update language translations
// FREEBIE
2017-07-07 11:11:59 -07:00
Moxie Marlinspike
526d510423 Start creating "persistent" blobs in cache directory
Helps #5515
// FREEBIE
2017-07-06 12:58:05 -07:00
Gavin Howard
381237a315 Make plaintext export more compatible with SMS Backup and Restore
This commit adds the contact name and the readable date (and time) to
the plaintext export of every message. That's because that is how SMS
Backup and Restore does it, so this commit makes Signal more compatible.

Closes #6452
// FREEBIE
2017-07-06 12:19:12 -07:00
FeuRenard
512c6dc581 Keep screen off after end of audio playback
Fixes #6654
Closes #6669
// FREEBIE
2017-07-05 18:31:14 -07:00
Sebastian Malek
170b869a22 larger google play badge
Closes #6701
//FREEBIE
2017-07-05 18:22:25 -07:00
Christian Ascheberg
d0bb68e137 Fix group creation through group info request
Closes #6763
// FREEBIE
2017-07-05 14:19:55 -07:00
Christian Ascheberg
95d48bd3e9 Improve wording of joined contact notification
Fixes #6757
Closes #6764
// FREEBIE
2017-07-05 14:18:07 -07:00
Mateo Hernandez
5e1d63696f Fix ConversationAdapterTest#testGetItemIdEquals()
Regression introduced at cb670d67

Fixes #6652
Closes #6779
// FREEBIE
2017-07-05 14:13:35 -07:00
Moxie Marlinspike
338f8de787 We can now send trickle ice candidates immediately
// FREEBIE
2017-07-05 14:06:31 -07:00
Moxie Marlinspike
2c4c0f1349 Archive sessions and generate new registration id on re-register
Fixes #6703
// FREEBIE
2017-07-05 13:13:53 -07:00
Moxie Marlinspike
39b95ca4ed Do more to keep MessageRetrievalService alive
Closes #6456
2017-07-03 11:36:31 -07:00
Moxie Marlinspike
fcbcffe9ba Bump version to 4.7.4
// FREEBIE
2017-06-25 22:34:01 -07:00
Moxie Marlinspike
501b351f80 Update signal-service to 2.5.14
// FREEBIE
2017-06-25 22:33:31 -07:00
Moxie Marlinspike
b72b1cda94 Bump version to 4.7.3
// FREEBIE
2017-06-23 14:10:15 -07:00
Moxie Marlinspike
074e46b2d9 Enable verification syncing
// FREEBIE
2017-06-23 13:59:06 -07:00
Moxie Marlinspike
91612cb6f2 Bump version to 4.7.2
// FREEBIE
2017-06-22 11:04:23 -07:00
Moxie Marlinspike
f193723182 Don't display verified marker in conversation if unregistered
Closes #6755
// FREEBIE
2017-06-22 10:37:26 -07:00
Moxie Marlinspike
a0e23612d4 We need to disable this until push notifications contain more info
This could be a sync message, delivery receipt, or some other
message that isn't user-visible. The push notification content
would need to indicate whether that's the case in order to be
able to accurately display a notification

// FREEBIE
2017-06-20 10:57:11 -07:00
Moxie Marlinspike
8b12bc9acc Bump version to 4.7.1
// FREEBIE
2017-06-19 12:02:18 -07:00
Moxie Marlinspike
e2439278f4 Update libsignal-server to 2.5.12
Fixes #6734
// FREEBIE
2017-06-19 12:00:49 -07:00
Moxie Marlinspike
04f364942e Don't update thread state for groups w/ verified/default SNs
Fixes #6744
// FREEBIE
2017-06-19 11:20:15 -07:00
Moxie Marlinspike
0cc5618ba9 Only offer share/compare options when SN calculation is complete
Now that we're loading this asynchronously, these options need
to respond asynchronously as well

Fixes #6739
// FREEBIE
2017-06-19 10:39:15 -07:00
Moxie Marlinspike
8208bbf3c0 Remove stale identity approval preference (no longer used)
Fixes #6745
// FREEBIE
2017-06-19 09:27:35 -07:00
Moxie Marlinspike
1c8077a7fe Switch from a hardware AEC whitelist back to a blacklist
Disabling OpenSL ES seems to make the hardware AEC "work" on
devices where it was previously causing problems.

Using the WebRTC-based software AEC *without* OpenSL ES seems to
be causing new problems.

Fixes #6737
Related #6432
Related #6241
// FREEBIE
2017-06-19 09:22:07 -07:00
Moxie Marlinspike
7c2191f9a0 Bump version to 4.7.0
// FREEBIE
2017-06-15 12:41:55 -07:00
Moxie Marlinspike
83b1e7ba6c Updated language translations
// FREEBIE
2017-06-15 12:41:30 -07:00
Moxie Marlinspike
ec240a94e6 Fix capitalization (innocuous)
// FREEBIE
2017-06-15 12:04:50 -07:00
Moxie Marlinspike
666be5f358 Preserve unverified status if aleady unverified on update
// FREEBIE
2017-06-14 11:01:24 -07:00
Moxie Marlinspike
7f76bcc976 Don't attempt to fetch profiles for SMS contacts
// FREEBIE
2017-06-14 09:53:22 -07:00
Moxie Marlinspike
2dbeebac77 Maintain placeholder encrypted body to avoid processing error
// FREEBIE
2017-06-14 09:45:38 -07:00
Moxie Marlinspike
fa64c5de62 Updated language translations
// FREEBIE
2017-06-14 09:39:20 -07:00
Moxie Marlinspike
0f6823d37e Null check just in case the profile comes back empty
// FREEBIE
2017-06-14 09:35:32 -07:00
Moxie Marlinspike
172de96ce4 Update to webrtc M59
// FREEBIE
2017-06-13 12:28:12 -07:00
Moxie Marlinspike
f92d768be5 Correctly handle ice candidate for stale call
Fixes #6373
Fixes #6305
// FREEBIE
2017-06-13 09:21:42 -07:00
RiseT
52311eb881 "Message notifications" >> "Messages"
Closes #6700
// FREEBIE
2017-06-12 09:52:46 -07:00
Moxie Marlinspike
414a885b54 Make string plural
// FREEBIE
2017-06-12 09:49:04 -07:00
Moxie Marlinspike
1eccc07673 Temporarily disable synchronization messages
Until desktop catches up

// FREEBIE
2017-06-12 09:47:58 -07:00
Moxie Marlinspike
59d3e666fe Rename 'verify safety number' to 'view safety number'
// FREEBIE
2017-06-09 19:58:05 -07:00
Moxie Marlinspike
76c28cfa7a Add support for SN verification
// FREEBIE
2017-06-09 19:58:01 -07:00
Moxie Marlinspike
58273997b9 Explicitly check for disabled play services if needs update
Fixes #6381
// FREEBIE
2017-06-02 09:59:23 -07:00
Moxie Marlinspike
5672701a60 Add uncaught exception handler to message retrieval thread
Related #6644
// FREEBIE
2017-06-02 09:49:44 -07:00
Moxie Marlinspike
711740d156 Update to libsignal-service 2.5.10
// FREEBIE
2017-06-02 09:49:29 -07:00
Moxie Marlinspike
b50a3fa2b8 Actually handle busy signal correctly
// FREEBIE
2017-06-01 13:11:48 -07:00
Moxie Marlinspike
c09c7b6649 Update language translations
// FREEBIE
2017-06-01 10:58:22 -07:00
Moxie Marlinspike
7e40204eb2 Fix migration
Fixes #6695
// FREEBIE
2017-06-01 10:57:45 -07:00
Moxie Marlinspike
d413b80b15 Canonicalize number when retrieving profile
// FREEBIE
2017-05-31 14:51:48 -07:00
Moxie Marlinspike
73410f64b5 Display a notification when unable retrieve messages for push
Fixes #6684
// FREEBIE
2017-05-31 14:51:48 -07:00
Moxie Marlinspike
cd55feb2b9 Update signal-service to 2.5.9
// FREEBIE
2017-05-31 14:51:48 -07:00
FeuRenard
a9ea672888 Resolve media message race condition
Fixes #6677
Closes #6681
2017-05-31 14:51:48 -07:00
Moxie Marlinspike
5455bdffb2 Make sure existing identity entries are approved in migration
// FREEBIE
2017-05-31 14:51:48 -07:00
Moxie Marlinspike
0367bf0de4 Update signal-service to 2.5.8
// FREEBIE
2017-05-31 14:51:48 -07:00
Moxie Marlinspike
e9ae439b70 Fix for out of bounds on last seen search
Fixes #6661
Fixes #6660
// FREEBIE
2017-05-31 14:51:48 -07:00
Paride Legovini
99d229bb45 Don't connect to server if !isPushRegistered
Partial fix for #6620.
Closes #6627
// FREEBIE
2017-05-31 14:51:48 -07:00
Nicholas Rizzio
3d7331159f Set the advanced menu icon correctly
Fixes #6638
Closes #6639
// FREEBIE
2017-05-31 14:51:48 -07:00
Christian Ascheberg
662fe826cb Fix conversation list safety number change snippet for groups
Fixes #5985
Closes #6655
// FREEBIE
2017-05-31 14:51:48 -07:00
FeuRenard
ec1a0547d6 Don't show sent checkmark for outgoing calls
Fixes #6502
Closes #6667
// FREEBIE
2017-05-31 14:51:48 -07:00
Moxie Marlinspike
d507756821 Some identity key handling changes
1) Prefetch identity keys when possible

2) Always accept prefetched keys or keys from incoming messages

3) Block sending only if it's a recent change, or if always
   block is enabled

// FREEBIE
2017-05-31 14:51:48 -07:00
Moxie Marlinspike
ca701df1e4 Update copyright date
Closes #6678
// FREEBIE
2017-05-25 11:34:24 -07:00
Moxie Marlinspike
56f85e7f85 Bump version to 4.6.1
// FREEBIE
2017-05-24 11:03:40 -07:00
Moxie Marlinspike
4509077338 Lollipop MMS API doesn't seem to work reliably until L_MR1
Fixes #6663
Fixes #6668
// FREEBIE
2017-05-24 10:52:08 -07:00
Moxie Marlinspike
4dd5a92817 Fix for NPE when place picker name is unavailable
Fixes #6671
// FREEBIE
2017-05-24 10:03:35 -07:00
Moxie Marlinspike
782bd6003b Actually fallback to manual MMS receiving when system fails
Should resolve #6668 for tmobile users on older lollipop phones
// FREEBIE
2017-05-23 18:23:47 -07:00
Moxie Marlinspike
15df691017 Bump version to 4.6.0
// FREEBIE
2017-05-12 15:47:53 -07:00
Moxie Marlinspike
0d6f8a003d Add proguard config for klinker library
// FREEBIE
2017-05-12 15:47:04 -07:00
Moxie Marlinspike
50cec22aa1 Updated language translations
// FREEBIE
2017-05-11 22:49:26 -07:00
Moxie Marlinspike
b78c05e70b Keep track of when audio attachments are voice notes
// FREEBIE
2017-05-11 22:46:35 -07:00
Moxie Marlinspike
e96bf2bdc7 Allow share intents for arbitrary file types
Fixes #6608
// FREEBIE
2017-05-10 15:21:52 -07:00
Moxie Marlinspike
1c8c6d5f85 Be sure to canonicalize numbers when updating groups
// FREEBIE
2017-05-09 17:46:07 -07:00
Moxie Marlinspike
1525d0833c Enforce ordered data channel
// FREEBIE
2017-05-09 12:13:42 -07:00
Moxie Marlinspike
3fd5e58bd5 Disable OpenSL ES by default
Fixes #6432
// FREEBIE
2017-05-09 11:03:32 -07:00
Moxie Marlinspike
51d6144591 Significant MMS changes
1) Remove all our PDU code and switch to the PDU code from the
   klinker library

2) Switch to using the system Lollipop MMS library by default,
   and falling back to our own custom library if that fails.

3) Format SMIL differently, using code from klinker instead of
   what we've pieced together.

4) Pull per-carrier MMS media constraints from the XML config
   files in the klinker library, instead of hardcoding it at 280kb.

Hopefully this is an improvement, but given that MMS is involved,
it will probably make things worse instead.
2017-05-08 18:14:55 -07:00
Audric Ackermann
165fae5734 Display contact custom label instead of phone number
Fixes #6211
2017-05-07 19:23:55 -07:00
AndHell
dc18f73594 update contact query
update query to remove duplicated numbers

Fixes #4191
Closes #6475
2017-05-07 19:18:26 -07:00
Moxie Marlinspike
12ce92bb83 Fix super call
// FREEBIE
2017-05-07 18:59:35 -07:00
Moxie Marlinspike
b0b08a37db Rename "other" to "sms"
// FREEBIE
2017-05-07 18:59:18 -07:00
FeuRenard
1b75d00de5 Color registration buttons correctly <API21
Fixes #6604
Closes #6605
// FREEBIE
2017-05-07 18:23:19 -07:00
Joan Montané
6ede47d4f7 FREEBIE: Add Catalan to language selector
Closes #6612
2017-05-06 14:08:43 -07:00
Jonas Vautherin
dd3cef5ec2 Refactor storage management to have a centralized,
clearer way to get the Signal output directories

Closes #6476
// FREEBIE
2017-05-06 14:06:04 -07:00
Moxie Marlinspike
757ccd0c36 Updated emoji set
Fixes #4279
Fixes #6587
2017-05-05 19:42:23 -07:00
Moxie Marlinspike
bfc9ad7761 Bump version to 4.5.3
// FREEBIE
2017-04-30 10:29:31 -07:00
Moxie Marlinspike
e340f85258 Tint devices icon too
Fixes #6601
// FREEBIE
2017-04-28 16:30:20 -07:00
Moxie Marlinspike
89d1232bdc Bump version to 4.5.2
// FREEBIE
2017-04-28 14:57:01 -07:00
Moxie Marlinspike
cf04b0521e Updated language translations
// FREEBIE
2017-04-28 14:56:35 -07:00
Mateo Hernandez
a93fb1a0e5 Fix font size preference
Closes #6597
// FREEBIE
2017-04-28 14:51:56 -07:00
Moxie Marlinspike
50cf9c448a Bump version to 4.5.1
// FREEBIE
2017-04-27 17:59:15 -07:00
Mateo Hernandez
da6a00c4dc Tweak reminder layout
Closes #6586
// FREEBIE
2017-04-27 17:56:21 -07:00
Shenka
58a5e1f33c Fix vertical space in import_export_fragment
Fixes #6590
// FREEBIE
2017-04-27 17:47:09 -07:00
Mateo Hernandez
31e78f5fae Tweak contact selection layout
Fixes #6588

// FREEBIE
2017-04-27 18:42:25 -05:00
Mateo Hernandez
f4f0a97fc6 Revert "Tweak contact selection layout"
This reverts commit 59a2bf8a.
(wrong commit merged)

// FREEBIE
2017-04-27 18:41:18 -05:00
Christian Juner
1c94137f7a Fall back to Camera1Enumerator on exceptions
If Camera2Enumerator.isSupported() throws, consider Camera2Enumerator to
not be supported, log the Throwable, and use Camera1Enumerator instead.

Before this patch, an exception thrown by Camera2Enumerator.isSupported
would crash any Signal call (even if video was not enabled).

Fixes #6537
// FREEBIE
2017-04-27 20:51:31 +02:00
Moxie Marlinspike
2e8250f25e Add LG G3 to OpenSLES blacklist
// FREEBIE
2017-04-27 11:38:49 -07:00
Moxie Marlinspike
12062bdfe1 Bump version to 4.5.0
// FREEBIE
2017-04-26 18:08:32 -07:00
Moxie Marlinspike
bc9a52c510 Updated language translations
// FREEBIE
2017-04-26 18:08:05 -07:00
Mateo Hernandez
59a2bf8ae7 Tweak contact selection layout
Closes #6563
// FREEBIE
2017-04-26 18:05:07 -07:00
Mateo Hernandez
b17cba621e Show emoji-only messages larger
Closes #6531
// FREEBIE
2017-04-26 17:52:16 -07:00
mcloo
5ffee53faa Fix Unread Badger for Sony Launcher
Closes #6552
Fixes #6484
2017-04-26 10:27:30 -07:00
Mateo Hernandez
869630b7f4 Tint and resize import/export icons
Closes #6567
// FREEBIE
2017-04-26 10:27:30 -07:00
Mateo Hernandez
291dafa5c8 Switch import/export activity from cards to a list
Add touch ripple to items

Closes #6564
// FREEBIE
2017-04-26 10:27:30 -07:00
Moxie Marlinspike
cb670d6783 Improve UI send latency
// FREEBIE
2017-04-26 10:27:30 -07:00
Moxie Marlinspike
4d889a45e2 Blacklist Nexus 5 from OpenSL ES
Fixes #6432
// FREEBIE
2017-04-26 10:26:32 -07:00
Moxie Marlinspike
66d1d88686 Fix file push media constraint
// FREEBIE
2017-04-25 10:01:09 -07:00
Moxie Marlinspike
e4ac1b8dde Update language translations
// FREEBIE
2017-04-24 18:08:59 -07:00
Moxie Marlinspike
31a549449b Mutate Drawables we tint
Fixes #6575
// FREEBIE
2017-04-24 16:37:13 -07:00
Moxie Marlinspike
9bf198bb81 Add media constraints for arbitrary file types
Fixes #6573
// FREEBIE
2017-04-24 15:53:22 -07:00
Moxie Marlinspike
03e347bfd9 s/Document/File
// FREEBIE
2017-04-23 16:28:10 -07:00
Ahmed Ibrahim Khalil
c2796285d5 Fix copying links when scrolling in #6343
Closes #6565
// FREEBIE
2017-04-23 16:25:57 -07:00
Moxie Marlinspike
3acfba7bd0 Bump version to 4.4.0
// FREEBIE
2017-04-22 09:50:02 -07:00
Moxie Marlinspike
9377fb6ce0 Updated language translations
// FREEBIE
2017-04-22 09:49:22 -07:00
Moxie Marlinspike
25c7459464 Add support for notification priority preference
Fixes #6315
// FREEBIE
2017-04-21 23:05:59 -07:00
Moxie Marlinspike
2dceef50b7 Slim down some preference screens
// FREEBIE
2017-04-21 23:05:59 -07:00
Moxie Marlinspike
438a78ed30 Switch jobs with network requirement to timed wakelock
// FREEBIE
2017-04-21 23:05:59 -07:00
Moxie Marlinspike
8e7c7a9c54 Improve video thumbnail generation and handling on send side
For direct attach only

// FREEBIE
2017-04-21 23:05:59 -07:00
Moxie Marlinspike
ad4657df1f Fix video selection support with extra mime type
// FREEBIE
2017-04-21 23:05:59 -07:00
Moxie Marlinspike
bc33f8ec02 Remove unused resources
// FREEBIE
2017-04-21 23:05:59 -07:00
Moxie Marlinspike
d00671e7a5 Tweak attachment type selector look
// FREEBIE
2017-04-21 23:05:59 -07:00
Moxie Marlinspike
2b79e131a7 Support for sending arbitrary file types
// FREEBIE
2017-04-21 23:05:59 -07:00
Ahmed Ibrahim Khalil
c3164a8e84 Support copying links on long click.
Fixes #6343
Closes #6454
2017-04-21 23:05:59 -07:00
Mateo Hernandez
f07ce7b1f1 Move SMS/MMS pref hiding logic to onCreate
Closes #6528
// FREEBIE
2017-04-21 23:05:59 -07:00
Mateo Hernandez
a353ebd834 Add tint to preference icons
Closes #6540
// FREEBIE
2017-04-21 23:05:59 -07:00
Moxie Marlinspike
a697fcea04 Bump version to 4.3.2
// FREEBIE
2017-04-19 18:08:53 -07:00
Mateo Hernandez
9716849bb9 Fix preference divider crash on KitKat
Closes #6546
Fixes #6544
// FREEBIE
2017-04-19 18:08:44 -07:00
Moxie Marlinspike
9c5fe77e96 Bump version to 4.3.1
// FREEBIE
2017-04-17 16:03:06 -07:00
Moxie Marlinspike
0a0203a019 Update language translations
// FREEBIE
2017-04-17 16:02:56 -07:00
Moxie Marlinspike
8aab61c2e3 Make preference category card dividers more dark theme compatible
// FREEBIE
2017-04-17 15:31:54 -07:00
RiseT
9d3ff55457 Make "Contact joined Signal" translatable
Closes #6534
// FREEBIE
2017-04-17 10:29:34 -07:00
Mateo Hernandez
19c7fd21a8 Update preference screen icons
Closes #6538
// FREEBIE
2017-04-17 10:27:02 -07:00
Moxie Marlinspike
a5500655a7 Bump version to 4.3.0
// FREEBIE
2017-04-16 15:59:30 -07:00
Moxie Marlinspike
4a516084a6 Updated langauge translations
// FREEBIE
2017-04-16 15:59:01 -07:00
Moxie Marlinspike
f583c14e0e s/text/font size
// FREEBIE
2017-04-16 12:54:42 -07:00
Moxie Marlinspike
ddf6126abf Fix VideoPlayer Build.VERSION minimum
// FREEBIE
2017-04-16 11:11:08 -07:00
Mateo Hernandez
c389a9d3ce Support non-BMP chars (e.g. emojis) in avatars
Closes #6527
Fixes #6522
// FREEBIE
2017-04-16 10:35:08 -07:00
Moxie Marlinspike
cd56f03e07 Adjust conversation list look
// FREEBIE
2017-04-15 11:19:06 -07:00
Moxie Marlinspike
fe1cc3d6d1 Adjust compose field look
1) Align top of compose bubble with top of attach/send icon

2) Simplify hint

3) Make hint size same as input size

// FREEBIE
2017-04-15 10:12:00 -07:00
Moxie Marlinspike
5f5db5ded7 Support for message body text size preference
// FREEBIE
2017-04-14 22:59:30 -07:00
Moxie Marlinspike
e5a287b4e5 Add preference for SMS invitation prompt
// FREEBIE
2017-04-14 20:51:22 -07:00
Moxie Marlinspike
13d785894a Fix up preference screen a little
1) Remove phantom padding on left margin for all fragments

2) Move preferences around slightly

3) Add some card separators and style led list pref

// FREEBIE
2017-04-14 20:39:38 -07:00
Moxie Marlinspike
4fd41080ac Use exoplayer for playing video on API 16+ devices
// FREEBIE
2017-04-13 14:15:06 -07:00
Moxie Marlinspike
fad697ba2a Fix CipherInputStream seek behavior
Fixes #6518
// FREEBIE
2017-04-13 12:21:38 -07:00
Moxie Marlinspike
51f27631ef Switch from hardware AEC blacklist to whitelist
Related #6241
// FREEBIE
2017-04-12 15:12:13 -07:00
Taylor Kline
04153a3869 Grey 'LED blink pattern' when LED Color is None
Add BooleanListPreference to allow pref_led_blink to depend on
pref_led_color being non-None.

Closes #6480
2017-04-12 15:01:35 -07:00
Simon
b0b1cdef35 Add Redmi Note 4 to HARDWARE_AEC_BLACKLIST
See #6241
Closes #6516
// FRЕЕBIЕ
2017-04-10 14:31:45 -07:00
AQNOUCH Mohammed
6f6632c08a fix warning: XML has empty body
Closes #6473
2017-04-10 11:07:55 -07:00
Nicholas Rizzio
407c5d5ed2 Remove unused settings.gradle file
Closes #6479
// FREEBIE
2017-04-10 10:53:13 -07:00
Taylor Kline
b7f9525680 Remove unused summary field for notification.
Closes #6481
2017-04-10 10:45:18 -07:00
Moxie Marlinspike
68e68508a7 Bump version to 4.2.5
// FREEBIE
2017-04-10 09:46:34 -07:00
Moxie Marlinspike
e6f693a677 Updated language translations
// FREEBIE
2017-04-10 09:45:11 -07:00
Moxie Marlinspike
6b7174bb35 Add OnePlus One to AEC blacklist
// FREEBIE
2017-04-10 09:29:46 -07:00
Moxie Marlinspike
92ea7549d4 Make UpdateApkJob use a timed wakelock
Fixes #6514
// FREEBIE
2017-04-10 09:25:52 -07:00
Moxie Marlinspike
0a4d1569fb Clean up file name some on save
Rusty Bird points out that we don't want the save action to create
files outside the parent or hidden files.

// FREEBIE
2017-04-10 09:14:59 -07:00
Moxie Marlinspike
4c83e2ce10 Bump version to 4.2.4
// FREEBIE
2017-04-03 17:25:02 -07:00
Moxie Marlinspike
7c5df81840 Fix for busted OpenSSL JCE provider on older versions of android
Fixes #6477
// FREEBIE
2017-04-03 17:23:56 -07:00
Moxie Marlinspike
6afee68831 Bump version to 4.2.3
// FREEBIE
2017-04-03 10:13:40 -07:00
Moxie Marlinspike
bae549b1cc Update language translations
// FREEBIE
2017-04-03 10:11:07 -07:00
Moxie Marlinspike
ce9a67d095 Fix case
// FREEBIE
2017-04-02 18:26:28 -07:00
Moxie Marlinspike
3356f7c190 Bump version to 4.2.2
// FREEBIE
2017-04-02 09:33:58 -07:00
Moxie Marlinspike
2ce9eeabed Fix for broken attachments
Fixes #6467
// FREEBIE
2017-04-02 09:29:26 -07:00
Moxie Marlinspike
5b8e75c068 Bump version to 4.2.1
// FREEBIE
2017-03-31 16:55:20 -07:00
Paride Legovini
c97fa0d3d1 Blacklist OnePlus X from hardware AEC
Closes #6465
// FREEBIE
2017-03-31 16:54:22 -07:00
Moxie Marlinspike
b0bd6ad729 Fix for crash when opening group conversation
Fixes #6464
// FREEBIE
2017-03-31 16:52:50 -07:00
Moxie Marlinspike
d85ddbcd10 Bump version to 4.2.0
// FREEBIE
2017-03-31 10:24:24 -07:00
Moxie Marlinspike
51807226a7 Update language translations
// FREEBIE
2017-03-31 10:23:55 -07:00
FeuRenard
07c8db824e Disable screen during earpiece voice note playback
Fixes #6437
Closes #6445
// FREEBIE
2017-03-31 09:13:00 -07:00
Moxie Marlinspike
75782affd1 Adjust joined signal string
// FREEBIE
2017-03-31 08:54:07 -07:00
FeuRenard
49117a4138 Remove unused icon
Closes #6444
// FREEBIE
2017-03-30 18:51:43 -07:00
Paride Legovini
9d52e6af6a Don't mention CyanogenMod
Closes #6422
// FREEBIE
2017-03-30 18:50:40 -07:00
Moxie Marlinspike
706835584e Update shortcut badger
// FREEBIE
2017-03-30 18:41:29 -07:00
Moxie Marlinspike
f7261cc9e7 Remove GV from registration problems list
// FREEBIE
2017-03-30 18:41:18 -07:00
Moxie Marlinspike
3aae86d20c Update registration activity style
// FREEBIE
2017-03-30 18:18:04 -07:00
Moxie Marlinspike
ad0f2830c8 Raise max gif limit to 25MB
// FREEBIE
2017-03-30 16:12:55 -07:00
Moxie Marlinspike
056f2717ed Remove duplicate column in SQL query
// FREEBIE
2017-03-30 16:12:42 -07:00
Moxie Marlinspike
f67eb5f9f3 Support for receiving arbitrary attachment types
// FREEBIE
2017-03-29 18:17:34 -07:00
Moxie Marlinspike
c69efbffd2 Don't enable speakerphone when video enabled if headset on
Fixes #6431
// FREEBIE
2017-03-24 11:11:48 -07:00
Moxie Marlinspike
3dfc72dad0 Bump version to 4.1.0
// FREEBIE
2017-03-23 16:30:13 -07:00
Moxie Marlinspike
372cdc4b9f Update language translations
// FREEBIE
2017-03-23 16:29:35 -07:00
Moxie Marlinspike
01d66087aa Blacklist Nexus 6 from hardware AEC
Remove all blacklisting from library

// FREEBIE
2017-03-23 16:18:07 -07:00
Moxie Marlinspike
e0e932df02 Add Samsung Galaxy S7 and Sony Xperia SP to AEC blacklist
Related #6241
// FREEBIE
2017-03-23 16:18:07 -07:00
Moxie Marlinspike
3ca653627d Add LG G3 to hardware AEC blacklist
Helps #6241
// FREEBIE
2017-03-23 16:18:07 -07:00
Moxie Marlinspike
f4acaad407 Add Pixel, S5, Redmi Note 3, and Xiaomi Mi4 to AEC blacklist
Make these application-level changes

Helps #6241
// FREEBIE
2017-03-23 16:18:07 -07:00
Moxie Marlinspike
6787a96d71 Revert "Add Pixel, S5, Redmi Note 3, and Xiaomi Mi4 to AEC blacklist"
This reverts commit f5768220f2a0ea6ccc09d2026a29f96bc5046027.
// FREEBIE
2017-03-23 16:18:07 -07:00
Moxie Marlinspike
e7f5022a75 Add Pixel, S5, Redmi Note 3, and Xiaomi Mi4 to AEC blacklist
Addresses #6241
// FREEBIE
2017-03-23 16:18:07 -07:00
Moxie Marlinspike
93e7a626bf Make voice note playback proximity aware
1) Play audio through earpiece if placed to ear

2) Stop playing audio if removed from ear

Fixes #6195
// FREEBIE
2017-03-23 16:18:07 -07:00
Moxie Marlinspike
448335e9bc Bump version to 4.0.1
// FREEBIE
2017-03-22 09:53:37 -07:00
Moxie Marlinspike
7ad68296dd Fix for crash when call initiated from contacts
Fixes #6428
// FREEBIE
2017-03-22 09:49:06 -07:00
Moxie Marlinspike
3d28db3453 Bump version to 4.0.0
// FREEBIE
2017-03-17 11:25:01 -07:00
Moxie Marlinspike
56c0ea0a4f Remove redphone keystore (thanks @paride)
Closes #6405
// FREEBIE
2017-03-17 11:24:13 -07:00
Moxie Marlinspike
b964c74ce8 Updated language translations
// FREEBIE
2017-03-17 10:58:28 -07:00
Moxie Marlinspike
a3445fb2fd Update Dockerfile for new build tools version
// FREEBIE
2017-03-17 10:47:32 -07:00
Moxie Marlinspike
0d11b3dd26 Lets limit GCM refresh to every 6hrs, and only retry once
// FREEBIE
2017-03-17 10:40:34 -07:00
greenjoe
deb96646a3 Add action indicator when resending a message.
When message is being resent, "RESEND" button now disappears.
"Resending..." text is displayed instead of an error message.

Fixes #6307
Closes #6347
2017-03-16 15:27:26 -07:00
FeuRenard
a421630789 Update input after enabling SMS
Fixes #6363
Closes #6387
// FREEBIE
2017-03-16 15:22:02 -07:00
RiseT
4f0422ee94 Fixes misnamed string resource
Closes #6398
// FREEBIE
2017-03-16 15:19:04 -07:00
FeuRenard
0f548a431b Fallback to SMS app for invitations
Fixes #6369
Closes #6400
// FREEBIE
2017-03-16 14:29:41 -07:00
Benedikt Constantin Radtke
742b54f32d fix ContactUpdates for non-e164 contacts
convert every number to e164 before sending it to slaves/siblings.

Closes #6310
2017-03-16 14:25:47 -07:00
Paride Legovini
1c9715f700 More RedPhone cleanup
Closes #6393
// FREEBIE
2017-03-15 16:59:46 -07:00
FeuRenard
52b1e17c36 Unify alert dialog button colors
Fixes #5227
Closes #5415
// FREEBIE
2017-03-15 16:57:11 -07:00
Moxie Marlinspike
9273f5cc67 Switch import/export activity from tabs to cards
// FREEBIE
2017-03-15 16:53:15 -07:00
Moxie Marlinspike
a8366387ab Fix the build
// FREEBIE
2017-03-14 15:47:08 -07:00
Admir Ireiz
5e02715a2c Change the app icon
Closes #6189
2017-03-14 15:46:19 -07:00
Christian Ascheberg
3506f2db12 Improve group update descriptions
Closes #5416
// FREEBIE
2017-03-14 14:26:14 -07:00
haffenloher
66c9fd44df Honor synced end session messages
Fixes #5174
Closes #5178
2017-03-14 14:07:18 -07:00
Tim Serong
944f5aad0d BUILDING.md: clarify build tools version
Closes #6264
// FREEBIE
2017-03-14 13:57:14 -07:00
RiseT
a41e82bb7d Make WebRtcCallScreen_new_safety_numbers_title singular
Closes #6364
// FREEBIE
2017-03-14 13:42:39 -07:00
Moxie Marlinspike
94964474b2 So long redphone
// FREEBIE
2017-03-14 13:24:24 -07:00
Moxie Marlinspike
2f46c6ca1f Don't redisplay notifications after they have been dismissed
Fixes #5751
Fixes #6218
// FREEBIE
2017-03-14 10:09:24 -07:00
Moxie Marlinspike
33e0b4fc6d Bump version to 3.31.4
// FREEBIE
2017-03-13 11:50:20 -07:00
Moxie Marlinspike
bb5e7db57e We don't need to refresh attributes in redphone any longer
// FREEBIE
2017-03-13 11:50:10 -07:00
Moxie Marlinspike
e1d0f2f4e9 Bump version to 3.31.3
// FREEBIE
2017-03-12 11:00:06 -07:00
Moxie Marlinspike
20af8045e8 Update language translations
// FREEBIE
2017-03-12 10:59:39 -07:00
Moxie Marlinspike
3127fda7fe Actually show the GMS update dialog
// FREEBIE
2017-03-12 10:56:51 -07:00
Christian Ascheberg
12b27cc56b Fix WebRTC capability check for unregistered users
Fixes #6358
Closes #6368
// FREEBIE
2017-03-12 10:50:13 -07:00
mcloo
1683bb4636 Choose AudioManager SCO action device depended
Closes #6367
//FREEBIE
2017-03-12 10:47:35 -07:00
mcloo
9d13b9437c Fix NPE crash when no bluetooth is available
Fixes #6355
Closes #6366
2017-03-12 10:45:52 -07:00
Christian Ascheberg
97c3e8fa3f Inform about timed out incoming calls
Closes #6344
// FREEBIE
2017-03-12 10:43:55 -07:00
Moxie Marlinspike
76c41a8295 Bump version to 3.31.2
// FREEBIE
2017-03-10 09:33:55 -08:00
Moxie Marlinspike
edbd20899e Update language translations
// FREEBIE
2017-03-10 09:33:24 -08:00
Moxie Marlinspike
8e25689c24 Modify upstream webrtc NetEq to pass bounds information to speex
Just in case

Closes #6334
// FREEBIE
2017-03-10 09:28:54 -08:00
Moxie Marlinspike
057c348d08 Bump version to 3.31.1
// FREEBIE
2017-03-09 17:31:07 -08:00
Moxie Marlinspike
6866a74d95 Don't display the last seen divider for outgoing calls
// FREEBIE
2017-03-09 17:31:07 -08:00
Moxie Marlinspike
cbba8c0d76 Update signal-service
// FREEBIE
2017-03-09 17:31:03 -08:00
Moxie Marlinspike
c7c411b3f3 Bump version to 3.31.0
// FREEBIE
2017-03-07 13:55:37 -08:00
Moxie Marlinspike
c7782c51db Updated language translations
// FREEBIE
2017-03-07 13:55:27 -08:00
mcloo
7ae0f38c45 Update language list
Closes #6055
2017-03-07 13:20:44 -08:00
Max Muth
2c1a5aef1c Fix occasional crash on Android 7 direct reply
Fixes #6185
Closes #6322
//FREEBIE
2017-03-06 14:08:25 -08:00
FeuRenard
defb173ffe Dark theme support for audio drafts
Fixes #4681
Closes #6251
// FREEBIE
2017-03-06 13:51:03 -08:00
FeuRenard
0095e00bc7 Keep screen on during voice note recording
Closes #6239
Fixes #4646
// FREEBIE
2017-03-06 13:45:34 -08:00
Moxie Marlinspike
ed5faa4ba9 Add video calling intro screen
// FREEBIE
2017-03-06 12:32:09 -08:00
Moxie Marlinspike
1e02d70052 Make webrtc calling default
// FREEBIE
2017-03-06 12:10:26 -08:00
Moxie Marlinspike
b110c8a2cb Reregister GCM on every app start
Fixes #5531
// FREEBIE
2017-03-06 11:50:51 -08:00
Moxie Marlinspike
bdcfabf1ee Silence incoming ringer when power button is pressed
// FREEBIE
2017-03-05 10:36:01 -08:00
Moxie Marlinspike
cd28cd172f Refactor webrtc audio management
Attempts to:

1) Successfully play ringtone through speaker instead of earpiece
   when possible.

2) Manage bluetooth headset connectivity as well as possible

3) Eliminate notification sounds while in-call when possible

4) Make sure audio is correctly setup when receiving calls

Fixes #6271
Fixes #6248
Fixes #6238
Fixes #6184
Fixes #6169

// FREEBIE
2017-03-05 10:35:55 -08:00
Moxie Marlinspike
3904c76261 Some additional debug logging
Related #6305
// FREEBIE
2017-02-28 17:06:05 -08:00
Moxie Marlinspike
cb6e048070 Don't try to unregister for GCM if Play Services doesn't exist
Fixes #6314
// FREEBIE
2017-02-28 16:59:15 -08:00
Moxie Marlinspike
9b8719e2d5 Support for website distribution build with auto-updating APK
// FREEBIE
2017-02-27 23:53:36 -08:00
Moxie Marlinspike
79e925051a Support for attachment digests
// FREEBIE
2017-02-26 11:16:01 -08:00
Moxie Marlinspike
a37d2f568c Update webrtc to M57
// FREEBIE
2017-02-26 11:16:01 -08:00
Moxie Marlinspike
e92b51ed98 Run webrtc calls as foreground service
Should hopefully stop performance degredation when in background

Fixes #6249
// FREEBIE
2017-02-26 11:16:01 -08:00
Moxie Marlinspike
cb9f225f59 Don't start VideoCapturer until video enabled.
Should help with battery consumption on audio-only calls

Fixes #6259
// FREEBIE
2017-02-26 11:16:01 -08:00
Moxie Marlinspike
f4a7f354c5 Bump version to 3.30.4
// FREEBIE
2017-02-26 10:51:13 -08:00
Moxie Marlinspike
8f96cff104 Don't let outgoing messages trigger last seen divider
Closes #6306
// FREEBIE
2017-02-26 10:49:48 -08:00
Siloportem
1d3f1cc79e Revert "Fixing broken unit test for ConversationAdapter"
Fixes #6250
Commit 7286fd9 that broke this unit test was reverted so the change to
this unit test has also to be reverted since the unit test currently
fails.

Closes #6308
This reverts commit 11463d410d.
2017-02-26 10:13:15 -08:00
Christian Ascheberg
25daf01307 Fix unread messages timestamp comparison
Closes #6302
// FREEBIE
2017-02-26 10:11:37 -08:00
Moxie Marlinspike
741066a10e Bump version to 3.30.3
// FREEBIE
2017-02-24 17:28:49 -08:00
Christian Ascheberg
44bb2c7c72 Do not call Notification.setSound with empty ringtone
Closes #6293
// FREEBIE
2017-02-24 17:27:25 -08:00
Moxie Marlinspike
65c05e0388 Fix outbound calls for non-play-services users
Fixes #6272
// FREEBIE
2017-02-23 10:07:12 -08:00
Moxie Marlinspike
8cd50d1e82 Update last seen state on desktop sync send
// FREEBIE
2017-02-22 15:05:35 -08:00
Moxie Marlinspike
2395b79bfc Bump version to 3.30.2
// FREEBIE
2017-02-22 12:48:01 -08:00
haffenloher
76ac95756f Fix last seen divider crash on Android <5.0
Apparently, it's not possible to reference an attribute in an xml
drawable on API <21, so we have to use separate light and dark theme
drawables instead.

Closes #6285
2017-02-22 17:57:42 +01:00
Moxie Marlinspike
d9659219de Bump version to 3.30.1
// FREEBIE
2017-02-21 22:34:46 -08:00
Moxie Marlinspike
bdc464193d Adjust last seen divider on read sync
Fixes #6273
// FREEBIE
2017-02-21 22:33:16 -08:00
Moxie Marlinspike
b43beaab75 Reduce size of new message divider, adjust style slightly
// FREEBIE
2017-02-21 12:55:44 -08:00
Moxie Marlinspike
4ee607878c Fix unread message conversation separator for dark theme
Fixes #6265
// FREEBIE
2017-02-21 12:37:40 -08:00
Moxie Marlinspike
a0489a9f48 Bump version to 3.30.0
// FREEBIE
2017-02-20 16:45:03 -08:00
Moxie Marlinspike
8aab9b0fc1 Fix build (grr)
// FREEBIE
2017-02-20 16:44:25 -08:00
Moxie Marlinspike
4bd3841788 Updated language translations
// FREEBIE
2017-02-20 15:32:59 -08:00
Moxie Marlinspike
b27d829013 Extract some strings for localization
// FREEBIE
2017-02-20 13:59:23 -08:00
Moxie Marlinspike
1669731329 Support for using Signal without Play Services
This is now possible with beta calling, so non-GCM users are a
part of beta calling by default.

// FREEBIE
2017-02-20 12:00:03 -08:00
Moxie Marlinspike
4112f23f33 Remove item animations on conversation list recyclerview
// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
eddb97013a Disable proximity lock when local video is enabled
Fixes #6179
// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
a075bf7505 Don't scroll to last seen until the recyclerview has been measured
// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
acca4a72d3 Improve default SMS subscription id intelligence
Fixes #5266
// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
1b1470aae2 Upgrade to EventBus 3.X
// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
d5b7ff58e2 Fix for last_seen crash when archive placeholder is visible
// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
d2eebbc55a Little bit of extra SmsListener logging
Related #5253
// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
cf891edce9 Should fix "locked message" on reminder notification issue
Fixes #5782
// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
f541e33356 Publish TURN-only ICE candidates in some situations
1) Incoming call is from a number not in user's address book

2) Turn-only preference is enabled for all incoming/outgoing calls

// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
aa30f3e410 Revert "Don't use SHA1 for stable IDs"
This reverts commit 7286fd9b06.

Fixes #6223
// FREEBIE
2017-02-19 12:29:33 -08:00
haffenloher
83e31cac07 Show videos in media overview
Fixes #5941
Closes #6152
// FREEBIE
2017-02-19 12:29:33 -08:00
FeuRenard
98d223f094 Don't display date for drafts in media preview
Closes #6208
// FREEBIE
2017-02-19 12:29:33 -08:00
RiseT
917389131c Fix some wording for group conversations
Closes #6204
Fixes #6193

// FREEBIE
2017-02-19 12:29:33 -08:00
Nicholas Rizzio
e1f09e0437 Debloat ConversationAdapter's tag
getName() includes the full package name, which adds a ridiculous
amount of text to the debug log. Using getSimpleName() is in line with
the rest of the repository.

Closes #6202
// FREEBIE
2017-02-19 12:29:33 -08:00
Mattias Eriksson
0f820e6beb Re-add Android Auto manifest entry
Voice reply is now verified to work,
so it should be safe to re-add the
Android Auto manifest entry.

Closes #6180
//FREEBIE
2017-02-19 12:29:33 -08:00
Mattias Eriksson
e2d94adfdb Add Intent.FLAG_INCLUDE_STOPPED_PACKAGES
Add Intent.FLAG_INCLUDE_STOPPED_PACKAGES to Android Auto intents to
match https://developer.android.com/training/auto/messaging/index.html

// FREEBIE
2017-02-19 12:29:33 -08:00
brumsel
c594691b93 Fix resend buttons being shown when they shouldn't
Correctly set the IS_PUSH_GROUP_EXTRA flag for MessageDetailsActivities
started by selecting a message and pressing the (i) icon in the action
bar

Closes #6171
Fixes #3582

// FREEBIE
2017-02-19 12:29:33 -08:00
haffenloher
9395f7faa0 Correct PushGroupUpdateJob's TAG
Closes #6166

// FREEBIE
2017-02-19 12:29:33 -08:00
haffenloher
9c1f7f1657 Make VideoPlayer toast error message translatable
Closes #6150
// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
8bf160532e Make safety numbers singular in webrtc call screen
Closes #6148
// FREEBIE
2017-02-19 12:29:33 -08:00
Christian Ascheberg
1aa2d546d2 enable silent per recipient ringtone preference
Closes #4957
// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
143fb1fe21 Make header decorations play well together
// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
d9b42c4369 Support for a "new messages" divider in conversations
// FREEBIE
2017-02-19 12:29:33 -08:00
Moxie Marlinspike
0075940050 Delete archived sessions on identity change
// FREEBIE
2017-02-19 12:29:08 -08:00
Moxie Marlinspike
7d10560575 Workaround android SurfaceView bug
Fixes #6225
// FREEBIE
2017-02-16 13:01:45 -08:00
Moxie Marlinspike
0adce89eec Bumped version to 3.29.6
// FREEBIE
2017-02-13 23:01:43 -08:00
Moxie Marlinspike
be53bc6138 Updated language translations
// FREEBIE
2017-02-13 23:01:32 -08:00
Moxie Marlinspike
e25d31ceb6 Disable webrtc calling for Gingerbread users
Fixes #6220
// FREEBIE
2017-02-13 22:55:06 -08:00
Moxie Marlinspike
70d94c0130 Bump version to 3.29.5
// FREEBIE
2017-02-12 20:24:22 -08:00
Moxie Marlinspike
55c1b6d72c Updated language translations
// FREEBIE
2017-02-12 20:24:00 -08:00
Moxie Marlinspike
42211ccca6 Bump version to 3.29.4
// FREEBIE
2017-02-12 16:54:31 -08:00
Moxie Marlinspike
0efd6d9341 Don't use AsyncTask for beta calling capabilities refresh
Also, actually store the result in the directory db.

Fixes #6212
// FREEBIE
2017-02-12 11:27:26 -08:00
Moxie Marlinspike
6b737a3d48 Bump version to 3.29.3
// FREEBIE
2017-02-11 21:11:28 -08:00
Moxie Marlinspike
f3e47f7b60 Support for minimized controls during video call
// FREEBIE
2017-02-11 20:48:42 -08:00
Moxie Marlinspike
6b8336db06 Blacklist Nexus 6p from hardware AEC
// FREEBIE
2017-02-08 23:40:22 -08:00
Moxie Marlinspike
739ee89fb1 Bump version to 3.29.2
// FREEBIE
2017-02-05 13:02:55 -08:00
Moxie Marlinspike
fb8440f886 Correctly manage busy state for (webrtc, redphone, pstn) tuple
Fixes #6156
// FREEBIE
2017-02-05 12:38:08 -08:00
Moxie Marlinspike
d92cbfe305 More intelligent default behavior with speakerphone and wired headset
When video is enabled, speakerphone is now enabled unless
there's a wired headset.  If speakerphone is enabled and
a wired headset gets plugged in, speakerphone is disabled.
If video is enabled and a wired headset is removed, speakerphone
is enabled.

Fixes #6153
// FREEBIE
2017-02-03 12:01:03 -08:00
Moxie Marlinspike
5cfd7477ab Keep websocket connection open during call
// FREEBIE
2017-02-03 11:59:10 -08:00
Moxie Marlinspike
0992d6545e Don't sleep screen in calls
Fixes #6141
// FREEBIE
2017-02-02 19:02:26 -08:00
Moxie Marlinspike
7d644ae9c6 Run local hangup events through view model
Fixes #6143
// FREEBIE
2017-02-02 18:53:45 -08:00
Moxie Marlinspike
9a93a8b28d Better support for building webrtc call view off of model
Fixes #6144
// FREEBIE
2017-02-02 18:46:34 -08:00
Moxie Marlinspike
8dc6f2b15b Mark egl resources as freed in webrtc terminate
Fixes #6138
// FREEBIE
2017-02-01 22:55:19 -08:00
Moxie Marlinspike
f148ff8bfa Bump version to 3.29.1
// FREEBIE
2017-02-01 18:37:57 -08:00
Moxie Marlinspike
2408bd4d65 Fix for groups crash when beta calling enabled
Fixes #6137
// FREEBIE
2017-02-01 18:30:53 -08:00
Moxie Marlinspike
94c61f8af9 Bump version to 3.29.0
// FREEBIE
2017-02-01 13:57:19 -08:00
Benedikt Constantin Radtke
85aa5c5b97 use canonical number when sending blocked updates
MultiDeviceBlockedUpdates now send e164 numbers instead
 of localized ones.

Fixes #6093
Closes #6109
// FREEBIE
2017-02-01 13:55:52 -08:00
FeuRenard
c88a0ba324 Fix linkifying in selection mode
Fixes #6106
Closes #6108
// FREEBIE
2017-02-01 13:55:52 -08:00
Stuart Gilbert
11463d410d Fixing broken unit test for ConversationAdapter
The unit test for ConversationAdapter.getItemId() was
broken by this change: 7286fd9

Fixes #6088
// FREEBIE
2017-02-01 13:55:52 -08:00
Moxie Marlinspike
53d590947e Force capability refresh on conversation load if in webrtc beta
// FREEBIE
2017-02-01 13:55:52 -08:00
Moxie Marlinspike
ea0945d406 Beta support for webrtc video and voice calling
// FREEBIE
2017-02-01 13:55:52 -08:00
Moxie Marlinspike
a9651e2e9c Bump version to 3.28.4
// FREEBIE
2017-01-31 21:55:33 -08:00
Moxie Marlinspike
9afbdaa2be Don't let failed capability retrieval erroneously disable SMS
Fixes #6135
// FREEBIE
2017-01-31 21:46:20 -08:00
Moxie Marlinspike
bdc8618889 Bump version to 3.28.3
// FREEBIE
2017-01-30 19:19:26 -08:00
Moxie Marlinspike
a2de60a75c Remove Android Auto manifest entry to get past the reviewers
(There are reviewers now?)

Related #6124
// FREEBIE
2017-01-30 19:17:17 -08:00
Moxie Marlinspike
b2e93ec502 Bump version to 3.28.2
// FREEBIE
2017-01-29 13:34:51 -08:00
Moxie Marlinspike
4fb8d1fa49 Fix for NPE when MMS From is absent
Fixes #6115
// FREEBIE
2017-01-29 13:16:51 -08:00
Moxie Marlinspike
67cab3ce86 Fix illegalargumentexception on rotate
Fixes #6118
// FREEBIE
2017-01-29 13:02:59 -08:00
Moxie Marlinspike
3be55e36d9 Bump version to 3.28.1
// FREEBIE
2017-01-26 12:08:23 -08:00
Moxie Marlinspike
cee0edff7c Updated language translations
// FREEBIE
2017-01-26 12:08:04 -08:00
Moxie Marlinspike
15a389c171 Don't calculate date header item for adapter header
Fixes #6098
// FREEBIE
2017-01-25 18:00:26 -08:00
Moxie Marlinspike
d46d3b72c8 Make the sticky date header only visible during scroll
// FREEBIE
2017-01-25 16:38:36 -08:00
Moxie Marlinspike
2e16c6cf41 Bump version to 3.28.0
// FREEBIE
2017-01-24 18:31:35 -08:00
Moxie Marlinspike
03e2075ba4 Updated language translations
// FREEBIE
2017-01-24 17:54:19 -08:00
Moxie Marlinspike
d9f19fe36c Move scroll-to-bottom arrow placement up slightly
// FREEBIE
2017-01-24 17:51:32 -08:00
Moxie Marlinspike
b575b4e6ae Fix for intermittent crash
// FREEBIE
2017-01-24 17:51:32 -08:00
Moxie Marlinspike
342fd37799 Updated language translations
// FREEBIE
2017-01-24 11:11:53 -08:00
Moxie Marlinspike
e2b81c9637 Update look and feel of fast-scroll-to-bottom
Closes #6086
// FREEBIE
2017-01-24 11:05:32 -08:00
Stuart Gilbert
aa9d8e4d14 Add scroll to bottom button in conversation view
Added a FloatingActionButton to the conversation_fragment
that appears and disappears using the same logic as the
existing compose divider: appear when the conversation list
is scrolled away from the bottom, disappear when the list is
scrolled to the bottom.

Fixes #5651
2017-01-24 11:05:03 -08:00
Moxie Marlinspike
4c815db076 Support for sticky date headers
Closes #4696
// FREEBIE
2017-01-23 16:44:38 -08:00
Moxie Marlinspike
b677370597 Apparently this doesn't work in Cuba
// FREEBIE
2017-01-23 10:46:57 -08:00
Moxie Marlinspike
f53d64ab7a Remove ShortcutBadger "default launcher" junk
// FREEBIE
2017-01-22 22:45:58 -08:00
Benedikt Constantin Radtke
4461ebf662 check if image decoding succeeded before using the result
Fixes #6061
Closes #6080
// FREEBIE
2017-01-22 22:05:27 -08:00
Moxie Marlinspike
21a0fe3a48 Don't return unresolved asynchronous recipients for non-async callers
Fixes #6082
// FREEBIE
2017-01-22 21:57:23 -08:00
Moxie Marlinspike
dadc8d0183 Refactor "unnamed" group logic
// FREEBIE
2017-01-22 21:23:51 -08:00
Moxie Marlinspike
7e51d61c79 Ignore duplicate signal messages
Fixes #5579

// FREEBIE
2017-01-22 14:47:02 -08:00
john gravois
47aa7979b2 small CONTRIBUTING copyedits
Closes #6067
// FREEBIE
2017-01-21 10:32:11 -08:00
Nicholas Rizzio
da05cf9192 Use HTTPS for all support links
support.whispersystems.org is now available through TLS, but is not
included in the HSTS preload list. Hence, these links are vulnerable
to SSL stripping until the user visits the site over HTTPS for the
first time. Changing these links to https:// ensures that the user
always gets the encrypted version of the support website.

Closes #6056
// FREEBIE
2017-01-21 10:20:58 -08:00
Piotr Prucia
970448d43d Disable AudioView controls clicks when message is selected
Fixes: #5898
Closes #6054
2017-01-21 10:18:18 -08:00
RiseT
333a0f38e3 Remove one ellipsis I've overlooked in #5887
Closes #6052
// FREEBIE
2017-01-21 10:13:40 -08:00
Moxie Marlinspike
86df150374 Update ShortcutBadger
Fixes #6069
// FREEBIE
2017-01-21 10:06:49 -08:00
Moxie Marlinspike
235a8472d9 Remove dedicated MMS download controls
// FREEBIE
2017-01-20 15:26:17 -08:00
Moxie Marlinspike
183f8742a7 ViewStub for ThumbnailView in ConversationItem
// FREEBIE
2017-01-20 10:27:18 -08:00
Moxie Marlinspike
e270e8d429 ViewStub for AudioView in ConversationItems
// FREEBIE
2017-01-20 09:11:40 -08:00
Moxie Marlinspike
7286fd9b06 Don't use SHA1 for stable IDs
// FREEBIE
2017-01-19 19:06:46 -08:00
Moxie Marlinspike
9f2328457e Mark application largeHeap
// FREEBIE
2017-01-19 18:42:17 -08:00
Moxie Marlinspike
f2a9b02b5e Add a little timing information
// FREEBIE
2017-01-19 11:47:02 -08:00
Moxie Marlinspike
41c9bed155 ViewStub for EmojiDrawer
// FREEBIE
2017-01-19 11:47:02 -08:00
Moxie Marlinspike
508a666e76 ViewStub for ReminderView, lazy create AttachmentTypeSelector
// FREEBIE
2017-01-19 11:47:02 -08:00
Moxie Marlinspike
3d6cbdd775 ViewStub for entire AttachmentManager
// FREEBIE
2017-01-19 11:47:02 -08:00
Moxie Marlinspike
4906bdbdcc Make default SMS provider lookup asynchronous
// FREEBIE
2017-01-18 11:01:13 -08:00
Moxie Marlinspike
f0b615eda6 Bump version to 3.27.1
// FREEBIE
2017-01-17 20:57:22 -08:00
Moxie Marlinspike
0a25c3a33d Updated language translations
// FREEBIE
2017-01-17 20:56:56 -08:00
Moxie Marlinspike
bbb8ac113b Disable image keyboards for SDK < 5.0
Fixes #6045
// FREEBIE
2017-01-17 20:46:20 -08:00
Moxie Marlinspike
360c2b2a50 This attempts to work around a ROM crash bug
getActiveNotifications() seems to throw an NPE on some Motorola
ROMs, all of which appear to be 6.0.1.  This change just swallows
the exception.

6.0 doesn't support bundled notifications, so I think it's alright
if they don't get canceled, since the summary notification will
still be displayed correctly.

This would only affect users who have an android wear device
attached to one of these buggy ROMs. By swallowing this exception,
they would not always get notifictions dismissed on their wear
 device.

Fixes #6043
// FREEBIE
2017-01-17 20:41:24 -08:00
Moxie Marlinspike
cfef855d99 Bump version to 2.27.0
// FREEBIE
2017-01-13 18:06:41 -08:00
Moxie Marlinspike
80503067e9 Updated language translations
// FREEBIE
2017-01-13 18:06:19 -08:00
Moxie Marlinspike
9779604932 Had to re-publish signal-service dependency
// FREEBIE
2017-01-13 16:38:45 -08:00
Moxie Marlinspike
c6d6e0e97e Updated language translations
// FREEBIE
2017-01-12 16:37:30 -08:00
Moxie Marlinspike
edac0e85c7 Fix non-thread-safe operations on canonical id cache
// FREEBIE
2017-01-12 16:06:14 -08:00
Moxie Marlinspike
fd3d02d818 Fix typo
// FREEBIE
2017-01-12 12:26:50 -08:00
Veeti Paananen
25f9bef74c Display elapsed voice recording time in user language
Closes #6011
// FREEBIE
2017-01-12 11:49:47 -08:00
Veeti Paananen
4dae4444bc Fix right-to-left language support for voice recording
Bug: fixes #5999

// FREEBIE
2017-01-12 11:47:43 -08:00
RiseT
49e78d16ba Remove redundant ellipses in strings according to Material guidelines
Quote :
"Use to indicate an action in progress ("Downloading…") or
 incomplete or truncated text. No space before the ellipses.

 Omit from menu items or buttons that open a dialog or start
  some other process.

 Midline ellipses (three-bullet glyphs) are also used to represent
 numeric truncation and the redaction of sensitive data, such as
 credit cards."

 https://material.google.com/style/writing.html

Closes #5887
// FREEBIE
2017-01-12 10:38:49 -08:00
Moxie Marlinspike
cb23e3a930 Untrusted identity is not always a legacy message content
Closes #5924
Fixes #5922
// FREEBIE
2017-01-12 10:33:23 -08:00
Niklas Wenzel
770026d4ee Fix the faulty tests in AttachmentDatabaseTest.java
Fixes #5948
Closes #5952
2017-01-12 10:23:35 -08:00
Moxie Marlinspike
7b928476a2 Make sure recipients are fully resolved, limit size of results
// FREEBIE
2017-01-12 09:52:24 -08:00
Moxie Marlinspike
a125fcb8fa Support for direct share targets
Fixes #4333
// FREEBIE
2017-01-11 19:54:58 -08:00
FeuRenard
bd819d7d10 Disable verify button if no message was exchanged
Fixes #5878
Closes #5951
// FREEBIE
2017-01-11 18:51:11 -08:00
Piotr Prucia
e5fcc465c9 Fixed action bar title not being translated after language change
Fixes #6009
Closes #6010
// FREEBIE
2017-01-11 18:46:08 -08:00
Moxie Marlinspike
94a29e375f Specify ConnectionSpecs for domain fronts
// FREEBIE
2017-01-11 15:37:51 -08:00
Moxie Marlinspike
ec5ac44cd3 Update okhttp and support for transmitting messages over websocket
// FREEBIE
2017-01-10 13:59:32 -08:00
Moxie Marlinspike
ac2626437e Bump version to 3.26.2
// FREEBIE
2017-01-09 08:00:53 -08:00
Moxie Marlinspike
99b8cfc82b Include missing cardview dependency
Fixes #6026
// FREEBIE
2017-01-09 07:51:56 -08:00
Moxie Marlinspike
6eef1a6ee4 Bump version to 3.26.1
// FREEBIE
2017-01-08 13:11:48 -08:00
Moxie Marlinspike
4ad989cc38 Fix rounded corners bitmap double free
Fixes #4732
// FREEBIE
2017-01-08 13:06:11 -08:00
Moxie Marlinspike
5804213152 Eliminate item animations in ConversationFragment
Experience feels faster this way too

// FREEBIE
2017-01-08 10:16:23 -08:00
Moxie Marlinspike
d599c058c6 No choice but to multiDex
// FREEBIE
2017-01-08 09:58:01 -08:00
Moxie Marlinspike
b7d4294314 This is no longer testable =(
// FREEBIE
2017-01-07 11:36:50 -08:00
Moxie Marlinspike
d280604f1f Fix compileSdk 25 problems with GIF search
For #5965
// FREEBIE
2017-01-07 11:02:18 -08:00
AsamK
7817e38e5f Fix crash when clicking on a gif image
For gif images, the dimensions is always null.

Closes #6021
//FREEBIE
2017-01-07 10:40:22 -08:00
Moxie Marlinspike
f310dd6047 Update Play Services
Apparently we've put this off for as long as we can

Fixes #6018
// FREEBIE
2017-01-06 18:00:40 -08:00
Moxie Marlinspike
30633c9672 Bump version to 3.26.0
// FREEBIE
2017-01-06 11:48:49 -08:00
Moxie Marlinspike
16c44812c8 Update Dockerfile to support new compileSdk target
// FREEBIE
2017-01-06 11:48:35 -08:00
Moxie Marlinspike
1a57ff16cd Updated language translations
// FREEBIE
2017-01-06 11:36:02 -08:00
Moxie Marlinspike
c3451d19db This doesn't work in Iran
// FREEBIE
2017-01-06 09:40:04 -08:00
Moxie Marlinspike
bb5dcb7131 Start increasing frequency of signed prekey rotation
// FREEBIE
2017-01-06 09:19:58 -08:00
Moxie Marlinspike
884d8b7f72 Store display name in Signal contacts
Fixes #5974
// FREEBIE
2017-01-05 12:42:28 -08:00
Moxie Marlinspike
57cdbaedd6 Remove EXTRA_SUBJECT from safety number share.
Negatively impacts share through email slightly, positively
impacts share through a few other mechanisms somewhat
significantly.

Fixes #5959
// FREEBIE
2017-01-03 13:57:09 -08:00
Moxie Marlinspike
3861084ea2 Disable expiration menu on inactive group
Fixes #6007
// FREEBIE
2017-01-03 13:51:29 -08:00
Piotr Prucia
bb1ab2e929 Added Iran to domain fronting list
Fixes #5992
Closes #6006
// FREEBIE
2017-01-02 17:22:24 -08:00
Ali Makki
5a6e75a7e1 +968 uses google.com.om +53 uses google.com.cu
Closes #6001
2017-01-02 17:18:42 -08:00
Moxie Marlinspike
d2be49af42 Support for tiling image view and large image viewing
Fixes #5949
Fixes #5574
Fixes #4380
// FREEBIE
2017-01-02 17:17:48 -08:00
FeuRenard
477589b092 Color passphrase prompt text field blue
Closes #5424
// FREEBIE
2017-01-02 17:17:48 -08:00
Benedikt Constantin Radtke
a6488b3652 fix zero length attachments crashing signal
Fixes #5331
Closes #5926
2017-01-02 17:17:48 -08:00
FeuRenard
cde92256a6 Convert file save toast string to plural
Closes #5961
// FREEBIE
2017-01-02 17:17:48 -08:00
Echo
47f1f0b9a0 Update crowdfunding link
Closes #5984
// FREEBIE
2017-01-02 17:17:48 -08:00
Moxie Marlinspike
a3019be7b6 Support for image keyboards
// FREEBIE
2017-01-02 17:17:48 -08:00
Moxie Marlinspike
373a0f9527 Support for Android N direct reply notifications
// FREEBIE
2017-01-02 17:17:48 -08:00
Moxie Marlinspike
a9bd84c69c Support for bundled notifications (Android wear and Android N)
// FREEBIE
2017-01-02 17:17:48 -08:00
Moxie Marlinspike
0c6bfdbd0d Improve canonical address database caching
// FREEBIE
2017-01-02 17:17:48 -08:00
Moxie Marlinspike
cdf3a849e9 Reduce DB updates on send path, move support SDK up to 24
// FREEBIE
2017-01-02 17:17:48 -08:00
Moxie Marlinspike
4e32fb21fe Bump version to 3.25.4
// FREEBIE
2016-12-30 08:47:10 -08:00
Moxie Marlinspike
ae40715526 Support for expanded domain fronting strategies
// FREEBIE
2016-12-29 20:54:05 -08:00
Moxie Marlinspike
7488525641 Add Cuba and Oman to domain fronting list
// FREEBIE
2016-12-21 14:28:41 -08:00
Moxie Marlinspike
fd00298930 Bump version to 3.25.3
// FREEBIE
2016-12-21 09:59:40 -08:00
Moxie Marlinspike
f3f2f29b23 Fix avatar download crash bug
Fixes #5980
// FREEBIE
2016-12-21 09:58:45 -08:00
Moxie Marlinspike
d35133b3bc Bump version to 3.25.2
// FREEBIE
2016-12-20 09:56:38 -08:00
Moxie Marlinspike
541718fd11 Support for censorship circumvention in Egypt and UAE
// FREEBIE
2016-12-20 09:55:52 -08:00
Moxie Marlinspike
777aeea138 Bump version to 3.25.1
// FREEBIE
2016-12-19 11:10:42 -08:00
Moxie Marlinspike
c3ab6e6c29 Updated language translations
// FREEBIE
2016-12-19 11:10:35 -08:00
Moxie Marlinspike
c7e373ed55 Update emoji category images to fix SDK <21 tinting issues
Fixes #5973
// FREEBIE
2016-12-18 21:05:01 -08:00
Moxie Marlinspike
71f8e9eb31 Revert support library update, the future wasn't all we hoped for
Fixes #5965
// FREEBIE
2016-12-18 19:06:39 -08:00
Moxie Marlinspike
899f3af5e4 Scale down bitmap during scribble rendering on lowmem devices
Fixes #5969

// FREEBIE
2016-12-17 18:59:47 -08:00
Moxie Marlinspike
4ff8de0ca8 Remove superfluous icon and padding that came with sdk 24
Fixes #5965
// FREEBIE
2016-12-17 15:52:27 -08:00
Moxie Marlinspike
d6d3d1fee4 Bump version to 3.25.0
// FREEBIE
2016-12-16 09:59:19 -08:00
Moxie Marlinspike
9a1225fe21 Updated language translations
// FREEBIE
2016-12-16 09:59:06 -08:00
Moxie Marlinspike
5d6439030d Update Dockerfile to support new compileSdk target
// FREEBIE
2016-12-16 09:53:13 -08:00
Moxie Marlinspike
f871d83e68 No need to run this job on install
// FREEBIE
2016-12-16 09:10:44 -08:00
Moxie Marlinspike
47471f09f4 Update photoview library
Fixes #5955

// FREEBIE
2016-12-15 11:34:46 -08:00
Moxie Marlinspike
ee07a59950 Updated language translations
// FREEBIE
2016-12-15 10:44:03 -08:00
RiseT
e8555a84ac Make description strings in audio_view.xml translatable.
Closes #5916
// FREEBIE
2016-12-15 10:41:18 -08:00
Paul Lanctot
73bf75f65f Accessible content labels for attachment icons
Fixes #5908
Closes #5917
// FREEBIE
2016-12-14 20:56:37 -08:00
Moxie Marlinspike
01bc2ebde4 Don't print safety number changes in inactive groups
Fixes #5930
// FREEBIE
2016-12-14 16:20:09 -08:00
Moxie Marlinspike
b16a27c249 Update libsignal-service
Fixes #5928

// FREEBIE
2016-12-14 16:17:42 -08:00
Moxie Marlinspike
791cc4b4f8 Use downsampled GIFs for MMS messages
Fixes #5958
// FREEBIE
2016-12-14 11:58:47 -08:00
Amire80
71276161fc Remove comma splice from an English interface string 2016-12-12 17:44:04 -08:00
Moxie Marlinspike
a4c17e5325 Support for generating video thumbnails
// FREEBIE
2016-12-12 17:38:05 -08:00
Moxie Marlinspike
6308e6491a A slight foray into the modern era
// FREEBIE
2016-12-12 17:38:05 -08:00
Moxie Marlinspike
f7474362ff Updated emoji set
// FREEBIE
2016-12-12 17:37:27 -08:00
Moxie Marlinspike
1b44bdcd3c Support for stickers and scribbles
// FREEBIE
2016-12-12 17:37:00 -08:00
Moxie Marlinspike
c8fe671f9c Bump version to 3.24.1
// FREEBIE
2016-12-04 18:13:35 -08:00
Nicholas Rizzio
2197d77ffc Fix the content description of the audio record button
Fixes #5910
Closes #5911
// FREEBIE
2016-12-04 18:12:48 -08:00
Benedikt Constantin Radtke
d9ff5b00b7 fix NPE in PushGroupUpdateJob
Fixes #5919
Closes #5921
// FREEBIE
2016-12-04 18:06:25 -08:00
Moxie Marlinspike
5d341e175d Bump version to 3.24.0
// FREEBIE
2016-12-01 12:03:34 -08:00
Moxie Marlinspike
f6cbae602d Fix broken build (grrr @RiseT)
// FREEBIE
2016-12-01 12:03:01 -08:00
Moxie Marlinspike
e3a7781392 Updated language translations
// FREEBIE
2016-12-01 11:38:19 -08:00
Moxie Marlinspike
cf01959e16 Support recovering forgotten/unknown group info from sender
Closes #5876
// FREEBIE
2016-12-01 10:34:47 -08:00
FeuRenard
10abd09239 Catch up on renaming 'All images' button
Closes #5896
// FREEBIE
2016-11-28 14:57:32 -08:00
FeuRenard
3136cadf59 Use Signal's language for media preview timestamp
Fixes #3449
Closes #5600

// FREEBIE
2016-11-28 09:45:44 -08:00
FeuRenard
09ff8d5865 Add gallery button to MediaPreview
// FREEBIE
2016-11-28 09:42:26 -08:00
RiseT
43e1d452c7 Change DateUtils string 'Now' to 'Just now'
Changes the DateUtils string 'Now' to 'Just now' which is a better fit
imho.
Used for messages in the conversation view that e. g. just have been
received.

// FREEBIE

Closes #5761
2016-11-28 09:16:38 -08:00
Moxie Marlinspike
ed8215de81 Move null recipients check
// FREEBIE

Closes #5800
2016-11-28 09:14:44 -08:00
Moxie Marlinspike
69b102bfe3 Support for playing video in-app
// FREEBIE

Closes #5892
2016-11-27 19:38:59 -08:00
Moxie Marlinspike
8b342ee18b Support for "recent photos" thumbnailsabove attachment selector
// FREEBIE

Closes #5893
2016-11-27 19:37:31 -08:00
RiseT
e8ae6d67b1 Change safety number strings to be singular
// FREEBIE

Closes #5894
2016-11-27 19:35:54 -08:00
Mattias Eriksson
9148b7da5f Initial Android Auto support
This adds android auto support accordign to
https://developer.android.com/training/auto/messaging/index.html#messaging
However, since android auto is not officially supported in my country,
the functionality is limited. Which means that I have not been able
to fully test everything yet.

What work is:
* Message notification is shown.
* When you click on it, the message is read.

Closes #5880
2016-11-27 19:33:11 -08:00
Moxie Marlinspike
ce812ed8ba Bump version to 3.23.0
// FREEBIE
2016-11-24 09:11:37 -08:00
Moxie Marlinspike
030df09f67 Updated language translations
// FREEBIE
2016-11-24 09:05:16 -08:00
zaprice
794e2cb872 Do not disable multiline input when enter key sends
Fixes #5264
Closes #5783
2016-11-24 08:31:12 -08:00
Niklas Wenzel
0d493a3af9 Get the automated tests up and running again
* Fix the build.gradle file
* Use the correct VisibleForTesting class
* Fix the Android test setUp() logic
* Enable a test in DeliveryReceiptJobTest.java where the @Test anotation was missing

It should be noted that the tests in AttachmentDatabaseTest.java fail.

Fixes #3474
Closes #5882
2016-11-24 08:13:46 -08:00
Moxie Marlinspike
3787551878 Squelch notifications for active desktop converastions
Additionally, limit audible notifications to once every 2 seconds.

// FREEBIE

Fixes #4905
Fixes #3165
Closes #5813
2016-11-24 08:09:34 -08:00
Moxie Marlinspike
7c0dacc627 Updated language translations
// FREEBIE
2016-11-22 21:46:36 -08:00
Moxie Marlinspike
8af9b7fd15 Improve animations on audio controls, enable push to talk
// FREEBIE
2016-11-21 18:58:10 -08:00
FeuRenard
3e008f6752 Hide linked devices pref for unregistered users
Fixes #4860
Closes #5872
// FREEBIE
2016-11-21 09:53:36 -08:00
Moxie Marlinspike
8fdcff9f20 If Signal isn't enabled for receiving SMS, don't allow sending SMS
Closes #5877
// FREEBIE
2016-11-21 08:56:21 -08:00
7842 changed files with 369820 additions and 914708 deletions

View File

@@ -1,17 +1,21 @@
<!-- This is a bug report template. By following the instructions below and filling out the sections with your information, you will help the developers to get all the necessary data to fix your issue.
<!-- This is a bug report template. By following the instructions below and filling out the sections with your information, you will help the developers get all the necessary data to fix your issue.
You can also preview your report before submitting it. You may remove sections that aren't relevant to your particular case.
Before we begin, please note that this tracker is only for issues, not questions or comments.
Before we begin, please note that this tracker is only for issues. It is not for questions, comments, or feature requests.
If you are looking for support, please see our support center instead:
http://support.whispersystems.org/
or email support@whispersystems.org
If you would like to discuss a new feature or submit suggestions, please visit the community forum:
https://community.signalusers.org
Let's begin with a checklist: replace the empty checkboxes [ ] below with checked ones [x] accordingly -->
If you are looking for support, please visit our support center:
https://support.signal.org/
or email support@signal.org
I have:
- [ ] searched open and closed issues for duplicates
- [ ] read https://github.com/WhisperSystems/Signal-Android/wiki/Submitting-useful-bug-reports
Let's begin with a checklist: Replace the empty checkboxes [ ] below with checked ones [x] accordingly. -->
- [ ] I have searched open and closed issues for duplicates
- [ ] I am submitting a bug report for existing functionality that does not work as intended
- [ ] I have read https://github.com/signalapp/Signal-Android/wiki/Submitting-useful-bug-reports
- [ ] This isn't a feature request or a discussion topic
----------------------------------------

View File

@@ -1,19 +1,18 @@
<!-- You can remove this first section if you have contributed before -->
### First time contributor checklist
<!-- replace the empty checkboxes [ ] below with checked ones [x] accordingly -->
- [ ] I have read [how to contribute](https://github.com/WhisperSystems/Signal-Android/blob/master/CONTRIBUTING.md) to this project
- [ ] I have signed the [Contributor Licence Agreement](https://whispersystems.org/cla/)
- [ ] I have read [how to contribute](https://github.com/signalapp/Signal-Android/blob/master/CONTRIBUTING.md) to this project
- [ ] I have signed the [Contributor License Agreement](https://whispersystems.org/cla/)
### Contributor checklist
<!-- replace the empty checkboxes [ ] below with checked ones [x] accordingly -->
- [ ] I am following the [Code Style Guidelines](https://github.com/WhisperSystems/Signal-Android/wiki/Code-Style-Guidelines)
- [ ] I am following the [Code Style Guidelines](https://github.com/signalapp/Signal-Android/wiki/Code-Style-Guidelines)
- [ ] I have tested my contribution on these devices:
* Device A, Android X.Y.Z
* Device B, Android Z.Y
* Virtual device W, Android Y.Y.Z
- [ ] My contribution is fully baked and ready to be merged as is
- [ ] I ensure that all the open issues my contribution fixes are mentioned in the commit message of my first commit using the `Fixes #1234` [syntax](https://help.github.com/articles/closing-issues-via-commit-messages/)
- [ ] I have made the choice whether I want the [BitHub reward](https://github.com/WhisperSystems/Signal-Android/wiki/BitHub-Rewards) or not by omitting or adding the word `FREEBIE` in the commit message of my first commit
----------

30
.github/workflows/android.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Android CI
on:
pull_request:
push:
branches:
- 'master'
- '4.**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Install NDK
run: echo "y" | sudo /usr/local/lib/android/sdk/tools/bin/sdkmanager --install "ndk;20.0.5594570" --sdk_root=${ANDROID_SDK_ROOT}
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Build with Gradle
run: ./gradlew qa

4
.gitignore vendored
View File

@@ -1,4 +1,5 @@
.classpath
captures/
project.properties
.project
.settings
@@ -8,7 +9,6 @@ gen/
*.iml
out
tests
lint.xml
local.properties
ant.properties
.DS_Store
@@ -23,3 +23,5 @@ ffpr
test/androidTestEspresso/res/values/arrays.xml
obj/
jni/libspeex/.deps/
*.sh
pkcs11.password

View File

@@ -1,11 +0,0 @@
[main]
host = https://www.transifex.com
lang_map = fr_CA:fr-rCA,pt_BR:pt-rBR,pt_PT:pt,zh_CN:zh-rCN,zh_HK:zh-rHK,zh_TW:zh-rTW,da_DK:da-rDK,de_DE:de,tr_TR:tr,fr_FR:fr,es_ES:es,hu_HU:hu,sv_SE:sv-rSE,bg_BG:bg,el_GR:el,kn_IN:kn-rIN,cs_CZ:cs,sr:sr,he:iw,id:in
[signal-android.master]
file_filter = res/values-<lang>/strings.xml
source_file = res/values/strings.xml
source_lang = en
type = ANDROID

View File

@@ -1,517 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.thoughtcrime.securesms"
android:versionCode="214"
android:versionName="3.22.2">
<uses-sdk tools:overrideLibrary="com.amulyakhare.textdrawable,com.astuetz.pagerslidingtabstrip,pl.tajchert.waitingdots,com.h6ah4i.android.multiselectlistpreferencecompat"/>
<permission android:name="org.thoughtcrime.securesms.ACCESS_SECRETS"
android:label="Access to TextSecure Secrets"
android:protectionLevel="signature" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.bluetooth" android:required="false" />
<uses-feature android:name="android.hardware.location" android:required="false"/>
<uses-feature android:name="android.hardware.location.network" android:required="false"/>
<uses-feature android:name="android.hardware.location.gps" android:required="false"/>
<uses-feature android:name="android.hardware.microphone" android:required="false"/>
<uses-feature android:name="android.hardware.wifi" android:required="false"/>
<uses-feature android:name="android.hardware.portrait" android:required="false"/>
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
<uses-permission android:name="org.thoughtcrime.securesms.ACCESS_SECRETS"/>
<uses-permission android:name="android.permission.READ_PROFILE"/>
<uses-permission android:name="android.permission.WRITE_PROFILE"/>
<uses-permission android:name="android.permission.BROADCAST_WAP_PUSH"
tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_MMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- For sending location tiles in the future -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- So we can add a TextSecure 'Account' -->
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<!-- For conversation 'shortcuts' on the desktop -->
<uses-permission android:name="android.permission.INSTALL_SHORTCUT"/>
<!-- For sending/receiving events -->
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<!-- For fixing MMS -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- Set image as wallpaper -->
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
<!-- Permissions from RedPhone -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.CALL_PRIVILEGED" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.RAISED_THREAD_PRIORITY" />
<uses-permission android:name="android.permission.READ_CALL_STATE"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
<permission android:name="org.thoughtcrime.securesms.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="org.thoughtcrime.securesms.permission.C2D_MESSAGE" />
<application android:name=".ApplicationContext"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:supportsRtl="true"
tools:replace="android:allowBackup"
android:allowBackup="false"
android:theme="@style/TextSecure.LightTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCSx9xea86GwDKGznCAULE9Y5a8b-TfN9U"/>
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data android:name="org.thoughtcrime.securesms.mms.TextSecureGlideModule"
android:value="GlideModule" />
<activity android:name="org.thoughtcrime.redphone.RedPhone"
android:excludeFromRecents="true"
android:screenOrientation="portrait"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|screenSize|fontScale"
android:launchMode="singleTask">
</activity>
<activity android:name=".CountrySelectionActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".ImportExportActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".InviteActivity"
android:theme="@style/TextSecure.HighlightTheme"
android:windowSoftInputMode="stateHidden"
android:parentActivityName=".ConversationListActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.thoughtcrime.securesms.ConversationListActivity" />
</activity>
<activity android:name=".PromptMmsActivity"
android:label="Configure MMS Settings"
android:windowSoftInputMode="stateUnchanged"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".DeviceProvisioningActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tsdevice"/>
</intent-filter>
</activity>
<activity android:name=".preferences.MmsPreferencesActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".ShareActivity"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:noHistory="true"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="audio/*" />
<data android:mimeType="image/*" />
<data android:mimeType="text/plain" />
<data android:mimeType="video/*" />
</intent-filter>
</activity>
<activity android:name=".ConversationListActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:exported="true" />
<activity-alias android:name=".RoutingActivity"
android:targetActivity=".ConversationListActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.MULTIWINDOW_LAUNCHER" />
</intent-filter>
<meta-data android:name="com.sec.minimode.icon.portrait.normal"
android:resource="@drawable/icon" />
<meta-data android:name="com.sec.minimode.icon.landscape.normal"
android:resource="@drawable/icon" />
</activity-alias>
<activity android:name=".ConversationListArchiveActivity"
android:label="@string/AndroidManifest_archived_conversations"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:parentActivityName=".ConversationListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.thoughtcrime.securesms.ConversationListActivity" />
</activity>
<activity android:name=".ConversationActivity"
android:windowSoftInputMode="stateUnchanged"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:parentActivityName=".ConversationListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.thoughtcrime.securesms.ConversationListActivity" />
</activity>
<activity android:name=".ConversationPopupActivity"
android:windowSoftInputMode="stateVisible"
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true"
android:theme="@style/TextSecure.LightTheme.Popup"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize" />
<activity android:name=".MessageDetailsActivity"
android:label="@string/AndroidManifest__message_details"
android:windowSoftInputMode="stateHidden"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".GroupCreateActivity"
android:windowSoftInputMode="stateVisible"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".DatabaseMigrationActivity"
android:theme="@style/NoAnimation.Theme.AppCompat.Light.DarkActionBar"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".DatabaseUpgradeActivity"
android:theme="@style/NoAnimation.Theme.AppCompat.Light.DarkActionBar"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".ExperienceUpgradeActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".PassphraseCreateActivity"
android:label="@string/AndroidManifest__create_passphrase"
android:windowSoftInputMode="stateUnchanged"
android:theme="@style/TextSecure.LightIntroTheme"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".PassphrasePromptActivity"
android:label="@string/AndroidManifest__enter_passphrase"
android:launchMode="singleTask"
android:theme="@style/TextSecure.LightIntroTheme"
android:windowSoftInputMode="stateAlwaysVisible"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".NewConversationActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:windowSoftInputMode="stateAlwaysVisible"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".PushContactSelectionActivity"
android:label="@string/AndroidManifest__select_contacts"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".giph.ui.GiphyActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".PassphraseChangeActivity"
android:label="@string/AndroidManifest__change_passphrase"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".VerifyIdentityActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".ApplicationPreferencesActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".RegistrationActivity"
android:windowSoftInputMode="stateUnchanged"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".RegistrationProgressActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".DeviceActivity"
android:label="@string/AndroidManifest__linked_devices"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".LogSubmitActivity"
android:label="@string/AndroidManifest__log_submit"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".MediaPreviewActivity"
android:label="@string/AndroidManifest__media_preview"
android:windowSoftInputMode="stateHidden"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".MediaOverviewActivity"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".DummyActivity"
android:theme="@android:style/Theme.NoDisplay"
android:enabled="true"
android:allowTaskReparenting="true"
android:noHistory="true"
android:excludeFromRecents="true"
android:alwaysRetainTaskState="false"
android:stateNotNeeded="true"
android:clearTaskOnLaunch="true"
android:finishOnTaskLaunch="true" />
<activity android:name=".PlayServicesProblemActivity"
android:theme="@style/TextSecure.DialogActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".SmsSendtoActivity">
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact" />
</intent-filter>
</activity>
<activity android:name="org.thoughtcrime.redphone.RedPhoneShare"
android:excludeFromRecents="true"
android:theme="@style/NoAnimation.Theme.BlackScreen"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.call" />
</intent-filter>
</activity>
<activity android:name=".RecipientPreferenceActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".BlockedContactsActivity"
android:theme="@style/TextSecure.LightTheme"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name="com.soundcloud.android.crop.CropImageActivity" />
<service android:enabled="true" android:name="org.thoughtcrime.redphone.RedPhoneService"/>
<service android:enabled="true" android:name=".service.ApplicationMigrationService"/>
<service android:enabled="true" android:name=".service.KeyCachingService"/>
<service android:enabled="true" android:name=".service.RegistrationService"/>
<service android:enabled="true" android:name=".service.MessageRetrievalService"/>
<service android:name=".service.QuickResponseService"
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</service>
<service android:name=".service.AccountAuthenticatorService" android:exported="true">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator" />
</service>
<service android:name=".service.ContactsSyncAdapterService" android:exported="true">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data android:name="android.content.SyncAdapter" android:resource="@xml/syncadapter" />
<meta-data android:name="android.provider.CONTACTS_STRUCTURE" android:resource="@xml/contactsformat" />
</service>
<receiver android:name=".gcm.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="org.thoughtcrime.securesms" />
</intent-filter>
</receiver>
<receiver android:name=".service.SmsListener"
android:permission="android.permission.BROADCAST_SMS"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1001">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.SMS_DELIVER"/>
</intent-filter>
</receiver>
<receiver android:name=".service.SmsDeliveryListener"
android:exported="true">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.services.MESSAGE_SENT"/>
</intent-filter>
</receiver>
<receiver android:name=".service.MmsListener"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BROADCAST_WAP_PUSH">
<intent-filter android:priority="1001">
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED"/>
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER"/>
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
</receiver>
<receiver android:name=".notifications.MarkReadReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.notifications.CLEAR"/>
</intent-filter>
</receiver>
<receiver android:name=".notifications.WearReplyReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.notifications.WEAR_REPLY"/>
</intent-filter>
</receiver>
<provider android:name=".providers.PartProvider"
android:grantUriPermissions="true"
android:exported="false"
android:authorities="org.thoughtcrime.provider.securesms" />
<provider android:name=".providers.MmsBodyProvider"
android:grantUriPermissions="true"
android:exported="false"
android:authorities="org.thoughtcrime.provider.securesms.mms" />
<receiver android:name=".service.RegistrationNotifier"
android:exported="false">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.REGISTRATION_EVENT" />
</intent-filter>
</receiver>
<receiver android:name=".service.DirectoryRefreshListener">
<intent-filter>
<action android:name="org.whispersystems.whisperpush.DIRECTORY_REFRESH"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".notifications.MessageNotifier$ReminderReceiver">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.MessageNotifier.REMINDER_ACTION"/>
</intent-filter>
</receiver>
<receiver android:name=".notifications.MessageNotifier$DeleteReceiver">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.MessageNotifier.DELETE_REMINDER_ACTION"/>
</intent-filter>
</receiver>
<receiver android:name=".ExperienceUpgradeActivity$AppUpgradeReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<data android:scheme="package" />
</intent-filter>
</receiver>
<receiver
android:name=".service.PanicResponderListener"
android:exported="true">
<intent-filter>
<action android:name="info.guardianproject.panic.action.TRIGGER" />
</intent-filter>
</receiver>
<uses-library android:name="com.sec.android.app.multiwindow" android:required="false"/>
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_W" android:value="632.0dip" />
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_H" android:value="598.0dip" />
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_W" android:value="632.0dip" />
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_H" android:value="598.0dip" />
</application>
</manifest>

View File

@@ -1,72 +0,0 @@
Building Signal
===============
Basics
------
Signal uses [Gradle](http://gradle.org) to build the project and to maintain
dependencies. However, you needn't install it yourself; the
"gradle wrapper" `gradlew`, mentioned below, will do that for you.
Building Signal
---------------
The following steps should help you (re)build Signal from the command line.
1. Checkout the Signal-Android project source with the command:
git clone https://github.com/WhisperSystems/Signal-Android.git
2. Make sure you have the [Android SDK](https://developer.android.com/sdk/index.html) installed.
3. Ensure that the following packages are installed from the Android SDK manager:
* Android SDK Build Tools
* SDK Platform (API level 22)
* Android Support Repository
* Google Repository
4. Create a local.properties file at the root of your source checkout and add an sdk.dir entry to it. For example:
sdk.dir=/Application/android-sdk-macosx
5. Execute Gradle:
./gradlew build
Visual assets
----------------------
Source assets tend to be large binary blobs, which are best stored outside of git repositories. We host ours in a [Pixelapse repository](https://www.pixelapse.com/openwhispersystems/projects/signal-android/). Some source files are SVGs that can be auto-colored and sized using a tool like [android-res-utils](https://github.com/sebkur/android-res-utils).
Sample command for generating our audio placeholder image:
```bash
pngs_from_svg.py ic_audio.svg /path/to/Signal/res/ 150 --color #000 --opacity 0.54 --suffix _light
pngs_from_svg.py ic_audio.svg /path/to/Signal/res/ 150 --color #fff --opacity 1.00 --suffix _light
```
Setting up a development environment
------------------------------------
[Android Studio](https://developer.android.com/sdk/installing/studio.html) is the recommended development environment.
1. Install Android Studio.
2. Open Android Studio. On a new installation, the Quickstart panel will appear. If you have open projects, close them using "File > Close Project" to see the Quickstart panel.
3. From the Quickstart panel, choose "Configure" then "SDK Manager".
4. In the SDK Tools tab of the SDK Manager, make sure that the "Android Support Repository" is installed, and that the latest "Android SDK build-tools" are installed. Click "OK" to return to the Quickstart panel.
5. From the Quickstart panel, choose "Checkout from Version Control" then "git".
6. Paste the URL for the Signal-Android project when prompted (https://github.com/WhisperSystems/Signal-Android.git).
7. Android studio should detect the presence of a project file and ask you whether to open it. Click "yes".
9. Default config options should be good enough.
9. Project initialisation and build should proceed.
Contributing code
-----------------
Code contributions should be sent via github as pull requests, from feature branches [as explained here](https://help.github.com/articles/using-pull-requests).
Mailing list
------------
Development discussion happens on the whispersystems mailing list.
[To join](https://lists.riseup.net/www/info/whispersystems)
Send emails to whispersystems@lists.riseup.net

View File

@@ -1,6 +1,6 @@
# Contributing to Signal Android
Thank you for deciding to help this project! If you have contributed to other open source projects before please note that some conventions here might be a bit different than what you have been used to. Reading this document will save you, other contributors and the developers time.
Thank you for supporting Signal and looking for ways to help. Please note that some conventions here might be a bit different than what you are used to, even if you have contributed to other open source projects before. Reading this document will help you save time and work effectively with the developers and other contributors.
## Development Ideology
@@ -9,80 +9,81 @@ Truths which we believe to be self-evident:
1. **The answer is not more options.** If you feel compelled to add a preference that's exposed to the user, it's very possible you've made a wrong turn somewhere.
1. **The user doesn't know what a key is.** We need to minimize the points at which a user is exposed to this sort of terminology as extremely as possible.
1. **There are no power users.** The idea that some users "understand" concepts better than others has proven to be, for the most part, false. If anything, "power users" are more dangerous than the rest, and we should avoid exposing dangerous functionality to them.
1. **There are no power users.** The idea that some users "understand" concepts better than others has proven to be, for the most part, false. If anything, "power users" are more dangerous than the rest, and we should avoid exposing dangerous functionality to them.
1. **If it's "like PGP," it's wrong.** PGP is our guide for what not to do.
1. **It's an asynchronous world.** Be wary of anything that is anti-asynchronous: ACKs, protocol confirmations, or any protocol-level "advisory" message.
1. **There is no such thing as time.** Protocol ideas that require synchronized clocks are doomed to failure.
1. **There is no such thing as time.** Protocol ideas that require synchronized clocks are doomed to failure.
## Translations
Please do not submit issues or pull requests for translation fixes. Anyone can update the translations in [Transifex](https://www.transifex.com/projects/p/signal-android/). Please submit your corrections there.
Thanks to a dedicated community of volunteer translators, Signal is now available in more than one hundred languages. We use Transifex to manage our translation efforts, not GitHub. Any suggestions, corrections, or new translations should be submitted to the [Signal localization project for Android](https://www.transifex.com/signalapp/signal-android/).
## Issues
### Useful bug reports
1. Please search both open and closed issues first to make sure your issue is not a duplicate.
1. Read the [Submitting useful bug reports guide](https://github.com/WhisperSystems/Signal-Android/wiki/Submitting-useful-bug-reports) before posting a bug.
1. Please search both open and closed issues to make sure your bug report is not a duplicate.
1. Read the [guide to submitting useful bug reports](https://github.com/signalapp/Signal-Android/wiki/Submitting-useful-bug-reports) before posting a bug.
### Issue tracker is for bugs
The main purpose of this issue tracker is to track bugs for the Android client. Relevant, concise and to the point comments that help to solve the issue are very welcome.
### The issue tracker is for bugs, not feature requests
The GitHub issue tracker is not used for feature requests, but new ideas can be submitted and discussed on the [community forum](https://community.signalusers.org/c/feature-requests). The purpose of this issue tracker is to track bugs in the Android client. Bug reports should only be submitted for existing functionality that does not work as intended. Comments that are relevant and concise will help the developers solve issues more quickly.
##### Send support questions to support
Please do **not** ask support questions at the issue tracker. We want to help you using Signal and we have created our support system just for that. You can reach support by sending email to support@whispersystems.org or by going to our [Support Center](http://support.whispersystems.org). You can also search for existing troubleshooting articles at the [Support Center](http://support.whispersystems.org).
### Send support questions to support
You can reach support by sending an email to support@signal.org or by visiting the [Signal Support Center](https://support.signal.org/) where you can also search for existing troubleshooting articles and find answers to frequently asked questions. Please do not post support questions on the GitHub issue tracker.
##### Not a discussion forum
Please do **not** use this issue tracker as a discussion forum. Discussion related to the bug in question should of course go to the issue itself. However other discussion should take place at the [community forum](https://whispersystems.discoursehosting.net). You can use that forum to discuss any Signal related topics or to just hang out with your fellow users.
### GitHub is not a generic discussion forum
Conversations about open bug reports belong here. However, all other discussions should take place on the [community forum](https://community.signalusers.org). You can use the community forum to discuss anything that is related to Signal or to hang out with your fellow users in the "Off Topic" category.
### Don't bump issues
Every time someone comments on an issue, GitHub sends email to [everyone who is watching](https://github.com/WhisperSystems/Signal-Android/watchers) the repository (currently around 500 people). Thus bumping issues with :+1:s, _me toos_ or asking for updates just generate unnecessary email notifications. Moreover bumping an issue does not help solving it. Please be respectful to everyone's time and try to only comment when you have relevant new information to add.
Every time someone comments on an issue, GitHub sends an email to [hundreds of people](https://github.com/signalapp/Signal-Android/watchers). Bumping issues with a "+1" (or asking for updates) generates a lot of unnecessary email notifications and does not help anyone solve the issue any faster. Please be respectful of everyone's time and only comment when you have new information to add.
### Open issues
#### If it's open it's tracked
Have you followed all the points in the [Submitting useful bug reports guide](https://github.com/WhisperSystems/Signal-Android/wiki/Submitting-useful-bug-reports) but nobody has commented on your issue? Is there no milestone or person assigned to it? Don't worry, the developers read every issue and if it's open it means it's tracked and taken into account. It might just take time as other issues have higher priorities. And remember that this is an open source project: Anyone is encouraged to take an active role in fixing open issues.
#### If it's open, it's tracked
The developers read every issue, but high-priority bugs or features can take precedence over others. Signal is an open source project, and everyone is encouraged to play an active role in diagnosing and fixing open issues.
### Closed issues
#### "My issue was closed without giving a reason!"
Please understand that writing detailed explanations every time for every issue someone comes up with takes time. Sometimes a reason has been posted earlier to another related issue which you can search for. It's also possible that your issue was not in line with the guidelines of the project (see especially the [Development Ideology](https://github.com/WhisperSystems/Signal-Android/blob/master/CONTRIBUTING.md#development-ideology)). Or it was just simply decided that the issue is not something that Signal should do at this time.
Although we do our best, writing detailed explanations for every issue can be time consuming, and the topic also might have been covered previously in other related issues.
## Pull requests
### Sign the Contributor Licence Agreement (CLA)
You need to sign our CLA before your pull request can be merged. You can sign it at: https://whispersystems.org/cla/
### Smaller is better
Big changes are significantly less likely to be accepted. Large features often require protocol modifications and necessitate a staged rollout process that is coordinated across millions of users on multiple platforms (Android, iOS, and Desktop).
Try not to take on too much at once. As a first-time contributor, we recommend starting with small and simple PRs in order to become familiar with the codebase. Most of the work should go into discovering which three lines need to change rather than writing the code.
### Sign the Contributor License Agreement (CLA)
You will need to [sign our CLA](https://signal.org/cla/) before your pull request can be merged.
### Follow the Code Style Guidelines
Before submitting a pull request please check that your code adheres to the [Code style Guidelines](https://github.com/WhisperSystems/Signal-Android/wiki/Code-Style-Guidelines).
Ensure that your code adheres to the [Code Style Guidelines](https://github.com/signalapp/Signal-Android/wiki/Code-Style-Guidelines) before submitting a pull request.
### Submit only complete PRs and test them
Please do not submit pull requests that are still a work in progress. Pull requests should be ready for a merge when you submit them. Also please do not submit pull requests that you have not tested.
### Smaller is better
Please do not try to change too much at once. Big changes are less likely to be merged. If you are a first time contributor start with small and simple PRs to get to know the codebase.
### Submit finished and well-tested pull requests
Please do not submit pull requests that are still a work in progress. Pull requests should be thoroughly tested and ready to merge before they are submitted.
### Merging can sometimes take a while
If your pull request follows all the advice above but still has not been merged it usually means the developers haven't simply had the time to review it yet. We understand that this might feel frustrating. We are sorry!
### Bithub
Accepted pull requests will be rewarded with Bitcoins! After your pull request has been merged you will automatically receive an email to the address you have specified as your Git commit email. Follow the instructions in the email to claim your coins. If you wish to submit your contribution for free please add the word `FREEBIE` in your Git commit message. You may wish to explore some previously merged commits to see how it all works.
If your pull request follows all of the advice above but still has not been merged, this usually means that the developers haven't had time to review it yet. We understand that this might feel frustrating, and we apologize. The Signal team is still small, but [we are hiring](https://signal.org/workworkwork/).
## How can I contribute?
Any one can help by
- advising new people about the guidelines of this project
- redirecting support questions to support@whispersystems.org and the [support site](http://support.whispersystems.org)
- redirecting non-bug related discussions to the [community forum](https://whispersystems.discoursehosting.net)
- improving documentation at the [wiki](https://github.com/WhisperSystems/Signal-Android/wiki)
- [translating](https://www.transifex.com/projects/p/signal-android/)
- finding and marking duplicate issues
- trying to reproduce issues
- finding solutions to open issues and posting relevant findings as comments
- submitting pull requests
- testing other people's pull requests
- spreading the joy of Signal to your friends and family
- donating money to our [BitHub](https://www.coinbase.com/checkouts/51dac699e660a4d773216b5ad94d6a0b) or through the [Freedom of the Press Foundation's donation page](https://freedom.press/bundle/encryption-tools-journalists)
There are several other ways to get involved:
* Help new users learn about Signal.
* Redirect support questions to support@signal.org and the [Signal Support Center](https://support.signal.org/).
* Redirect non-bug discussions to the [community forum](https://community.signalusers.org).
* Improve documentation in the [wiki](https://github.com/signalapp/Signal-Android/wiki).
* Join the community of volunteer translators on Transifex:
* [Android](https://www.transifex.com/signalapp/signal-android/)
* [iOS](https://www.transifex.com/signalapp/signal-ios/)
* [Desktop](https://www.transifex.com/signalapp/signal-desktop/)
* Find and mark duplicate issues.
* Try to reproduce issues and help with troubleshooting.
* Discover solutions to open issues and post any relevant findings.
* Test other people's pull requests.
* Contribute to Signal via the [Freedom of the Press Foundation's donation page](https://freedom.press/crowdfunding/signal/).
* Share Signal with your friends and family.
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/WhisperSystems/Signal-Android?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
Signal is made for you. Thank you for your feedback and support.

View File

@@ -1,19 +1,18 @@
FROM ubuntu:14.04.3
FROM ubuntu:17.10
RUN dpkg --add-architecture i386 && \
apt-get update -y && \
apt-get install -y software-properties-common && \
add-apt-repository -y ppa:openjdk-r/ppa && \
apt-get update -y && \
apt-get install -y libc6:i386=2.19-0ubuntu6.7 libncurses5:i386=5.9+20140118-1ubuntu1 libstdc++6:i386=4.8.4-2ubuntu1~14.04.1 lib32z1=1:1.2.8.dfsg-1ubuntu1 wget openjdk-8-jdk=8u72-b15-1~trusty1 git unzip && \
apt-get install -y libc6:i386=2.26-0ubuntu2.1 libncurses5:i386=6.0+20160625-1ubuntu1 libstdc++6:i386=7.2.0-8ubuntu3.2 lib32z1=1:1.2.11.dfsg-0ubuntu2 wget openjdk-8-jdk=8u171-b11-0ubuntu0.17.10.1 git unzip opensc pcscd && \
rm -rf /var/lib/apt/lists/* && \
apt-get autoremove -y && \
apt-get clean
ENV ANDROID_SDK_FILENAME android-sdk_r24.4.1-linux.tgz
ENV ANDROID_SDK_URL https://dl.google.com/android/${ANDROID_SDK_FILENAME}
ENV ANDROID_API_LEVELS android-22
ENV ANDROID_BUILD_TOOLS_VERSION 23.0.2
ENV ANDROID_API_LEVELS android-28
ENV ANDROID_BUILD_TOOLS_VERSION 28.0.3
ENV ANDROID_HOME /usr/local/android-sdk-linux
ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
RUN cd /usr/local/ && \

View File

@@ -6,12 +6,12 @@ Signal uses your phone's data connection (WiFi/3G/4G) to communicate securely, o
Currently available on the Play store.
<a href="https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms&utm_source=global_co&utm_medium=prtnr&utm_content=Mar2515&utm_campaign=PartBadge&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1"><img alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" height=36px /></a>
<a href='https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' height='80px'/></a>
## Contributing Bug reports
We use GitHub for bug tracking. Please search the existing issues for your bug and create a new one if the issue is not yet tracked!
https://github.com/WhisperSystems/Signal-Android/issues
https://github.com/signalapp/Signal-Android/issues
## Joining the Beta
Want to live life on the bleeding edge and help out with testing?
@@ -27,35 +27,25 @@ Interested in helping to translate Signal? Contribute here:
https://www.transifex.com/projects/p/signal-android/
## Contributing Code
Instructions on how to setup your development environment and build Signal can be found in [BUILDING.md](https://github.com/WhisperSystems/Signal-Android/blob/master/BUILDING.md).
If you're new to the Signal codebase, we recommend going through our issues and picking out a simple bug to fix (check the "easy" label in our issues) in order to get yourself familiar. Also please have a look at the [CONTRIBUTING.md](https://github.com/WhisperSystems/Signal-Android/blob/master/CONTRIBUTING.md), that might answer some of your questions.
If you're new to the Signal codebase, we recommend going through our issues and picking out a simple bug to fix (check the "easy" label in our issues) in order to get yourself familiar. Also please have a look at the [CONTRIBUTING.md](https://github.com/signalapp/Signal-Android/blob/master/CONTRIBUTING.md), that might answer some of your questions.
For larger changes and feature ideas, we ask that you propose it on the [unofficial Community Forum](https://whispersystems.discoursehosting.net) for a high-level discussion with the wider community before implementation.
This repository is set up with [BitHub](https://whispersystems.org/blog/bithub/), so you can make money for committing to Signal. The current BitHub price for an accepted pull request is:
[![Current BitHub Price](https://bithub.herokuapp.com/v1/status/payment/commit/)](https://whispersystems.org/blog/bithub/)
For larger changes and feature ideas, we ask that you propose it on the [unofficial Community Forum](https://community.signalusers.org) for a high-level discussion with the wider community before implementation.
## Contributing Ideas
Have something you want to say about Open Whisper Systems projects or want to be part of the conversation? Get involved in the [community forum](https://whispersystems.discoursehosting.net).
## Contributing Funds
[![Donate](https://cloud.githubusercontent.com/assets/3121306/11278543/d46e03d0-8eeb-11e5-9691-0da1bf643192.png)](https://www.coinbase.com/checkouts/51dac699e660a4d773216b5ad94d6a0b)
You can add funds to BitHub to directly help further development efforts.
Have something you want to say about Open Whisper Systems projects or want to be part of the conversation? Get involved in the [community forum](https://community.signalusers.org).
Help
====
## Support
For troubleshooting and questions, please visit our support center!
http://support.whispersystems.org/
https://support.signal.org/
## Documentation
Looking for documentation? Check out the wiki!
https://github.com/WhisperSystems/Signal-Android/wiki
https://github.com/signalapp/Signal-Android/wiki
# Legal things
## Cryptography Notice
@@ -69,8 +59,8 @@ The form and manner of this distribution makes it eligible for export under the
## License
Copyright 2011 Whisper Systems
Copyright 2013-2016 Open Whisper Systems
Copyright 2013-2020 Signal
Licensed under the GPLv3: http://www.gnu.org/licenses/gpl-3.0.html
Google Play and the Google Play logo are trademarks of Google Inc.

287
ReproducibleBuilds.md Normal file
View File

@@ -0,0 +1,287 @@
# Reproducible Builds
## TL;DR
You can just use these [instructions](https://signal.org/blog/reproducible-android/) from the official announcement at Open Whisper Systems's blog:
```
# Clone the Signal Android source repository
$ git clone https://github.com/signalapp/Signal-Android.git && cd Signal-Android
# Check out the release tag for the version you'd like to compare
$ git checkout v[the version number]
# Build using the Docker environment
$ docker run --rm -v $(pwd):/project -w /project whispersystems/signal-android:1.3 ./gradlew clean assembleRelease
# Verify the APKs
$ python3 apkdiff/apkdiff.py build/outputs/apks/project-release-unsigned.apk path/to/SignalFromPlay.apk
```
Note that the instructions above use a pre-built Signal Docker image from [Docker Hub](https://hub.docker.com/u/whispersystems/). If you wish to compile the image yourself, continue reading the longer version below.
***
## Introduction
Since version 3.15.0 Signal for Android has supported reproducible builds. This is achieved by replicating the build environment as a Docker image. You'll need to build the image, run a container instance of it, compile Signal inside the container and finally compare the resulted APK to the APK that is distributed in the Google Play Store.
The command line parts in this guide are written for Linux but with some little modifications you can adapt them to macOS (OS X) and Windows. In the following sections we will use `3.15.2` as an example Signal version. You'll just need to replace all occurrences of `3.15.2` with the version number you are about to verify.
## Setting up directories
First let's create a new directory for this whole reproducible builds project. In your home folder (`~`), create a new directory called `reproducible-signal`.
```
user@host:$ mkdir ~/reproducible-signal
```
Next create another directory inside `reproducible-signal` called `apk-from-google-play-store`.
```
user@host:$ mkdir ~/reproducible-signal/apk-from-google-play-store
```
We will use this directory to share APKs between the host OS and the Docker container.
Finally create one more directory inside `reproducible-signal` called `image-build-context`.
```
user@host:$ mkdir ~/reproducible-signal/image-build-context
```
This directory will be used later to build our Docker image.
## Getting the Google Play Store version of Signal APK
To compare the APKs we of course need a version of Signal from the Google Play Store.
First make sure that the Signal version you want to verify is installed on your Android device. You'll need `adb` for this part.
Plug your device to your computer and run this command to pull the APK from the device:
```
user@host:$ adb pull $(adb shell pm path org.thoughtcrime.securesms | grep /base.apk | awk -F':' '{print $2}') ~/reproducible-signal/apk-from-google-play-store/Signal-$(adb shell dumpsys package org.thoughtcrime.securesms | grep versionName | awk -F'=' '{print $2}').apk
```
This will pull a file into `~/reproducible-signal/apk-from-google-play-store/` with the name `Signal-<version>.apk`
Alternatively, you can do this step-by-step:
```
user@host:$ adb shell pm path org.thoughtcrime.securesms
```
This will output something like:
```
package:/data/app/org.thoughtcrime.securesms-aWRzcGlzcG9wZA==/base.apk
```
The output will tell you where the Signal APK is located in your device. (In this example the path is `/data/app/org.thoughtcrime.securesms-aWRzcGlzcG9wZA==/base.apk`)
Now using this information, pull the APK from your device to the `reproducible-signal/apk-from-google-play-store` directory you created before:
```
user@host:$ adb pull \
/data/app/org.thoughtcrime.securesms-aWRzcGlzcG9wZA==/base.apk \
~/reproducible-signal/apk-from-google-play-store/Signal-3.15.2.apk
```
We will use this APK in the final part when we compare it with the self-built APK from GitHub.
## Identifying the ABI
Since v4.37.0, the APKs have been split by ABI, the CPU architecture of the target device. Google play will serve the correct one to you for your device.
To identify which ABIs the google play APK supports, we can look inside the APK, which is just a zip file:
```
user@host:$ unzip -l ~/reproducible-signal/apk-from-google-play-store/Signal-*.apk | grep lib/
```
Example:
```
1214348 00-00-1980 00:00 lib/armeabi-v7a/libconscrypt_jni.so
151980 00-00-1980 00:00 lib/armeabi-v7a/libcurve25519.so
4164320 00-00-1980 00:00 lib/armeabi-v7a/libjingle_peerconnection_so.so
13948 00-00-1980 00:00 lib/armeabi-v7a/libnative-utils.so
2357812 00-00-1980 00:00 lib/armeabi-v7a/libsqlcipher.so
```
As there is just one sub directory of `lib/` called `armeabi-v7a`, that is your ABI. Make a note of that for later. If you see more than one subdirectory of `lib/`:
```
1214348 00-00-1980 00:00 lib/armeabi-v7a/libconscrypt_jni.so
151980 00-00-1980 00:00 lib/armeabi-v7a/libcurve25519.so
4164320 00-00-1980 00:00 lib/armeabi-v7a/libjingle_peerconnection_so.so
13948 00-00-1980 00:00 lib/armeabi-v7a/libnative-utils.so
2357812 00-00-1980 00:00 lib/armeabi-v7a/libsqlcipher.so
2111376 00-00-1980 00:00 lib/x86/libconscrypt_jni.so
201056 00-00-1980 00:00 lib/x86/libcurve25519.so
7303888 00-00-1980 00:00 lib/x86/libjingle_peerconnection_so.so
5596 00-00-1980 00:00 lib/x86/libnative-utils.so
3977636 00-00-1980 00:00 lib/x86/libsqlcipher.so
```
Then that means you have the `universal` APK.
## Installing Docker
Install Docker by following the instructions for your platform at https://docs.docker.com/engine/installation/
Your platform might also have its own preferred way of installing Docker. E.g. Ubuntu has its own Docker package (`docker.io`) if you do not want to follow Docker's instructions.
In the following sections we will assume that your Docker installation works without issues. So after installing, please make sure that everything is running smoothly before continuing.
## Building a Docker image for Signal
#### Grabbing the `Dockerfile`
First you will need the `Dockerfile` for Signal Android. It comes bundled with Signal's source code. The `Dockerfile` contains instructions on how to automatically build a Docker image for Signal. You just need to run it and it builds itself.
Download the `Dockerfile` to the `image-build-context` directory.
```
user@host:$ wget -O ~/reproducible-signal/image-build-context/Dockerfile_v3.15.2 \
https://raw.githubusercontent.com/signalapp/Signal-Android/v3.15.2/Dockerfile
```
Note that the `Dockerfile` is specific to the Signal version you want to compare to. Again you have to adjust the URL above to match the right version. (Though sometimes the file might not be up to date, see the [Troubleshooting section](#troubleshooting))
#### Building the image
Now we have everything we need to build the Docker image for Signal. Go to the `image-build-context` directory:
```
user@host:$ cd ~/reproducible-signal/image-build-context
```
And list the contents.
```
user@host:$ ls
```
The output should look like this:
```
Dockerfile_v3.15.2
```
Now in this directory build the image using `Dockerfile_v3.15.2`:
```
user@host:$ docker build --file Dockerfile_v3.15.2 --tag signal-android .
```
(Note that there is a dot at the end of that command!)
Wait a few years for the build to finish... :construction_worker:
(Depending on your computer and network connection, this may take several minutes.)
:calendar: :sleeping:
After the build has finished, you may wish to list all your Docker images to see that it's really there:
```
user@host:$ docker images
```
Output should look something like this:
```
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
signal-android latest c6b84450b896 46 seconds ago 2.94 GB
ubuntu 14.04.3 8693db7e8a00 9 weeks ago 187.9 MB
```
## Compiling Signal inside a container
Next we will run a container of the image we just built, grab Signal's source code and compile Signal.
First go to the `reproducible-signal` directory:
```
user@host:$ cd ~/reproducible-signal/
```
To run a new ephemeral container with an interactive terminal session execute the following long command:
```
user@host:$ docker run \
--name signal \
--rm \
--interactive \
--tty \
--volume $(pwd)/apk-from-google-play-store:/signal-build/apk-from-google-play-store \
--workdir /signal-build \
signal-android
```
Now you are inside the container.
Grab Signal's source code from GitHub and go to the repository directory:
```
root@container:# git clone https://github.com/signalapp/Signal-Android.git
root@container:# cd Signal-Android
```
Before you can compile, you **must** ensure that you are at the right commit. In other words you **must** checkout the version you wish to verify (here we are verifying 3.15.2):
```
root@container:# git checkout --quiet v3.15.2
```
Now you may compile the release APK by running:
```
root@container:# ./gradlew clean assemblePlayRelease --exclude-task signProductionPlayRelease
```
This will take a few minutes :sleeping:
#### Checking if the APKs match
After the build has completed successfully we can finally compare if the APKs match. For the comparison we need of course the Google Play Store version of Signal APK which you copied to the `apk-from-google-play-store` directory in the beginning of this guide. Because we used that directory as a `--volume` parameter for our container, we can see all the files in that directory within our container.
So now we can compare the APKs using the `apkdiff.py` tool.
The above build step produced several APKs, one for each supported ABI and one universal one. You will need to determine the correct APK to compare.
Currently, the most common ABI is `armeabi-v7a`. Other options at this time include `x86` and `universal`. In the future it will also include 64-bit options, such as `x86_64` and `arm64-v8a`.
See [Identifying the ABI](#identifying-the-abi) above if you don't know the ABI of your play store APK.
Once you have determined the ABI, add an `abi` environment variable. For example, suppose we determine that `armeabi-v7a` is the ABI google play has served:
```
root@container:# export abi=armeabi-v7a
```
And the diff script to compare:
```
root@container:# python3 apkdiff/apkdiff.py \
build/outputs/apk/play/release/*play-$abi-release-unsigned*.apk \
../apk-from-google-play-store/Signal-3.15.2.apk
```
Output:
```
APKs match!
```
If you get `APKs match!`, you have successfully verified that the Google Play release matches with your own self-built version of Signal. Congratulations! Your APKs are a match made in heaven! :sparkles:
If you get `APKs don't match!`, you did something wrong in the previous steps. See the [Troubleshooting section](#troubleshooting) for more info.
## Comparing next time
If the build environment (i.e. `Dockerfile`) has not changed, you don't need to build the image again to verify a newer APK. You can just [run the container again](#compiling-signal-inside-a-container).
## Troubleshooting
If you cannot get things to work, please do not open an issue or comment on an existing issue at GitHub. Instead, ask for help at https://community.signalusers.org/c/development
Some common issues why things may not work:
- some pinned packages in the `Dockerfile` are not available anymore and building of the Docker image fails
- the Android packages in the Docker image are outdated and compiling Signal fails
- you built the Docker image with a wrong version of the `Dockerfile`
- you didn't checkout the correct Signal version tag with Git before compiling
- the ABI you selected is not the correct ABI, particularly if you see an error along the lines of `Sorted manifests don't match, lib/x86/libcurve25519.so vs lib/armeabi-v7a/libcurve25519.so`.
- this guide is outdated
- you are in a dream
- if you run into this issue: https://issuetracker.google.com/issues/110237303 try to add `resources.arsc` to the list of ignored files and compare again

View File

@@ -1,20 +1,21 @@
#! /usr/bin/env python
#! /usr/bin/env python3
import sys
from zipfile import ZipFile
class ApkDiff:
IGNORE_FILES = ["META-INF/CERT.RSA", "META-INF/CERT.SF", "META-INF/MANIFEST.MF"]
# resources.arsc is ignored due to https://issuetracker.google.com/issues/110237303
# May be fixed in Android Gradle Plugin 3.4
IGNORE_FILES = ["META-INF/MANIFEST.MF", "META-INF/SIGNAL_S.RSA", "META-INF/SIGNAL_S.SF", "resources.arsc"]
def compare(self, sourceApk, destinationApk):
sourceZip = ZipFile(sourceApk, 'r')
destinationZip = ZipFile(destinationApk, 'r')
if self.compareManifests(sourceZip, destinationZip) and self.compareEntries(sourceZip, destinationZip) == True:
print "APKs match!"
print("APKs match!")
else:
print "APKs don't match!"
print("APKs don't match!")
def compareManifests(self, sourceZip, destinationZip):
sourceEntrySortedList = sorted(sourceZip.namelist())
@@ -23,23 +24,23 @@ class ApkDiff:
for ignoreFile in self.IGNORE_FILES:
while ignoreFile in sourceEntrySortedList: sourceEntrySortedList.remove(ignoreFile)
while ignoreFile in destinationEntrySortedList: destinationEntrySortedList.remove(ignoreFile)
if len(sourceEntrySortedList) != len(destinationEntrySortedList):
print "Manifest lengths differ!"
print("Manifest lengths differ!")
for (sourceEntryName, destinationEntryName) in zip(sourceEntrySortedList, destinationEntrySortedList):
if sourceEntryName != destinationEntryName:
print "Sorted manifests don't match, %s vs %s" % (sourceEntryName, destinationEntryName)
print("Sorted manifests don't match, %s vs %s" % (sourceEntryName, destinationEntryName))
return False
return True
def compareEntries(self, sourceZip, destinationZip):
sourceInfoList = filter(lambda sourceInfo: sourceInfo.filename not in self.IGNORE_FILES, sourceZip.infolist())
destinationInfoList = filter(lambda destinationInfo: destinationInfo.filename not in self.IGNORE_FILES, destinationZip.infolist())
sourceInfoList = list(filter(lambda sourceInfo: sourceInfo.filename not in self.IGNORE_FILES, sourceZip.infolist()))
destinationInfoList = list(filter(lambda destinationInfo: destinationInfo.filename not in self.IGNORE_FILES, destinationZip.infolist()))
if len(sourceInfoList) != len(destinationInfoList):
print "APK info lists of different length!"
print("APK info lists of different length!")
return False
for sourceEntryInfo in sourceInfoList:
@@ -49,19 +50,19 @@ class ApkDiff:
destinationEntry = destinationZip.open(destinationEntryInfo, 'r')
if self.compareFiles(sourceEntry, destinationEntry) != True:
print "APK entry %s does not match %s!" % (sourceEntryInfo.filename, destinationEntryInfo.filename)
print("APK entry %s does not match %s!" % (sourceEntryInfo.filename, destinationEntryInfo.filename))
return False
destinationInfoList.remove(destinationEntryInfo)
break
return True
def compareFiles(self, sourceFile, destinationFile):
sourceChunk = sourceFile.read(1024)
destinationChunk = destinationFile.read(1024)
while sourceChunk != "" or destinationChunk != "":
while sourceChunk != b"" or destinationChunk != b"":
if sourceChunk != destinationChunk:
return False
@@ -72,7 +73,7 @@ class ApkDiff:
if __name__ == '__main__':
if len(sys.argv) != 3:
print "Usage: apkdiff <pathToFirstApk> <pathToSecondApk>"
print("Usage: apkdiff <pathToFirstApk> <pathToSecondApk>")
sys.exit(1)
ApkDiff().compare(sys.argv[1], sys.argv[2])

10
app/.tx/config Normal file
View File

@@ -0,0 +1,10 @@
[main]
host = https://www.transifex.com
lang_map = da_DK:da-rDK,fil:tl,he:iw,id:in,kn_IN:kn-rIN,pa_PK:pa-rPK,pt_BR:pt-rBR,pt_PT:pt,qu_EC:qu-rEC,sv_SE:sv-rSE,zh_CN:zh-rCN,zh_HK:zh-rHK,zh_TW:zh-rTW
[signal-android.master]
file_filter = src/main/res/values-<lang>/strings.xml
source_file = src/main/res/values/strings.xml
source_lang = en
type = ANDROID

457
app/build.gradle Normal file
View File

@@ -0,0 +1,457 @@
import org.signal.signing.ApkSignerUtil
import java.security.MessageDigest
buildscript {
repositories {
google()
maven {
url "https://repo1.maven.org/maven2"
}
jcenter {
content {
includeVersion 'org.jetbrains.trove4j', 'trove4j', '20160824'
}
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'androidx.navigation:navigation-safe-args-gradle-plugin:2.1.0'
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.10'
}
}
apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'
apply plugin: 'androidx.navigation.safeargs'
apply plugin: 'witness'
apply from: 'translations.gradle'
apply from: 'witness-verifications.gradle'
repositories {
maven {
url "https://raw.github.com/signalapp/maven/master/photoview/releases/"
content {
includeGroupByRegex "com\\.github\\.chrisbanes.*"
}
}
maven {
url "https://raw.github.com/signalapp/maven/master/shortcutbadger/releases/"
content {
includeGroupByRegex "me\\.leolin.*"
}
}
maven {
url "https://raw.github.com/signalapp/maven/master/circular-progress-button/releases/"
content {
includeGroupByRegex "com\\.github\\.dmytrodanylyk\\.circular-progress-button\\.*"
}
}
maven {
url "https://raw.github.com/signalapp/maven/master/sqlcipher/release/"
content {
includeGroupByRegex "org\\.signal.*"
}
}
maven { // textdrawable
url 'https://dl.bintray.com/amulyakhare/maven'
content {
includeGroupByRegex "com\\.amulyakhare.*"
}
}
google()
mavenCentral()
jcenter()
mavenLocal()
}
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.10.0'
}
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option "lite"
}
}
}
}
}
def canonicalVersionCode = 655
def canonicalVersionName = "4.63.2"
def postFixSize = 10
def abiPostFix = ['universal' : 0,
'armeabi-v7a' : 1,
'arm64-v8a' : 2,
'x86' : 3,
'x86_64' : 4]
android {
flavorDimensions "none"
compileSdkVersion 28
buildToolsVersion '28.0.3'
useLibrary 'org.apache.http.legacy'
dexOptions {
javaMaxHeapSize "4g"
}
defaultConfig {
versionCode canonicalVersionCode * postFixSize
versionName canonicalVersionName
minSdkVersion 19
targetSdkVersion 28
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
project.ext.set("archivesBaseName", "Signal");
buildConfigField "long", "BUILD_TIMESTAMP", getLastCommitTimestamp() + "L"
buildConfigField "String", "SIGNAL_URL", "\"https://textsecure-service.whispersystems.org\""
buildConfigField "String", "STORAGE_URL", "\"https://storage.signal.org\""
buildConfigField "String", "SIGNAL_CDN_URL", "\"https://cdn.signal.org\""
buildConfigField "String", "SIGNAL_CDN2_URL", "\"https://cdn2.signal.org\""
buildConfigField "String", "SIGNAL_CONTACT_DISCOVERY_URL", "\"https://api.directory.signal.org\""
buildConfigField "String", "SIGNAL_SERVICE_STATUS_URL", "\"uptime.signal.org\""
buildConfigField "String", "SIGNAL_KEY_BACKUP_URL", "\"https://api.backup.signal.org\""
buildConfigField "String", "CONTENT_PROXY_HOST", "\"contentproxy.signal.org\""
buildConfigField "int", "CONTENT_PROXY_PORT", "443"
buildConfigField "String", "SIGNAL_AGENT", "\"OWA\""
buildConfigField "String", "CDS_MRENCLAVE", "\"cd6cfc342937b23b1bdd3bbf9721aa5615ac9ff50a75c5527d441cd3276826c9\""
buildConfigField "String", "KBS_ENCLAVE_NAME", "\"fe7c1bfae98f9b073d220366ea31163ee82f6d04bead774f71ca8e5c40847bfe\""
buildConfigField "String", "KBS_MRENCLAVE", "\"a3baab19ef6ce6f34ab9ebb25ba722725ae44a8872dc0ff08ad6d83a9489de87\""
buildConfigField "String", "UNIDENTIFIED_SENDER_TRUST_ROOT", "\"BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF\""
buildConfigField "String", "ZKGROUP_SERVER_PUBLIC_PARAMS", "\"AMhf5ywVwITZMsff/eCyudZx9JDmkkkbV6PInzG4p8x3VqVJSFiMvnvlEKWuRob/1eaIetR31IYeAbm0NdOuHH8Qi+Rexi1wLlpzIo1gstHWBfZzy1+qHRV5A4TqPp15YzBPm0WSggW6PbSn+F4lf57VCnHF7p8SvzAA2ZZJPYJURt8X7bbg+H3i+PEjH9DXItNEqs2sNcug37xZQDLm7X0=\""
buildConfigField "String[]", "LANGUAGES", "new String[]{\"" + autoResConfig().collect { s -> s.replace('-r', '_') }.join('", "') + '"}'
buildConfigField "int", "CANONICAL_VERSION_CODE", "$canonicalVersionCode"
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
resConfigs autoResConfig()
splits {
abi {
enable true
reset()
include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
universalApk true
}
}
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions {
exclude 'LICENSE.txt'
exclude 'LICENSE'
exclude 'NOTICE'
exclude 'asm-license.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
exclude 'META-INF/proguard/androidx-annotations.pro'
}
buildTypes {
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard/proguard-firebase-messaging.pro',
'proguard/proguard-google-play-services.pro',
'proguard/proguard-jackson.pro',
'proguard/proguard-sqlite.pro',
'proguard/proguard-appcompat-v7.pro',
'proguard/proguard-square-okhttp.pro',
'proguard/proguard-square-okio.pro',
'proguard/proguard-spongycastle.pro',
'proguard/proguard-rounded-image-view.pro',
'proguard/proguard-glide.pro',
'proguard/proguard-shortcutbadger.pro',
'proguard/proguard-retrofit.pro',
'proguard/proguard-webrtc.pro',
'proguard/proguard-klinker.pro',
'proguard/proguard-retrolambda.pro',
'proguard/proguard-okhttp.pro',
'proguard/proguard-ez-vcard.pro',
'proguard/proguard.cfg'
testProguardFiles 'proguard/proguard-automation.pro',
'proguard/proguard.cfg'
}
staging {
initWith debug
buildConfigField "String", "SIGNAL_URL", "\"https://textsecure-service-staging.whispersystems.org\""
buildConfigField "String", "STORAGE_URL", "\"https://storage-staging.signal.org\""
buildConfigField "String", "SIGNAL_CDN_URL", "\"https://cdn-staging.signal.org\""
buildConfigField "String", "SIGNAL_CDN2_URL", "\"https://cdn2-staging.signal.org\""
buildConfigField "String", "SIGNAL_CONTACT_DISCOVERY_URL", "\"https://api-staging.directory.signal.org\""
buildConfigField "String", "SIGNAL_KEY_BACKUP_URL", "\"https://api-staging.backup.signal.org\""
buildConfigField "String", "CDS_MRENCLAVE", "\"ba4ebb438bc07713819ee6c98d94037747006d7df63fc9e44d2d6f1fec962a79\""
buildConfigField "String", "KBS_ENCLAVE_NAME", "\"823a3b2c037ff0cbe305cc48928cfcc97c9ed4a8ca6d49af6f7d6981fb60a4e9\""
buildConfigField "String", "UNIDENTIFIED_SENDER_TRUST_ROOT", "\"BbqY1DzohE4NUZoVF+L18oUPrK3kILllLEJh2UnPSsEx\""
buildConfigField "String", "ZKGROUP_SERVER_PUBLIC_PARAMS", "\"ABSY21VckQcbSXVNCGRYJcfWHiAMZmpTtTELcDmxgdFbtp/bWsSxZdMKzfCp8rvIs8ocCU3B37fT3r4Mi5qAemeGeR2X+/YmOGR5ofui7tD5mDQfstAI9i+4WpMtIe8KC3wU5w3Inq3uNWVmoGtpKndsNfwJrCg0Hd9zmObhypUnSkfYn2ooMOOnBpfdanRtrvetZUayDMSC5iSRcXKpdls=\""
}
flipper {
initWith debug
minifyEnabled false
}
release {
minifyEnabled true
proguardFiles = buildTypes.debug.proguardFiles
}
}
productFlavors {
play {
dimension "none"
ext.websiteUpdateUrl = "null"
buildConfigField "boolean", "PLAY_STORE_DISABLED", "false"
buildConfigField "String", "NOPLAY_UPDATE_URL", "$ext.websiteUpdateUrl"
}
website {
dimension "none"
ext.websiteUpdateUrl = "https://updates.signal.org/android"
buildConfigField "boolean", "PLAY_STORE_DISABLED", "true"
buildConfigField "String", "NOPLAY_UPDATE_URL", "\"$ext.websiteUpdateUrl\""
}
}
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFileName = output.outputFileName.replace(".apk", "-${variant.versionName}.apk")
def abiName = output.getFilter("ABI") ?: 'universal'
def postFix = abiPostFix.get(abiName, 0)
if (postFix >= postFixSize) throw new AssertionError("postFix is too large")
output.versionCodeOverride = canonicalVersionCode * postFixSize + postFix
}
}
lintOptions {
abortOnError true
baseline file("lint-baseline.xml")
disable "LintError"
}
testOptions {
unitTests {
includeAndroidResources = true
}
}
}
dependencies {
lintChecks project(':lintchecks')
implementation('androidx.appcompat:appcompat:1.1.0-beta01') {
force = true
}
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.preference:preference:1.0.0'
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.gridlayout:gridlayout:1.0.0'
implementation 'androidx.exifinterface:exifinterface:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.navigation:navigation-fragment:2.1.0'
implementation 'androidx.navigation:navigation-ui:2.1.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-alpha05'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.1.0'
implementation "androidx.camera:camera-core:1.0.0-beta01"
implementation "androidx.camera:camera-camera2:1.0.0-beta01"
implementation "androidx.camera:camera-lifecycle:1.0.0-beta01"
implementation "androidx.concurrent:concurrent-futures:1.0.0"
implementation "androidx.autofill:autofill:1.0.0"
implementation "androidx.paging:paging-common:2.1.2"
implementation "androidx.paging:paging-runtime:2.1.2"
implementation 'com.google.firebase:firebase-ml-vision:24.0.3'
implementation 'com.google.firebase:firebase-ml-vision-face-model:20.0.1'
implementation ('com.google.firebase:firebase-messaging:20.2.0') {
exclude group: 'com.google.firebase', module: 'firebase-core'
exclude group: 'com.google.firebase', module: 'firebase-analytics'
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
}
implementation 'com.google.android.gms:play-services-maps:16.1.0'
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation 'com.google.android.exoplayer:exoplayer-core:2.9.1'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.9.1'
implementation 'org.conscrypt:conscrypt-android:2.0.0'
implementation 'org.signal:aesgcmprovider:0.0.3'
implementation project(':libsignal-service')
implementation 'org.signal:zkgroup-android:0.7.0'
implementation 'org.signal:argon2:13.1@aar'
implementation 'org.signal:ringrtc-android:2.0.3'
implementation "me.leolin:ShortcutBadger:1.1.16"
implementation 'se.emilsjolander:stickylistheaders:2.7.0'
implementation 'com.jpardogo.materialtabstrip:library:1.0.9'
implementation 'org.apache.httpcomponents:httpclient-android:4.3.5'
implementation 'com.github.chrisbanes:PhotoView:2.1.3'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
annotationProcessor 'androidx.annotation:annotation:1.1.0'
implementation 'com.makeramen:roundedimageview:2.1.0'
implementation 'com.pnikosis:materialish-progress:1.5'
implementation 'org.greenrobot:eventbus:3.0.0'
implementation 'pl.tajchert:waitingdots:0.1.0'
implementation 'com.melnykov:floatingactionbutton:1.3.0'
implementation 'com.google.zxing:android-integration:3.1.0'
implementation 'mobi.upod:time-duration-picker:1.1.3'
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
implementation 'com.google.zxing:core:3.2.1'
implementation ('com.davemorrissey.labs:subsampling-scale-image-view:3.6.0') {
exclude group: 'com.android.support', module: 'support-annotations'
}
implementation ('cn.carbswang.android:NumberPickerView:1.0.9') {
exclude group: 'com.android.support', module: 'appcompat-v7'
}
implementation ('com.tomergoldst.android:tooltips:1.0.6') {
exclude group: 'com.android.support', module: 'appcompat-v7'
}
implementation ('com.klinkerapps:android-smsmms:4.0.1') {
exclude group: 'com.squareup.okhttp', module: 'okhttp'
exclude group: 'com.squareup.okhttp', module: 'okhttp-urlconnection'
}
implementation 'com.annimon:stream:1.1.8'
implementation ('com.takisoft.fix:colorpicker:0.9.1') {
exclude group: 'com.android.support', module: 'appcompat-v7'
exclude group: 'com.android.support', module: 'recyclerview-v7'
}
implementation 'com.airbnb.android:lottie:3.0.7'
implementation 'com.codewaves.stickyheadergrid:stickyheadergrid:0.9.4'
implementation 'com.github.dmytrodanylyk.circular-progress-button:library:1.1.3-S2'
implementation 'org.signal:android-database-sqlcipher:3.5.9-S3'
implementation ('com.googlecode.ez-vcard:ez-vcard:0.9.11') {
exclude group: 'com.fasterxml.jackson.core'
exclude group: 'org.freemarker'
}
implementation 'dnsjava:dnsjava:2.1.9'
flipperImplementation 'com.facebook.flipper:flipper:0.32.2'
flipperImplementation 'com.facebook.soloader:soloader:0.8.2'
testImplementation 'junit:junit:4.12'
testImplementation 'org.assertj:assertj-core:3.11.1'
testImplementation 'org.mockito:mockito-core:1.9.5'
testImplementation 'org.powermock:powermock-api-mockito:1.6.1'
testImplementation 'org.powermock:powermock-module-junit4:1.6.1'
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.1'
testImplementation 'org.powermock:powermock-classloading-xstream:1.6.1'
testImplementation 'androidx.test:core:1.2.0'
testImplementation ('org.robolectric:robolectric:4.2') {
exclude group: 'com.google.protobuf', module: 'protobuf-java'
}
testImplementation 'org.robolectric:shadows-multidex:4.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
dependencyVerification {
configuration = '(play|website)(Debug|Release)RuntimeClasspath'
}
def assembleWebsiteDescriptor = { variant, file ->
if (file.exists()) {
MessageDigest md = MessageDigest.getInstance("SHA-256");
file.eachByte 4096, {bytes, size ->
md.update(bytes, 0, size);
}
String digest = md.digest().collect {String.format "%02x", it}.join();
String url = variant.productFlavors.get(0).ext.websiteUpdateUrl
String apkName = file.getName()
String descriptor = "{" +
"\"versionCode\" : ${canonicalVersionCode * postFixSize + abiPostFix['universal']}," +
"\"versionName\" : \"$canonicalVersionName\"," +
"\"sha256sum\" : \"$digest\"," +
"\"url\" : \"$url/$apkName\"" +
"}"
File descriptorFile = new File(file.getParent(), apkName.replace(".apk", ".json"))
descriptorFile.write(descriptor)
}
}
def signProductionRelease = { variant ->
variant.outputs.collect { output ->
String apkName = output.outputFile.name
File inputFile = new File(output.outputFile.path)
File outputFile = new File(output.outputFile.parent, apkName.replace('-unsigned', ''))
new ApkSignerUtil('sun.security.pkcs11.SunPKCS11',
'pkcs11.config',
'PKCS11',
'file:pkcs11.password').calculateSignature(inputFile.getAbsolutePath(),
outputFile.getAbsolutePath())
inputFile.delete()
outputFile
}
}
task signProductionPlayRelease {
doLast {
signProductionRelease(android.applicationVariants.find { (it.name == 'playRelease') })
}
}
task signProductionWebsiteRelease {
doLast {
def variant = android.applicationVariants.find { (it.name == 'websiteRelease') }
File signedRelease = signProductionRelease(variant).find { it.name.contains('universal') }
assembleWebsiteDescriptor(variant, signedRelease)
}
}
tasks.whenTaskAdded { task ->
if (task.name.equals("assemblePlayRelease")) {
task.finalizedBy signProductionPlayRelease
}
if (task.name.equals("assembleWebsiteRelease")) {
task.finalizedBy signProductionWebsiteRelease
}
}
def getLastCommitTimestamp() {
new ByteArrayOutputStream().withStream { os ->
def result = exec {
executable = 'git'
args = ['log', '-1', '--pretty=format:%ct']
standardOutput = os
}
return os.toString() + "000"
}
}

11
app/jni/Android.mk Normal file
View File

@@ -0,0 +1,11 @@
JNI_DIR := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := native-utils
LOCAL_C_INCLUDES := $(JNI_DIR)/utils/
LOCAL_CFLAGS += -Wall
LOCAL_SRC_FILES := $(JNI_DIR)/utils/org_thoughtcrime_securesms_util_FileUtils.cpp
include $(BUILD_SHARED_LIBRARY)

6
app/jni/Application.mk Normal file
View File

@@ -0,0 +1,6 @@
# Built with NDK 19.2.5345600
APP_ABI := armeabi-v7a x86 arm64-v8a x86_64
APP_PLATFORM := android-19
APP_STL := c++_static
APP_CPPFLAGS += -fexceptions
APP_OPTIM := debug

View File

@@ -0,0 +1,45 @@
#include "org_thoughtcrime_securesms_util_FileUtils.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/memfd.h>
#include <syscall.h>
jint JNICALL Java_org_thoughtcrime_securesms_util_FileUtils_getFileDescriptorOwner
(JNIEnv *env, jclass clazz, jobject fileDescriptor)
{
jclass fdClass = env->GetObjectClass(fileDescriptor);
if (fdClass == NULL) {
return -1;
}
jfieldID fdFieldId = env->GetFieldID(fdClass, "descriptor", "I");
if (fdFieldId == NULL) {
return -1;
}
int fd = env->GetIntField(fileDescriptor, fdFieldId);
struct stat stat_struct;
if (fstat(fd, &stat_struct) != 0) {
return -1;
}
return stat_struct.st_uid;
}
JNIEXPORT jint JNICALL Java_org_thoughtcrime_securesms_util_FileUtils_createMemoryFileDescriptor
(JNIEnv *env, jclass clazz, jstring jname)
{
const char *name = env->GetStringUTFChars(jname, NULL);
int fd = syscall(SYS_memfd_create, name, MFD_CLOEXEC);
env->ReleaseStringUTFChars(jname, name);
return fd;
}

View File

@@ -0,0 +1,29 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_thoughtcrime_securesms_util_FileUtils */
#ifndef _Included_org_thoughtcrime_securesms_util_FileUtils
#define _Included_org_thoughtcrime_securesms_util_FileUtils
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_thoughtcrime_securesms_util_FileUtils
* Method: getFileDescriptorOwner
* Signature: (Ljava/io/FileDescriptor;)I
*/
JNIEXPORT jint JNICALL Java_org_thoughtcrime_securesms_util_FileUtils_getFileDescriptorOwner
(JNIEnv *, jclass, jobject);
/*
* Class: org_thoughtcrime_securesms_util_FileUtils
* Method: createMemoryFileDescriptor
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_org_thoughtcrime_securesms_util_FileUtils_createMemoryFileDescriptor
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif

48
app/lint-baseline.xml Normal file
View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<issues format="5" by="lint 3.3.2" client="gradle" variant="playRelease" version="3.3.2">
<issue
id="MissingPermission"
message="Call requires permission which may be rejected by user: code should explicitly check to see if permission is available (with `checkPermission`) or explicitly handle a potential `SecurityException`"
errorLine1=" List&lt;SubscriptionInfo> list = subscriptionManager.getActiveSubscriptionInfoList();"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/org/thoughtcrime/securesms/util/dualsim/SubscriptionManagerCompat.java"
line="101"
column="35"/>
</issue>
<issue
id="ResourceType"
message="Expected resource of type styleable"
errorLine1=" drawables.getColor(1, 0xff000000);"
errorLine2=" ~">
<location
file="src/main/java/org/thoughtcrime/securesms/contacts/ContactSelectionListAdapter.java"
line="187"
column="36"/>
</issue>
<issue
id="AppLinkUrlError"
message="Missing URL"
errorLine1=" &lt;intent-filter>"
errorLine2=" ^">
<location
file="AndroidManifest.xml"
line="368"
column="9"/>
</issue>
<issue
id="AppLinkUrlError"
message="Missing URL"
errorLine1=" &lt;intent-filter>"
errorLine2=" ^">
<location
file="AndroidManifest.xml"
line="381"
column="9"/>
</issue>
</issues>

33
app/lint.xml Normal file
View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<!-- L10N errors -->
<!-- This is a runtime crash so we don't want to ship with this. -->
<issue id="StringFormatMatches" severity="error" />
<!-- L10N warnings -->
<issue id="MissingTranslation" severity="warning" />
<issue id="MissingQuantity" severity="warning" />
<issue id="ExtraTranslation" severity="warning" />
<issue id="ImpliedQuantity" severity="warning" />
<issue id="CanvasSize" severity="error" />
<issue id="HardcodedText" severity="error" />
<issue id="VectorRaster" severity="error" />
<issue id="ButtonOrder" severity="error" />
<issue id="ExtraTranslation" severity="warning" />
<!-- Custom lints -->
<issue id="LogNotSignal" severity="error" />
<issue id="LogNotAppSignal" severity="error" />
<issue id="LogTagInlined" severity="error" />
<issue id="RestrictedApi" severity="error">
<ignore path="*/org/thoughtcrime/securesms/mediasend/camerax/VideoCapture.java" />
<ignore path="*/org/thoughtcrime/securesms/mediasend/camerax/CameraXModule.java" />
<ignore path="*/org/thoughtcrime/securesms/conversation/*.java" />
<ignore path="*/org/thoughtcrime/securesms/lock/v2/CreateKbsPinViewModel.java" />
<ignore path="*/org/thoughtcrime/securesms/jobs/StickerPackDownloadJob.java" />
</issue>
</lint>

View File

@@ -9,3 +9,5 @@
-dontwarn org.hamcrest.**
-dontwarn org.mockito.**
-dontwarn com.squareup.**
-dontobfuscate

View File

@@ -0,0 +1 @@
-dontwarn ezvcard.io.html.HCardPage

View File

@@ -0,0 +1 @@
-dontwarn com.google.firebase.analytics.connector.AnalyticsConnector

View File

@@ -0,0 +1,6 @@
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}

View File

@@ -0,0 +1,3 @@
-dontwarn android.net.ConnectivityManager
-dontwarn android.net.ConnectivityManager$NetworkCallback
-dontwarn org.webrtc.NetworkMonitorAutoDetect$ConnectivityManagerDelegate

View File

@@ -0,0 +1,3 @@
-dontwarn okio.**
-dontwarn javax.annotation.Nullable
-dontwarn javax.annotation.ParametersAreNonnullByDefault

View File

@@ -0,0 +1,2 @@
-dontwarn java.lang.invoke.*
-dontwarn **$$Lambda$*

View File

@@ -0,0 +1,5 @@
-keep class org.sqlite.** { *; }
-keep class org.sqlite.database.** { *; }
-keep class net.sqlcipher.** { *; }
-dontwarn net.sqlcipher.**

11
app/proguard/proguard.cfg Normal file
View File

@@ -0,0 +1,11 @@
-dontoptimize
-dontobfuscate
-keepattributes SourceFile,LineNumberTable
-keep class org.whispersystems.** { *; }
-keep class org.thoughtcrime.securesms.** { *; }
-keepclassmembers class ** {
public void onEvent*(**);
}
# Protobuf lite
-keep class * extends com.google.protobuf.GeneratedMessageLite { *; }

View File

@@ -0,0 +1,29 @@
{
"data": [
{
"name": "Ottttooooooooo Ocataaaaaaaavius",
"number": "+1 (555) 555-5555",
"label": "Mobile"
},
{
"name": "Victor Von Doom Phd",
"number": "+1 (555) 123-4567",
"label": "Home"
},
{
"name": "Flash Thompson",
"number": "+1 (555) 435-1261",
"label": "Work"
},
{
"name": "Dr. Curtis Connors",
"number": "+1 (555) 992-1567",
"label": "Mobile"
},
{
"name": "Billy Russo",
"number": "+1 (555) 234-1516",
"label": "Mobile"
}
]
}

View File

@@ -0,0 +1,93 @@
package org.thoughtcrime.securesms.lock;
import org.junit.Test;
import org.thoughtcrime.securesms.util.Hex;
import org.whispersystems.signalservice.api.kbs.HashedPin;
import org.whispersystems.signalservice.api.kbs.KbsData;
import org.whispersystems.signalservice.api.kbs.MasterKey;
import java.io.IOException;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public final class PinHashing_hashPin_Test {
@Test
public void argon2_hashed_pin_password() throws IOException {
String pin = "password";
byte[] backupId = Hex.fromStringCondensed("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
MasterKey masterKey = new MasterKey(Hex.fromStringCondensed("202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"));
HashedPin hashedPin = PinHashing.hashPin(pin, () -> backupId);
KbsData kbsData = hashedPin.createNewKbsData(masterKey);
assertArrayEquals(hashedPin.getKbsAccessKey(), kbsData.getKbsAccessKey());
assertArrayEquals(Hex.fromStringCondensed("ab7e8499d21f80a6600b3b9ee349ac6d72c07e3359fe885a934ba7aa844429f8"), kbsData.getKbsAccessKey());
assertArrayEquals(Hex.fromStringCondensed("3f33ce58eb25b40436592a30eae2a8fabab1899095f4e2fba6e2d0dc43b4a2d9cac5a3931748522393951e0e54dec769"), kbsData.getCipherText());
assertEquals(masterKey, kbsData.getMasterKey());
String localPinHash = PinHashing.localPinHash(pin);
assertTrue(PinHashing.verifyLocalPinHash(localPinHash, pin));
}
@Test
public void argon2_hashed_pin_another_password() throws IOException {
String pin = "anotherpassword";
byte[] backupId = Hex.fromStringCondensed("202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f");
MasterKey masterKey = new MasterKey(Hex.fromStringCondensed("88a787415a2ecd79da0d1016a82a27c5c695c9a19b88b0aa1d35683280aa9a67"));
HashedPin hashedPin = PinHashing.hashPin(pin, () -> backupId);
KbsData kbsData = hashedPin.createNewKbsData(masterKey);
assertArrayEquals(hashedPin.getKbsAccessKey(), kbsData.getKbsAccessKey());
assertArrayEquals(Hex.fromStringCondensed("301d9dd1e96f20ce51083f67d3298fd37b97525de8324d5e12ed2d407d3d927b"), kbsData.getKbsAccessKey());
assertArrayEquals(Hex.fromStringCondensed("9d9b05402ea39c17ff1c9298c8a0e86784a352aa02a74943bf8bcf07ec0f4b574a5b786ad0182c8d308d9eb06538b8c9"), kbsData.getCipherText());
assertEquals(masterKey, kbsData.getMasterKey());
String localPinHash = PinHashing.localPinHash(pin);
assertTrue(PinHashing.verifyLocalPinHash(localPinHash, pin));
}
@Test
public void argon2_hashed_pin_password_with_spaces_diacritics_and_non_arabic_numerals() throws IOException {
String pin = " Pass६örd ";
byte[] backupId = Hex.fromStringCondensed("cba811749042b303a6a7efa5ccd160aea5e3ea243c8d2692bd13d515732f51a8");
MasterKey masterKey = new MasterKey(Hex.fromStringCondensed("9571f3fde1e58588ba49bcf82be1b301ca3859a6f59076f79a8f47181ef952bf"));
HashedPin hashedPin = PinHashing.hashPin(pin, () -> backupId);
KbsData kbsData = hashedPin.createNewKbsData(masterKey);
assertArrayEquals(hashedPin.getKbsAccessKey(), kbsData.getKbsAccessKey());
assertArrayEquals(Hex.fromStringCondensed("ab645acdccc1652a48a34b2ac6926340ff35c03034013f68760f20013f028dd8"), kbsData.getKbsAccessKey());
assertArrayEquals(Hex.fromStringCondensed("11c0ba1834db15e47c172f6c987c64bd4cfc69c6047dd67a022afeec0165a10943f204d5b8f37b3cb7bab21c6dfc39c8"), kbsData.getCipherText());
assertEquals(masterKey, kbsData.getMasterKey());
assertEquals("577939bccb2b6638c39222d5a97998a867c5e154e30b82cc120f2dd07a3de987", kbsData.getMasterKey().deriveRegistrationLock());
String localPinHash = PinHashing.localPinHash(pin);
assertTrue(PinHashing.verifyLocalPinHash(localPinHash, pin));
}
@Test
public void argon2_hashed_pin_password_with_just_non_arabic_numerals() throws IOException {
String pin = " ६१८ ";
byte[] backupId = Hex.fromStringCondensed("717dc111a98423a57196512606822fca646c653facd037c10728f14ba0be2ab3");
MasterKey masterKey = new MasterKey(Hex.fromStringCondensed("0432d735b32f66d0e3a70d4f9cc821a8529521a4937d26b987715d8eff4e4c54"));
HashedPin hashedPin = PinHashing.hashPin(pin, () -> backupId);
KbsData kbsData = hashedPin.createNewKbsData(masterKey);
assertArrayEquals(hashedPin.getKbsAccessKey(), kbsData.getKbsAccessKey());
assertArrayEquals(Hex.fromStringCondensed("d2fedabd0d4c17a371491c9722578843a26be3b4923e28d452ab2fc5491e794b"), kbsData.getKbsAccessKey());
assertArrayEquals(Hex.fromStringCondensed("877ef871ef1fc668401c717ef21aa12e8523579fb1ff4474b76f28c2293537c80cc7569996c9e0229bea7f378e3a824e"), kbsData.getCipherText());
assertEquals(masterKey, kbsData.getMasterKey());
assertEquals("23a75cb1df1a87df45cc2ed167c2bdc85ab1220b847c88761b0005cac907fce5", kbsData.getMasterKey().deriveRegistrationLock());
String localPinHash = PinHashing.localPinHash(pin);
assertTrue(PinHashing.verifyLocalPinHash(localPinHash, pin));
}
}

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.thoughtcrime.securesms">
<application
android:name=".FlipperApplicationContext"
tools:replace="android:name"/>
</manifest>

View File

@@ -0,0 +1,27 @@
package org.thoughtcrime.securesms;
import com.facebook.flipper.android.AndroidFlipperClient;
import com.facebook.flipper.core.FlipperClient;
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
import com.facebook.soloader.SoLoader;
import org.thoughtcrime.securesms.database.FlipperSqlCipherAdapter;
public class FlipperApplicationContext extends ApplicationContext {
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, false);
FlipperClient client = AndroidFlipperClient.getInstance(this);
client.addPlugin(new InspectorFlipperPlugin(this, DescriptorMapping.withDefaults()));
client.addPlugin(new DatabasesFlipperPlugin(new FlipperSqlCipherAdapter(this)));
client.addPlugin(new SharedPreferencesFlipperPlugin(this));
client.start();
}
}

View File

@@ -0,0 +1,245 @@
package org.thoughtcrime.securesms.database;
import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.facebook.flipper.plugins.databases.DatabaseDescriptor;
import com.facebook.flipper.plugins.databases.DatabaseDriver;
import net.sqlcipher.DatabaseUtils;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteStatement;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A lot of this code is taken from {@link com.facebook.flipper.plugins.databases.impl.SqliteDatabaseDriver}
* and made to work with SqlCipher. Unfortunately I couldn't use it directly, nor subclass it.
*/
public class FlipperSqlCipherAdapter extends DatabaseDriver<FlipperSqlCipherAdapter.Descriptor> {
public FlipperSqlCipherAdapter(Context context) {
super(context);
}
@Override
public List<Descriptor> getDatabases() {
return Collections.singletonList(new Descriptor(DatabaseFactory.getRawDatabase(getContext())));
}
@Override
public List<String> getTableNames(Descriptor descriptor) {
SQLiteDatabase db = descriptor.getReadable();
List<String> tableNames = new ArrayList<>();
try (Cursor cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type IN (?, ?)", new String[] { "table", "view" })) {
while (cursor != null && cursor.moveToNext()) {
tableNames.add(cursor.getString(0));
}
}
return tableNames;
}
@Override
public DatabaseGetTableDataResponse getTableData(Descriptor descriptor, String table, String order, boolean reverse, int start, int count) {
SQLiteDatabase db = descriptor.getReadable();
long total = DatabaseUtils.queryNumEntries(db, table);
String orderBy = order != null ? order + (reverse ? " DESC" : " ASC") : null;
String limitBy = start + ", " + count;
try (Cursor cursor = db.query(table, null, null, null, null, null, orderBy, limitBy)) {
String[] columnNames = cursor.getColumnNames();
List<List<Object>> rows = cursorToList(cursor);
return new DatabaseGetTableDataResponse(Arrays.asList(columnNames), rows, start, rows.size(), total);
}
}
@Override
public DatabaseGetTableStructureResponse getTableStructure(Descriptor descriptor, String table) {
SQLiteDatabase db = descriptor.getReadable();
Map<String, String> foreignKeyValues = new HashMap<>();
try(Cursor cursor = db.rawQuery("PRAGMA foreign_key_list(" + table + ")", null)) {
while (cursor != null && cursor.moveToNext()) {
String from = cursor.getString(cursor.getColumnIndex("from"));
String to = cursor.getString(cursor.getColumnIndex("to"));
String tableName = cursor.getString(cursor.getColumnIndex("table")) + "(" + to + ")";
foreignKeyValues.put(from, tableName);
}
}
List<String> structureColumns = Arrays.asList("column_name", "data_type", "nullable", "default", "primary_key", "foreign_key");
List<List<Object>> structureValues = new ArrayList<>();
try (Cursor cursor = db.rawQuery("PRAGMA table_info(" + table + ")", null)) {
while (cursor != null && cursor.moveToNext()) {
String columnName = cursor.getString(cursor.getColumnIndex("name"));
String foreignKey = foreignKeyValues.containsKey(columnName) ? foreignKeyValues.get(columnName) : null;
structureValues.add(Arrays.asList(columnName,
cursor.getString(cursor.getColumnIndex("type")),
cursor.getInt(cursor.getColumnIndex("notnull")) == 0,
getObjectFromColumnIndex(cursor, cursor.getColumnIndex("dflt_value")),
cursor.getInt(cursor.getColumnIndex("pk")) == 1,
foreignKey));
}
}
List<String> indexesColumns = Arrays.asList("index_name", "unique", "indexed_column_name");
List<List<Object>> indexesValues = new ArrayList<>();
try (Cursor indexesCursor = db.rawQuery("PRAGMA index_list(" + table + ")", null)) {
List<String> indexedColumnNames = new ArrayList<>();
String indexName = indexesCursor.getString(indexesCursor.getColumnIndex("name"));
try(Cursor indexInfoCursor = db.rawQuery("PRAGMA index_info(" + indexName + ")", null)) {
while (indexInfoCursor.moveToNext()) {
indexedColumnNames.add(indexInfoCursor.getString(indexInfoCursor.getColumnIndex("name")));
}
}
indexesValues.add(Arrays.asList(indexName,
indexesCursor.getInt(indexesCursor.getColumnIndex("unique")) == 1,
TextUtils.join(",", indexedColumnNames)));
}
return new DatabaseGetTableStructureResponse(structureColumns, structureValues, indexesColumns, indexesValues);
}
@Override
public DatabaseGetTableInfoResponse getTableInfo(Descriptor databaseDescriptor, String table) {
SQLiteDatabase db = databaseDescriptor.getReadable();
try (Cursor cursor = db.rawQuery("SELECT sql FROM sqlite_master WHERE name = ?", new String[] { table })) {
cursor.moveToFirst();
return new DatabaseGetTableInfoResponse(cursor.getString(cursor.getColumnIndex("sql")));
}
}
@Override
public DatabaseExecuteSqlResponse executeSQL(Descriptor descriptor, String query) {
SQLiteDatabase db = descriptor.getWritable();
String firstWordUpperCase = getFirstWord(query).toUpperCase();
switch (firstWordUpperCase) {
case "UPDATE":
case "DELETE":
return executeUpdateDelete(db, query);
case "INSERT":
return executeInsert(db, query);
case "SELECT":
case "PRAGMA":
case "EXPLAIN":
return executeSelect(db, query);
default:
return executeRawQuery(db, query);
}
}
private static String getFirstWord(String s) {
s = s.trim();
int firstSpace = s.indexOf(' ');
return firstSpace >= 0 ? s.substring(0, firstSpace) : s;
}
private static DatabaseExecuteSqlResponse executeUpdateDelete(SQLiteDatabase database, String query) {
SQLiteStatement statement = database.compileStatement(query);
int count = statement.executeUpdateDelete();
return DatabaseExecuteSqlResponse.successfulUpdateDelete(count);
}
private static DatabaseExecuteSqlResponse executeInsert(SQLiteDatabase database, String query) {
SQLiteStatement statement = database.compileStatement(query);
long insertedId = statement.executeInsert();
return DatabaseExecuteSqlResponse.successfulInsert(insertedId);
}
private static DatabaseExecuteSqlResponse executeSelect(SQLiteDatabase database, String query) {
try (Cursor cursor = database.rawQuery(query, null)) {
String[] columnNames = cursor.getColumnNames();
List<List<Object>> rows = cursorToList(cursor);
return DatabaseExecuteSqlResponse.successfulSelect(Arrays.asList(columnNames), rows);
}
}
private static DatabaseExecuteSqlResponse executeRawQuery(SQLiteDatabase database, String query) {
database.execSQL(query);
return DatabaseExecuteSqlResponse.successfulRawQuery();
}
private static @NonNull List<List<Object>> cursorToList(Cursor cursor) {
List<List<Object>> rows = new ArrayList<>();
int numColumns = cursor.getColumnCount();
while (cursor.moveToNext()) {
List<Object> values = new ArrayList<>(numColumns);
for (int column = 0; column < numColumns; column++) {
values.add(getObjectFromColumnIndex(cursor, column));
}
rows.add(values);
}
return rows;
}
private static @Nullable Object getObjectFromColumnIndex(Cursor cursor, int column) {
switch (cursor.getType(column)) {
case Cursor.FIELD_TYPE_NULL:
return null;
case Cursor.FIELD_TYPE_INTEGER:
return cursor.getLong(column);
case Cursor.FIELD_TYPE_FLOAT:
return cursor.getDouble(column);
case Cursor.FIELD_TYPE_BLOB:
return cursor.getBlob(column);
case Cursor.FIELD_TYPE_STRING:
default:
return cursor.getString(column);
}
}
static class Descriptor implements DatabaseDescriptor {
private final SQLCipherOpenHelper sqlCipherOpenHelper;
Descriptor(@NonNull SQLCipherOpenHelper sqlCipherOpenHelper) {
this.sqlCipherOpenHelper = sqlCipherOpenHelper;
}
@Override
public String name() {
return sqlCipherOpenHelper.getDatabaseName();
}
public @NonNull SQLiteDatabase getReadable() {
return sqlCipherOpenHelper.getReadableDatabase();
}
public @NonNull SQLiteDatabase getWritable() {
return sqlCipherOpenHelper.getWritableDatabase();
}
}
}

View File

@@ -0,0 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<string name="app_name">Signal (Flipper)</string>
</resources>

View File

@@ -0,0 +1,762 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.thoughtcrime.securesms">
<uses-sdk tools:overrideLibrary="androidx.camera.core,androidx.camera.camera2,androidx.camera.lifecycle" />
<permission android:name="org.thoughtcrime.securesms.ACCESS_SECRETS"
android:label="Access to TextSecure Secrets"
android:protectionLevel="signature" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.bluetooth" android:required="false" />
<uses-feature android:name="android.hardware.location" android:required="false"/>
<uses-feature android:name="android.hardware.location.network" android:required="false"/>
<uses-feature android:name="android.hardware.location.gps" android:required="false"/>
<uses-feature android:name="android.hardware.microphone" android:required="false"/>
<uses-feature android:name="android.hardware.wifi" android:required="false"/>
<uses-feature android:name="android.hardware.portrait" android:required="false"/>
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
<uses-permission android:name="org.thoughtcrime.securesms.ACCESS_SECRETS"/>
<uses-permission android:name="android.permission.READ_PROFILE"/>
<uses-permission android:name="android.permission.WRITE_PROFILE"/>
<uses-permission android:name="android.permission.BROADCAST_WAP_PUSH"
tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_MMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CALL_STATE"/>
<!-- For sending/receiving events -->
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<!-- Normal -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- So we can add a TextSecure 'Account' -->
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<!-- For conversation 'shortcuts' on the desktop -->
<uses-permission android:name="android.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<!-- For fixing MMS -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- Set image as wallpaper -->
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.RAISED_THREAD_PRIORITY" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/>
<application android:name=".ApplicationContext"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
tools:replace="android:allowBackup"
android:allowBackup="false"
android:theme="@style/TextSecure.LightTheme"
android:largeHeap="true">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCSx9xea86GwDKGznCAULE9Y5a8b-TfN9U"/>
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc" />
<meta-data android:name="firebase_analytics_collection_deactivated" android:value="true" />
<meta-data android:name="google_analytics_adid_collection_enabled" android:value="false" />
<meta-data android:name="firebase_messaging_auto_init_enabled" android:value="false" />
<activity android:name="org.thoughtcrime.securesms.WebRtcCallActivity"
android:theme="@style/TextSecure.LightTheme.WebRTCCall"
android:excludeFromRecents="true"
android:screenOrientation="portrait"
android:supportsPictureInPicture="true"
android:windowSoftInputMode="stateAlwaysHidden"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:launchMode="singleTask"/>
<activity android:name=".InviteActivity"
android:theme="@style/Signal.Light.NoActionBar.Invite"
android:windowSoftInputMode="stateHidden"
android:parentActivityName=".MainActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.thoughtcrime.securesms.MainActivity" />
</activity>
<activity android:name=".PromptMmsActivity"
android:label="Configure MMS Settings"
android:windowSoftInputMode="stateUnchanged"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".DeviceProvisioningActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tsdevice"/>
</intent-filter>
</activity>
<activity android:name=".preferences.MmsPreferencesActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".sharing.ShareActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:taskAffinity=""
android:noHistory="true"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="audio/*" />
<data android:mimeType="image/*" />
<data android:mimeType="text/plain" />
<data android:mimeType="video/*" />
<data android:mimeType="application/*"/>
<data android:mimeType="text/*"/>
<data android:mimeType="*/*"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="image/*" />
<data android:mimeType="video/*" />
</intent-filter>
<meta-data
android:name="android.service.chooser.chooser_target_service"
android:value=".service.DirectShareService" />
</activity>
<activity android:name=".stickers.StickerPackPreviewActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:launchMode="singleTask"
android:noHistory="true"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="sgnl"
android:host="addstickers" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https"
android:host="signal.art"
android:pathPrefix="/addstickers"/>
</intent-filter>
</activity>
<activity-alias android:name=".RoutingActivity"
android:targetActivity=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.MULTIWINDOW_LAUNCHER" />
</intent-filter>
<meta-data android:name="com.sec.minimode.icon.portrait.normal"
android:resource="@mipmap/ic_launcher" />
<meta-data android:name="com.sec.minimode.icon.landscape.normal"
android:resource="@mipmap/ic_launcher" />
</activity-alias>
<activity android:name=".conversation.ConversationActivity"
android:windowSoftInputMode="stateUnchanged"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.thoughtcrime.securesms.MainActivity" />
</activity>
<activity android:name=".longmessage.LongMessageActivity" />
<activity android:name=".conversation.ConversationPopupActivity"
android:windowSoftInputMode="stateVisible"
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true"
android:theme="@style/TextSecure.LightTheme.Popup"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize" />
<activity android:name=".MessageDetailsActivity"
android:label="@string/AndroidManifest__message_details"
android:windowSoftInputMode="stateHidden"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".GroupCreateActivity"
android:windowSoftInputMode="stateVisible"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".groups.ui.pendingmemberinvites.PendingMemberInvitesActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:theme="@style/TextSecure.LightNoActionBar" />
<activity android:name=".groups.ui.managegroup.ManageGroupActivity"
android:windowSoftInputMode="stateAlwaysHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".DatabaseMigrationActivity"
android:theme="@style/NoAnimation.Theme.AppCompat.Light.DarkActionBar"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".migrations.ApplicationMigrationActivity"
android:theme="@style/NoAnimation.Theme.AppCompat.Light.DarkActionBar"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".PassphraseCreateActivity"
android:label="@string/AndroidManifest__create_passphrase"
android:windowSoftInputMode="stateUnchanged"
android:theme="@style/TextSecure.LightNoActionBar"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".PassphrasePromptActivity"
android:launchMode="singleTask"
android:theme="@style/TextSecure.LightIntroTheme"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".NewConversationActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:windowSoftInputMode="stateAlwaysVisible"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".PushContactSelectionActivity"
android:label="@string/AndroidManifest__select_contacts"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".giph.ui.GiphyActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".mediasend.MediaSendActivity"
android:theme="@style/TextSecure.FullScreenMedia"
android:windowSoftInputMode="stateHidden"
android:launchMode="singleTop"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".PassphraseChangeActivity"
android:label="@string/AndroidManifest__change_passphrase"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".VerifyIdentityActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".ApplicationPreferencesActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.NOTIFICATION_PREFERENCES" />
</intent-filter>
</activity>
<activity android:name=".registration.RegistrationNavigationActivity"
android:launchMode="singleTask"
android:theme="@style/TextSecure.LightRegistrationTheme"
android:windowSoftInputMode="stateUnchanged"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".revealable.ViewOnceMessageActivity"
android:launchMode="singleTask"
android:theme="@style/TextSecure.FullScreenMedia"
android:windowSoftInputMode="stateHidden"
android:excludeFromRecents="true"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".stickers.StickerManagementActivity"
android:launchMode="singleTask"
android:theme="@style/TextSecure.LightTheme"
android:windowSoftInputMode="stateUnchanged"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".DeviceActivity"
android:label="@string/AndroidManifest__linked_devices"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".logsubmit.SubmitDebugLogActivity"
android:label="@string/AndroidManifest__log_submit"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".MediaPreviewActivity"
android:label="@string/AndroidManifest__media_preview"
android:windowSoftInputMode="stateHidden"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".AvatarPreviewActivity"
android:label="@string/AndroidManifest__media_preview"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".mediaoverview.MediaOverviewActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".DummyActivity"
android:theme="@android:style/Theme.NoDisplay"
android:enabled="true"
android:allowTaskReparenting="true"
android:noHistory="true"
android:excludeFromRecents="true"
android:alwaysRetainTaskState="false"
android:stateNotNeeded="true"
android:clearTaskOnLaunch="true"
android:finishOnTaskLaunch="true" />
<activity android:name=".PlayServicesProblemActivity"
android:theme="@style/TextSecure.DialogActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".SmsSendtoActivity">
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact" />
</intent-filter>
</activity>
<activity android:name="org.thoughtcrime.securesms.webrtc.VoiceCallShare"
android:excludeFromRecents="true"
android:theme="@style/NoAnimation.Theme.BlackScreen"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.call" />
</intent-filter>
</activity>
<activity android:name=".RecipientPreferenceActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".mediasend.AvatarSelectionActivity"
android:theme="@style/TextSecure.FullScreenMedia"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".BlockedContactsActivity"
android:theme="@style/TextSecure.LightTheme"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".scribbles.ImageEditorStickerSelectActivity"
android:theme="@style/TextSecure.DarkTheme"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".profiles.edit.EditProfileActivity"
android:theme="@style/TextSecure.LightRegistrationTheme"
android:windowSoftInputMode="stateVisible|adjustResize" />
<activity android:name=".lock.v2.CreateKbsPinActivity"
android:theme="@style/TextSecure.LightRegistrationTheme"
android:windowSoftInputMode="adjustResize"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".lock.v2.KbsMigrationActivity"
android:theme="@style/TextSecure.LightRegistrationTheme"
android:windowSoftInputMode="adjustResize"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".ClearProfileAvatarActivity"
android:theme="@style/Theme.AppCompat.Dialog.Alert"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:icon="@drawable/clear_profile_avatar"
android:label="@string/AndroidManifest_remove_photo">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.action.CLEAR_PROFILE_PHOTO"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name=".messagerequests.MessageRequestMegaphoneActivity"
android:theme="@style/TextSecure.LightRegistrationTheme"
android:windowSoftInputMode="adjustResize"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".contactshare.ContactShareEditActivity"
android:theme="@style/TextSecure.LightTheme"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".contactshare.ContactNameEditActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".contactshare.SharedContactDetailsActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".ShortcutLauncherActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:exported="true"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity
android:name=".maps.PlacePickerActivity"
android:label="@string/PlacePickerActivity_title"
android:theme="@style/TextSecure.LightNoActionBar"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".MainActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize" />
<activity android:name=".pin.PinRestoreActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize" />
<activity android:name=".groups.ui.creategroup.CreateGroupActivity"
android:theme="@style/TextSecure.LightNoActionBar" />
<activity android:name=".groups.ui.addtogroup.AddToGroupsActivity"
android:theme="@style/TextSecure.LightNoActionBar" />
<activity android:name=".groups.ui.addmembers.AddMembersActivity"
android:theme="@style/TextSecure.LightNoActionBar" />
<activity android:name=".groups.ui.creategroup.details.AddGroupDetailsActivity"
android:theme="@style/TextSecure.LightNoActionBar" />
<service android:enabled="true" android:name="org.thoughtcrime.securesms.service.WebRtcCallService"/>
<service android:enabled="true" android:name=".service.ApplicationMigrationService"/>
<service android:enabled="true" android:exported="false" android:name=".service.KeyCachingService"/>
<service android:enabled="true" android:name=".messages.IncomingMessageObserver$ForegroundService"/>
<service android:name=".service.QuickResponseService"
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</service>
<service android:name=".service.AccountAuthenticatorService" android:exported="true">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator" />
</service>
<service android:name=".service.ContactsSyncAdapterService" android:exported="true">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data android:name="android.content.SyncAdapter" android:resource="@xml/syncadapter" />
<meta-data android:name="android.provider.CONTACTS_STRUCTURE" android:resource="@xml/contactsformat" />
</service>
<service android:name=".service.DirectShareService"
android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
<intent-filter>
<action android:name="android.service.chooser.ChooserTargetService" />
</intent-filter>
</service>
<service android:name=".service.GenericForegroundService"/>
<service android:name=".gcm.FcmFetchService" />
<service android:name=".gcm.FcmReceiveService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<receiver android:name=".service.SmsListener"
android:permission="android.permission.BROADCAST_SMS"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1001">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.SMS_DELIVER"/>
</intent-filter>
</receiver>
<receiver android:name=".service.SmsDeliveryListener"
android:exported="true">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.services.MESSAGE_SENT"/>
</intent-filter>
</receiver>
<receiver android:name=".service.MmsListener"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BROADCAST_WAP_PUSH">
<intent-filter android:priority="1001">
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED"/>
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER"/>
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
</receiver>
<receiver android:name=".notifications.MarkReadReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.notifications.CLEAR"/>
</intent-filter>
</receiver>
<receiver android:name=".notifications.RemoteReplyReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.notifications.WEAR_REPLY"/>
</intent-filter>
</receiver>
<receiver android:name=".notifications.AndroidAutoHeardReceiver"
android:exported="false">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.notifications.ANDROID_AUTO_HEARD"/>
</intent-filter>
</receiver>
<receiver android:name=".notifications.AndroidAutoReplyReceiver"
android:exported="false">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.notifications.ANDROID_AUTO_REPLY"/>
</intent-filter>
</receiver>
<receiver android:name=".service.ExpirationListener" />
<receiver android:name=".revealable.ViewOnceMessageManager$ViewOnceAlarm" />
<provider android:name=".providers.PartProvider"
android:grantUriPermissions="true"
android:exported="false"
android:authorities="org.thoughtcrime.provider.securesms" />
<provider android:name=".providers.MmsBodyProvider"
android:grantUriPermissions="true"
android:exported="false"
android:authorities="org.thoughtcrime.provider.securesms.mms" />
<provider android:name="androidx.core.content.FileProvider"
android:authorities="org.thoughtcrime.securesms.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_provider_paths" />
</provider>
<provider android:name=".database.DatabaseContentProviders$Conversation"
android:authorities="org.thoughtcrime.securesms.database.conversation"
android:exported="false" />
<provider android:name=".database.DatabaseContentProviders$ConversationList"
android:authorities="org.thoughtcrime.securesms.database.conversationlist"
android:exported="false" />
<provider android:name=".database.DatabaseContentProviders$Attachment"
android:authorities="org.thoughtcrime.securesms.database.attachment"
android:exported="false" />
<provider android:name=".database.DatabaseContentProviders$Sticker"
android:authorities="org.thoughtcrime.securesms.database.sticker"
android:exported="false" />
<provider android:name=".database.DatabaseContentProviders$StickerPack"
android:authorities="org.thoughtcrime.securesms.database.stickerpack"
android:exported="false" />
<receiver android:name=".service.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="org.thoughtcrime.securesms.RESTART"/>
</intent-filter>
</receiver>
<receiver android:name=".service.DirectoryRefreshListener">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".service.RotateSignedPreKeyListener">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".service.RotateSenderCertificateListener">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".service.LocalBackupListener">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".service.PersistentConnectionBootListener">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<receiver android:name=".notifications.LocaleChangedReceiver">
<intent-filter>
<action android:name="android.intent.action.LOCALE_CHANGED"/>
</intent-filter>
</receiver>
<receiver android:name=".notifications.MessageNotifier$ReminderReceiver">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.MessageNotifier.REMINDER_ACTION"/>
</intent-filter>
</receiver>
<receiver android:name=".notifications.DeleteNotificationReceiver">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.DELETE_NOTIFICATION"/>
</intent-filter>
</receiver>
<receiver
android:name=".service.PanicResponderListener"
android:exported="true">
<intent-filter>
<action android:name="info.guardianproject.panic.action.TRIGGER" />
</intent-filter>
</receiver>
<service
android:name=".gcm.FcmJobService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:enabled="@bool/enable_job_service"
tools:targetApi="26" />
<service
android:name=".jobmanager.JobSchedulerScheduler$SystemService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:enabled="@bool/enable_job_service"
tools:targetApi="26" />
<service
android:name=".jobmanager.KeepAliveService"
android:enabled="@bool/enable_alarm_manager" />
<receiver
android:name=".jobmanager.AlarmManagerScheduler$RetryReceiver"
android:enabled="@bool/enable_alarm_manager" />
<!-- Probably don't need this one -->
<receiver
android:name=".jobmanager.BootReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
<uses-library android:name="com.sec.android.app.multiwindow" android:required="false"/>
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_W" android:value="632.0dip" />
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_H" android:value="598.0dip" />
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_W" android:value="632.0dip" />
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_H" android:value="598.0dip" />
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

View File

@@ -0,0 +1,20 @@
package org.thoughtcrime.securesms;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
public final class AppCapabilities {
private AppCapabilities() {
}
private static final boolean UUID_CAPABLE = false;
/**
* @param storageCapable Whether or not the user can use storage service. This is another way of
* asking if the user has set a Signal PIN or not.
*/
public static SignalServiceProfile.Capabilities getCapabilities(boolean storageCapable) {
return new SignalServiceProfile.Capabilities(UUID_CAPABLE, FeatureFlags.groupsV2(), storageCapable);
}
}

View File

@@ -0,0 +1,55 @@
package org.thoughtcrime.securesms;
import android.content.Context;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.insights.InsightsOptOut;
import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.migrations.ApplicationMigrations;
import org.thoughtcrime.securesms.stickers.BlessedPacks;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
/**
* Rule of thumb: if there's something you want to do on the first app launch that involves
* persisting state to the database, you'll almost certainly *also* want to do it post backup
* restore, since a backup restore will wipe the current state of the database.
*/
public final class AppInitialization {
private static final String TAG = Log.tag(AppInitialization.class);
private AppInitialization() {}
public static void onFirstEverAppLaunch(@NonNull Context context) {
Log.i(TAG, "onFirstEverAppLaunch()");
InsightsOptOut.userRequestedOptOut(context);
TextSecurePreferences.setAppMigrationVersion(context, ApplicationMigrations.CURRENT_VERSION);
TextSecurePreferences.setJobManagerVersion(context, JobManager.CURRENT_VERSION);
TextSecurePreferences.setLastExperienceVersionCode(context, Util.getCanonicalVersionCode());
TextSecurePreferences.setHasSeenStickerIntroTooltip(context, true);
ApplicationDependencies.getMegaphoneRepository().onFirstEverAppLaunch();
SignalStore.onFirstEverAppLaunch();
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forInstall(BlessedPacks.ZOZO.getPackId(), BlessedPacks.ZOZO.getPackKey(), false));
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forInstall(BlessedPacks.BANDIT.getPackId(), BlessedPacks.BANDIT.getPackKey(), false));
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forReference(BlessedPacks.SWOON_HANDS.getPackId(), BlessedPacks.SWOON_HANDS.getPackKey()));
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forReference(BlessedPacks.SWOON_FACES.getPackId(), BlessedPacks.SWOON_FACES.getPackKey()));
}
public static void onPostBackupRestore(@NonNull Context context) {
Log.i(TAG, "onPostBackupRestore()");
ApplicationDependencies.getMegaphoneRepository().onFirstEverAppLaunch();
SignalStore.onFirstEverAppLaunch();
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forInstall(BlessedPacks.ZOZO.getPackId(), BlessedPacks.ZOZO.getPackKey(), false));
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forInstall(BlessedPacks.BANDIT.getPackId(), BlessedPacks.BANDIT.getPackKey(), false));
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forReference(BlessedPacks.SWOON_HANDS.getPackId(), BlessedPacks.SWOON_HANDS.getPackKey()));
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forReference(BlessedPacks.SWOON_FACES.getPackId(), BlessedPacks.SWOON_FACES.getPackKey()));
}
}

View File

@@ -0,0 +1,418 @@
/*
* Copyright (C) 2013 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;
import androidx.multidex.MultiDexApplication;
import com.google.android.gms.security.ProviderInstaller;
import org.conscrypt.Conscrypt;
import org.signal.aesgcmprovider.AesGcmProvider;
import org.signal.ringrtc.CallManager;
import org.thoughtcrime.securesms.components.TypingStatusRepository;
import org.thoughtcrime.securesms.components.TypingStatusSender;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencyProvider;
import org.thoughtcrime.securesms.gcm.FcmJobService;
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.FcmRefreshJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob;
import org.thoughtcrime.securesms.logging.AndroidLogger;
import org.thoughtcrime.securesms.logging.CustomSignalProtocolLogger;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.logging.PersistentLogger;
import org.thoughtcrime.securesms.logging.SignalUncaughtExceptionHandler;
import org.thoughtcrime.securesms.messages.InitialMessageRetriever;
import org.thoughtcrime.securesms.migrations.ApplicationMigrations;
import org.thoughtcrime.securesms.notifications.NotificationChannels;
import org.thoughtcrime.securesms.providers.BlobProvider;
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
import org.thoughtcrime.securesms.registration.RegistrationUtil;
import org.thoughtcrime.securesms.revealable.ViewOnceMessageManager;
import org.thoughtcrime.securesms.ringrtc.RingRtcLogger;
import org.thoughtcrime.securesms.service.DirectoryRefreshListener;
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
import org.thoughtcrime.securesms.messages.IncomingMessageObserver;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.service.LocalBackupListener;
import org.thoughtcrime.securesms.service.RotateSenderCertificateListener;
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
import org.thoughtcrime.securesms.service.UpdateApkRefreshListener;
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageContextWrapper;
import org.webrtc.voiceengine.WebRtcAudioManager;
import org.webrtc.voiceengine.WebRtcAudioUtils;
import org.whispersystems.libsignal.logging.SignalProtocolLoggerProvider;
import java.security.Security;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Will be called once when the TextSecure process is created.
*
* We're using this as an insertion point to patch up the Android PRNG disaster,
* to initialize the job manager, and to check for GCM registration freshness.
*
* @author Moxie Marlinspike
*/
public class ApplicationContext extends MultiDexApplication implements DefaultLifecycleObserver {
private static final String TAG = ApplicationContext.class.getSimpleName();
private ExpiringMessageManager expiringMessageManager;
private ViewOnceMessageManager viewOnceMessageManager;
private TypingStatusRepository typingStatusRepository;
private TypingStatusSender typingStatusSender;
private IncomingMessageObserver incomingMessageObserver;
private PersistentLogger persistentLogger;
private volatile boolean isAppVisible;
public static ApplicationContext getInstance(Context context) {
return (ApplicationContext)context.getApplicationContext();
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate()");
initializeSecurityProvider();
initializeLogging();
initializeCrashHandling();
initializeAppDependencies();
initializeFirstEverAppLaunch();
initializeApplicationMigrations();
initializeMessageRetrieval();
initializeExpiringMessageManager();
initializeRevealableMessageManager();
initializeTypingStatusRepository();
initializeTypingStatusSender();
initializeGcmCheck();
initializeSignedPreKeyCheck();
initializePeriodicTasks();
initializeCircumvention();
initializeRingRtc();
initializePendingMessages();
initializeBlobProvider();
initializeCleanup();
FeatureFlags.init();
NotificationChannels.create(this);
RefreshPreKeysJob.scheduleIfNecessary();
StorageSyncHelper.scheduleRoutineSync();
RegistrationUtil.markRegistrationPossiblyComplete();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
if (Build.VERSION.SDK_INT < 21) {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
ApplicationDependencies.getJobManager().beginJobLoop();
}
@Override
public void onStart(@NonNull LifecycleOwner owner) {
isAppVisible = true;
Log.i(TAG, "App is now visible.");
FeatureFlags.refreshIfNecessary();
ApplicationDependencies.getRecipientCache().warmUp();
executePendingContactSync();
KeyCachingService.onAppForegrounded(this);
ApplicationDependencies.getFrameRateTracker().begin();
ApplicationDependencies.getMegaphoneRepository().onAppForegrounded();
catchUpOnMessages();
}
@Override
public void onStop(@NonNull LifecycleOwner owner) {
isAppVisible = false;
Log.i(TAG, "App is no longer visible.");
KeyCachingService.onAppBackgrounded(this);
ApplicationDependencies.getMessageNotifier().clearVisibleThread();
ApplicationDependencies.getFrameRateTracker().end();
}
public ExpiringMessageManager getExpiringMessageManager() {
return expiringMessageManager;
}
public ViewOnceMessageManager getViewOnceMessageManager() {
return viewOnceMessageManager;
}
public TypingStatusRepository getTypingStatusRepository() {
return typingStatusRepository;
}
public TypingStatusSender getTypingStatusSender() {
return typingStatusSender;
}
public boolean isAppVisible() {
return isAppVisible;
}
public PersistentLogger getPersistentLogger() {
return persistentLogger;
}
private void initializeSecurityProvider() {
try {
Class.forName("org.signal.aesgcmprovider.AesGcmCipher");
} catch (ClassNotFoundException e) {
Log.e(TAG, "Failed to find AesGcmCipher class");
throw new ProviderInitializationException();
}
int aesPosition = Security.insertProviderAt(new AesGcmProvider(), 1);
Log.i(TAG, "Installed AesGcmProvider: " + aesPosition);
if (aesPosition < 0) {
Log.e(TAG, "Failed to install AesGcmProvider()");
throw new ProviderInitializationException();
}
int conscryptPosition = Security.insertProviderAt(Conscrypt.newProvider(), 2);
Log.i(TAG, "Installed Conscrypt provider: " + conscryptPosition);
if (conscryptPosition < 0) {
Log.w(TAG, "Did not install Conscrypt provider. May already be present.");
}
}
private void initializeLogging() {
persistentLogger = new PersistentLogger(this);
org.thoughtcrime.securesms.logging.Log.initialize(new AndroidLogger(), persistentLogger);
SignalProtocolLoggerProvider.setProvider(new CustomSignalProtocolLogger());
}
private void initializeCrashHandling() {
final Thread.UncaughtExceptionHandler originalHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new SignalUncaughtExceptionHandler(originalHandler));
}
private void initializeApplicationMigrations() {
ApplicationMigrations.onApplicationCreate(this, ApplicationDependencies.getJobManager());
}
public void initializeMessageRetrieval() {
this.incomingMessageObserver = new IncomingMessageObserver(this);
}
private void initializeAppDependencies() {
ApplicationDependencies.init(this, new ApplicationDependencyProvider(this, new SignalServiceNetworkAccess(this)));
}
private void initializeFirstEverAppLaunch() {
if (TextSecurePreferences.getFirstInstallVersion(this) == -1) {
if (!SQLCipherOpenHelper.databaseFileExists(this)) {
Log.i(TAG, "First ever app launch!");
AppInitialization.onFirstEverAppLaunch(this);
}
Log.i(TAG, "Setting first install version to " + BuildConfig.CANONICAL_VERSION_CODE);
TextSecurePreferences.setFirstInstallVersion(this, BuildConfig.CANONICAL_VERSION_CODE);
}
}
private void initializeGcmCheck() {
if (TextSecurePreferences.isPushRegistered(this)) {
long nextSetTime = TextSecurePreferences.getFcmTokenLastSetTime(this) + TimeUnit.HOURS.toMillis(6);
if (TextSecurePreferences.getFcmToken(this) == null || nextSetTime <= System.currentTimeMillis()) {
ApplicationDependencies.getJobManager().add(new FcmRefreshJob());
}
}
}
private void initializeSignedPreKeyCheck() {
if (!TextSecurePreferences.isSignedPreKeyRegistered(this)) {
ApplicationDependencies.getJobManager().add(new CreateSignedPreKeyJob(this));
}
}
private void initializeExpiringMessageManager() {
this.expiringMessageManager = new ExpiringMessageManager(this);
}
private void initializeRevealableMessageManager() {
this.viewOnceMessageManager = new ViewOnceMessageManager(this);
}
private void initializeTypingStatusRepository() {
this.typingStatusRepository = new TypingStatusRepository();
}
private void initializeTypingStatusSender() {
this.typingStatusSender = new TypingStatusSender(this);
}
private void initializePeriodicTasks() {
RotateSignedPreKeyListener.schedule(this);
DirectoryRefreshListener.schedule(this);
LocalBackupListener.schedule(this);
RotateSenderCertificateListener.schedule(this);
if (BuildConfig.PLAY_STORE_DISABLED) {
UpdateApkRefreshListener.schedule(this);
}
}
private void initializeRingRtc() {
try {
Set<String> HARDWARE_AEC_BLACKLIST = new HashSet<String>() {{
add("Pixel");
add("Pixel XL");
add("Moto G5");
add("Moto G (5S) Plus");
add("Moto G4");
add("TA-1053");
add("Mi A1");
add("Mi A2");
add("E5823"); // Sony z5 compact
add("Redmi Note 5");
add("FP2"); // Fairphone FP2
add("MI 5");
}};
Set<String> OPEN_SL_ES_WHITELIST = new HashSet<String>() {{
add("Pixel");
add("Pixel XL");
}};
if (HARDWARE_AEC_BLACKLIST.contains(Build.MODEL)) {
WebRtcAudioUtils.setWebRtcBasedAcousticEchoCanceler(true);
}
if (!OPEN_SL_ES_WHITELIST.contains(Build.MODEL)) {
WebRtcAudioManager.setBlacklistDeviceForOpenSLESUsage(true);
}
CallManager.initialize(this, new RingRtcLogger());
} catch (UnsatisfiedLinkError e) {
throw new AssertionError("Unable to load ringrtc library", e);
}
}
@SuppressLint("StaticFieldLeak")
private void initializeCircumvention() {
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
if (new SignalServiceNetworkAccess(ApplicationContext.this).isCensored(ApplicationContext.this)) {
try {
ProviderInstaller.installIfNeeded(ApplicationContext.this);
} catch (Throwable t) {
Log.w(TAG, t);
}
}
return null;
}
};
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private void executePendingContactSync() {
if (TextSecurePreferences.needsFullContactSync(this)) {
ApplicationDependencies.getJobManager().add(new MultiDeviceContactUpdateJob(true));
}
}
private void initializePendingMessages() {
if (TextSecurePreferences.getNeedsMessagePull(this)) {
Log.i(TAG, "Scheduling a message fetch.");
if (Build.VERSION.SDK_INT >= 26) {
FcmJobService.schedule(this);
} else {
ApplicationDependencies.getJobManager().add(new PushNotificationReceiveJob(this));
}
TextSecurePreferences.setNeedsMessagePull(this, false);
}
}
private void initializeBlobProvider() {
SignalExecutors.BOUNDED.execute(() -> {
BlobProvider.getInstance().onSessionStart(this);
});
}
private void initializeCleanup() {
SignalExecutors.BOUNDED.execute(() -> {
int deleted = DatabaseFactory.getAttachmentDatabase(this).deleteAbandonedPreuploadedAttachments();
Log.i(TAG, "Deleted " + deleted + " abandoned attachments.");
});
}
private void catchUpOnMessages() {
InitialMessageRetriever retriever = ApplicationDependencies.getInitialMessageRetriever();
if (retriever.isCaughtUp()) {
return;
}
SignalExecutors.UNBOUNDED.execute(() -> {
long startTime = System.currentTimeMillis();
switch (retriever.begin(TimeUnit.SECONDS.toMillis(60))) {
case SUCCESS:
Log.i(TAG, "Successfully caught up on messages. " + (System.currentTimeMillis() - startTime) + " ms");
break;
case FAILURE_TIMEOUT:
Log.w(TAG, "Did not finish catching up due to a timeout. " + (System.currentTimeMillis() - startTime) + " ms");
break;
case FAILURE_ERROR:
Log.w(TAG, "Did not finish catching up due to an error. " + (System.currentTimeMillis() - startTime) + " ms");
break;
case SKIPPED_ALREADY_CAUGHT_UP:
Log.i(TAG, "Already caught up. " + (System.currentTimeMillis() - startTime) + " ms");
break;
case SKIPPED_ALREADY_RUNNING:
Log.i(TAG, "Already in the process of catching up. " + (System.currentTimeMillis() - startTime) + " ms");
break;
}
});
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(DynamicLanguageContextWrapper.updateContext(base, TextSecurePreferences.getLanguage(base)));
}
private static class ProviderInitializationException extends RuntimeException {
}
}

View File

@@ -0,0 +1,286 @@
/*
* Copyright (C) 2011 Whisper Systems
* Copyright (C) 2013-2017 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.PorterDuff;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.Preference;
import org.thoughtcrime.securesms.help.HelpFragment;
import org.thoughtcrime.securesms.preferences.AdvancedPreferenceFragment;
import org.thoughtcrime.securesms.preferences.AppProtectionPreferenceFragment;
import org.thoughtcrime.securesms.preferences.AppearancePreferenceFragment;
import org.thoughtcrime.securesms.preferences.ChatsPreferenceFragment;
import org.thoughtcrime.securesms.preferences.CorrectedPreferenceFragment;
import org.thoughtcrime.securesms.preferences.NotificationsPreferenceFragment;
import org.thoughtcrime.securesms.preferences.SmsMmsPreferenceFragment;
import org.thoughtcrime.securesms.preferences.StoragePreferenceFragment;
import org.thoughtcrime.securesms.preferences.widgets.ProfilePreference;
import org.thoughtcrime.securesms.profiles.edit.EditProfileActivity;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.ThemeUtil;
/**
* The Activity for application preference display and management.
*
* @author Moxie Marlinspike
*
*/
public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarActivity
implements SharedPreferences.OnSharedPreferenceChangeListener
{
@SuppressWarnings("unused")
private static final String TAG = ApplicationPreferencesActivity.class.getSimpleName();
private static final String PREFERENCE_CATEGORY_PROFILE = "preference_category_profile";
private static final String PREFERENCE_CATEGORY_SMS_MMS = "preference_category_sms_mms";
private static final String PREFERENCE_CATEGORY_NOTIFICATIONS = "preference_category_notifications";
private static final String PREFERENCE_CATEGORY_APP_PROTECTION = "preference_category_app_protection";
private static final String PREFERENCE_CATEGORY_APPEARANCE = "preference_category_appearance";
private static final String PREFERENCE_CATEGORY_CHATS = "preference_category_chats";
private static final String PREFERENCE_CATEGORY_STORAGE = "preference_category_storage";
private static final String PREFERENCE_CATEGORY_DEVICES = "preference_category_devices";
private static final String PREFERENCE_CATEGORY_HELP = "preference_category_help";
private static final String PREFERENCE_CATEGORY_ADVANCED = "preference_category_advanced";
private final DynamicTheme dynamicTheme = new DynamicTheme();
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
@Override
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
}
@Override
protected void onCreate(Bundle icicle, boolean ready) {
//noinspection ConstantConditions
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (getIntent() != null && getIntent().getCategories() != null && getIntent().getCategories().contains("android.intent.category.NOTIFICATION_PREFERENCES")) {
initFragment(android.R.id.content, new NotificationsPreferenceFragment());
} else if (icicle == null) {
initFragment(android.R.id.content, new ApplicationPreferenceFragment());
}
}
@Override
public void onResume() {
super.onResume();
dynamicTheme.onResume(this);
dynamicLanguage.onResume(this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
Fragment fragment = getSupportFragmentManager().findFragmentById(android.R.id.content);
fragment.onActivityResult(requestCode, resultCode, data);
}
@Override
public boolean onSupportNavigateUp() {
FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 0) {
fragmentManager.popBackStack();
} else {
// TODO [greyson] Navigation
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
return true;
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(TextSecurePreferences.THEME_PREF)) {
recreate();
} else if (key.equals(TextSecurePreferences.LANGUAGE_PREF)) {
recreate();
Intent intent = new Intent(this, KeyCachingService.class);
intent.setAction(KeyCachingService.LOCALE_CHANGE_EVENT);
startService(intent);
}
}
public static class ApplicationPreferenceFragment extends CorrectedPreferenceFragment {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
this.findPreference(PREFERENCE_CATEGORY_PROFILE)
.setOnPreferenceClickListener(new ProfileClickListener());
this.findPreference(PREFERENCE_CATEGORY_SMS_MMS)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_SMS_MMS));
this.findPreference(PREFERENCE_CATEGORY_NOTIFICATIONS)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_NOTIFICATIONS));
this.findPreference(PREFERENCE_CATEGORY_APP_PROTECTION)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_APP_PROTECTION));
this.findPreference(PREFERENCE_CATEGORY_APPEARANCE)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_APPEARANCE));
this.findPreference(PREFERENCE_CATEGORY_CHATS)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_CHATS));
this.findPreference(PREFERENCE_CATEGORY_STORAGE)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_STORAGE));
this.findPreference(PREFERENCE_CATEGORY_DEVICES)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_DEVICES));
this.findPreference(PREFERENCE_CATEGORY_HELP)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_HELP));
this.findPreference(PREFERENCE_CATEGORY_ADVANCED)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_ADVANCED));
tintIcons();
}
private void tintIcons() {
if (Build.VERSION.SDK_INT >= 21) return;
Preference preference = this.findPreference(PREFERENCE_CATEGORY_SMS_MMS);
preference.getIcon().setColorFilter(ThemeUtil.getThemedColor(requireContext(), R.attr.icon_tint), PorterDuff.Mode.SRC_IN);
}
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences);
}
@Override
public void onResume() {
super.onResume();
//noinspection ConstantConditions
((ApplicationPreferencesActivity) getActivity()).getSupportActionBar().setTitle(R.string.text_secure_normal__menu_settings);
setCategorySummaries();
setCategoryVisibility();
}
private void setCategorySummaries() {
((ProfilePreference)this.findPreference(PREFERENCE_CATEGORY_PROFILE)).refresh();
this.findPreference(PREFERENCE_CATEGORY_SMS_MMS)
.setSummary(SmsMmsPreferenceFragment.getSummary(getActivity()));
this.findPreference(PREFERENCE_CATEGORY_NOTIFICATIONS)
.setSummary(NotificationsPreferenceFragment.getSummary(getActivity()));
this.findPreference(PREFERENCE_CATEGORY_APP_PROTECTION)
.setSummary(AppProtectionPreferenceFragment.getSummary(getActivity()));
this.findPreference(PREFERENCE_CATEGORY_APPEARANCE)
.setSummary(AppearancePreferenceFragment.getSummary(getActivity()));
this.findPreference(PREFERENCE_CATEGORY_CHATS)
.setSummary(ChatsPreferenceFragment.getSummary(getActivity()));
}
private void setCategoryVisibility() {
Preference devicePreference = this.findPreference(PREFERENCE_CATEGORY_DEVICES);
if (devicePreference != null && !TextSecurePreferences.isPushRegistered(getActivity())) {
getPreferenceScreen().removePreference(devicePreference);
}
}
private class CategoryClickListener implements Preference.OnPreferenceClickListener {
private String category;
CategoryClickListener(String category) {
this.category = category;
}
@Override
public boolean onPreferenceClick(Preference preference) {
Fragment fragment = null;
switch (category) {
case PREFERENCE_CATEGORY_SMS_MMS:
fragment = new SmsMmsPreferenceFragment();
break;
case PREFERENCE_CATEGORY_NOTIFICATIONS:
fragment = new NotificationsPreferenceFragment();
break;
case PREFERENCE_CATEGORY_APP_PROTECTION:
fragment = new AppProtectionPreferenceFragment();
break;
case PREFERENCE_CATEGORY_APPEARANCE:
fragment = new AppearancePreferenceFragment();
break;
case PREFERENCE_CATEGORY_CHATS:
fragment = new ChatsPreferenceFragment();
break;
case PREFERENCE_CATEGORY_STORAGE:
fragment = new StoragePreferenceFragment();
break;
case PREFERENCE_CATEGORY_DEVICES:
Intent intent = new Intent(getActivity(), DeviceActivity.class);
startActivity(intent);
break;
case PREFERENCE_CATEGORY_ADVANCED:
fragment = new AdvancedPreferenceFragment();
break;
case PREFERENCE_CATEGORY_HELP:
fragment = new HelpFragment();
break;
default:
throw new AssertionError();
}
if (fragment != null) {
Bundle args = new Bundle();
fragment.setArguments(args);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.slide_from_end, R.anim.slide_to_start, R.anim.slide_from_start, R.anim.slide_to_end);
fragmentTransaction.replace(android.R.id.content, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
return true;
}
}
private class ProfileClickListener implements Preference.OnPreferenceClickListener {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent(preference.getContext(), EditProfileActivity.class);
intent.putExtra(EditProfileActivity.EXCLUDE_SYSTEM, true);
intent.putExtra(EditProfileActivity.DISPLAY_USERNAME, true);
intent.putExtra(EditProfileActivity.NEXT_BUTTON_TEXT, R.string.save);
requireActivity().startActivity(intent);
return true;
}
}
}
}

View File

@@ -0,0 +1,152 @@
package org.thoughtcrime.securesms;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityOptionsCompat;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto;
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
/**
* Activity for displaying avatars full screen.
*/
public final class AvatarPreviewActivity extends PassphraseRequiredActionBarActivity {
private static final String TAG = Log.tag(AvatarPreviewActivity.class);
private static final String RECIPIENT_ID_EXTRA = "recipient_id";
public static @NonNull Intent intentFromRecipientId(@NonNull Context context,
@NonNull RecipientId recipientId)
{
Intent intent = new Intent(context, AvatarPreviewActivity.class);
intent.putExtra(RECIPIENT_ID_EXTRA, recipientId.serialize());
return intent;
}
public static Bundle createTransitionBundle(@NonNull Activity activity, @NonNull View from) {
return ActivityOptionsCompat.makeSceneTransitionAnimation(activity, from, "avatar").toBundle();
}
@Override
protected void onCreate(Bundle savedInstanceState, boolean ready) {
super.onCreate(savedInstanceState, ready);
setTheme(R.style.TextSecure_MediaPreview);
setContentView(R.layout.contact_photo_preview_activity);
Toolbar toolbar = findViewById(R.id.toolbar);
ImageView avatar = findViewById(R.id.avatar);
setSupportActionBar(toolbar);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
showSystemUI();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Context context = getApplicationContext();
RecipientId recipientId = RecipientId.from(getIntent().getStringExtra(RECIPIENT_ID_EXTRA));
Recipient.live(recipientId).observe(this, recipient -> {
ContactPhoto contactPhoto = recipient.isLocalNumber() ? new ProfileContactPhoto(recipient, recipient.getProfileAvatar())
: recipient.getContactPhoto();
FallbackContactPhoto fallbackPhoto = recipient.isLocalNumber() ? new ResourceContactPhoto(R.drawable.ic_profile_outline_40, R.drawable.ic_profile_outline_20, R.drawable.ic_person_large)
: recipient.getFallbackContactPhoto();
GlideApp.with(this).load(contactPhoto)
.fallback(fallbackPhoto.asCallCard(this))
.error(fallbackPhoto.asCallCard(this))
.diskCacheStrategy(DiskCacheStrategy.ALL)
.addListener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
Log.w(TAG, "Unable to load avatar, or avatar removed, closing");
finish();
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(avatar);
toolbar.setTitle(recipient.toShortString(context));
});
avatar.setOnClickListener(v -> toggleUiVisibility());
showAndHideWithSystemUI(getWindow(), findViewById(R.id.toolbar_layout));
}
private static void showAndHideWithSystemUI(@NonNull Window window, @NonNull View... views) {
window.getDecorView().setOnSystemUiVisibilityChangeListener(visibility -> {
boolean hide = (visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
for (View view : views) {
view.animate()
.alpha(hide ? 0 : 1)
.start();
}
});
}
private void toggleUiVisibility() {
int systemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
if ((systemUiVisibility & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0) {
showSystemUI();
} else {
hideSystemUI();
}
}
private void hideSystemUI() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN );
}
private void showSystemUI() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN );
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}

View File

@@ -1,23 +1,24 @@
package org.thoughtcrime.securesms;
import android.annotation.TargetApi;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageActivityHelper;
import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageContextWrapper;
import java.lang.reflect.Field;
@@ -37,6 +38,7 @@ public abstract class BaseActionBarActivity extends AppCompatActivity {
protected void onResume() {
super.onResume();
initializeScreenshotSecurity();
DynamicLanguageActivityHelper.recreateIfNotInCorrectLanguage(this, TextSecurePreferences.getLanguage(this));
}
@Override
@@ -54,9 +56,7 @@ public abstract class BaseActionBarActivity extends AppCompatActivity {
}
private void initializeScreenshotSecurity() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH &&
TextSecurePreferences.isScreenSecurityEnabled(this))
{
if (TextSecurePreferences.isScreenSecurityEnabled(this)) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
@@ -94,4 +94,8 @@ public abstract class BaseActionBarActivity extends AppCompatActivity {
}
}
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(DynamicLanguageContextWrapper.updateContext(newBase, TextSecurePreferences.getLanguage(newBase)));
}
}

View File

@@ -0,0 +1,46 @@
package org.thoughtcrime.securesms;
import android.content.Context;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import android.view.KeyEvent;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageActivityHelper;
import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageContextWrapper;
public abstract class BaseActivity extends FragmentActivity {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return (keyCode == KeyEvent.KEYCODE_MENU && isMenuWorkaroundRequired()) || super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && isMenuWorkaroundRequired()) {
openOptionsMenu();
return true;
}
return super.onKeyUp(keyCode, event);
}
public static boolean isMenuWorkaroundRequired() {
return VERSION.SDK_INT < VERSION_CODES.KITKAT &&
VERSION.SDK_INT > VERSION_CODES.GINGERBREAD_MR1 &&
("LGE".equalsIgnoreCase(Build.MANUFACTURER) || "E6710".equalsIgnoreCase(Build.DEVICE));
}
@Override
protected void onResume() {
super.onResume();
DynamicLanguageActivityHelper.recreateIfNotInCorrectLanguage(this, TextSecurePreferences.getLanguage(this));
}
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(DynamicLanguageContextWrapper.updateContext(newBase, TextSecurePreferences.getLanguage(newBase)));
}
}

View File

@@ -0,0 +1,51 @@
package org.thoughtcrime.securesms;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.View;
import org.thoughtcrime.securesms.contactshare.Contact;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.ReactionRecord;
import org.thoughtcrime.securesms.groups.GroupId;
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.stickers.StickerLocator;
import org.whispersystems.libsignal.util.guava.Optional;
import java.util.List;
import java.util.Locale;
import java.util.Set;
public interface BindableConversationItem extends Unbindable {
void bind(@NonNull MessageRecord messageRecord,
@NonNull Optional<MessageRecord> previousMessageRecord,
@NonNull Optional<MessageRecord> nextMessageRecord,
@NonNull GlideRequests glideRequests,
@NonNull Locale locale,
@NonNull Set<MessageRecord> batchSelected,
@NonNull Recipient recipients,
@Nullable String searchQuery,
boolean pulseHighlight);
MessageRecord getMessageRecord();
void setEventListener(@Nullable EventListener listener);
interface EventListener {
void onQuoteClicked(MmsMessageRecord messageRecord);
void onLinkPreviewClicked(@NonNull LinkPreview linkPreview);
void onMoreTextClicked(@NonNull RecipientId conversationRecipientId, long messageId, boolean isMms);
void onStickerClicked(@NonNull StickerLocator stickerLocator);
void onViewOnceMessageClicked(@NonNull MmsMessageRecord messageRecord);
void onSharedContactDetailsClicked(@NonNull Contact contact, @NonNull View avatarTransitionView);
void onAddToContactsClicked(@NonNull Contact contact);
void onMessageSharedContactClicked(@NonNull List<Recipient> choices);
void onInviteSharedContactClicked(@NonNull List<Recipient> choices);
void onReactionClicked(long messageId, boolean isMms);
void onGroupMemberAvatarClicked(@NonNull RecipientId recipientId, @NonNull GroupId groupId);
}
}

View File

@@ -0,0 +1,17 @@
package org.thoughtcrime.securesms;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.database.model.ThreadRecord;
import org.thoughtcrime.securesms.mms.GlideRequests;
import java.util.Locale;
import java.util.Set;
public interface BindableConversationListItem extends Unbindable {
void bind(@NonNull ThreadRecord thread,
@NonNull GlideRequests glideRequests, @NonNull Locale locale,
@NonNull Set<Long> typingThreads,
@NonNull Set<Long> selectedThreads, boolean batchMode);
}

View File

@@ -0,0 +1,128 @@
package org.thoughtcrime.securesms;
import android.content.Context;
import android.content.res.Resources;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.Lifecycle;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
/**
* This should be used whenever we want to prompt the user to block/unblock a recipient.
*/
public final class BlockUnblockDialog {
private BlockUnblockDialog() { }
public static void showBlockFor(@NonNull Context context,
@NonNull Lifecycle lifecycle,
@NonNull Recipient recipient,
@NonNull Runnable onBlock)
{
SimpleTask.run(lifecycle,
() -> buildBlockFor(context, recipient, onBlock, null),
AlertDialog.Builder::show);
}
public static void showBlockAndDeleteFor(@NonNull Context context,
@NonNull Lifecycle lifecycle,
@NonNull Recipient recipient,
@NonNull Runnable onBlock,
@NonNull Runnable onBlockAndDelete)
{
SimpleTask.run(lifecycle,
() -> buildBlockFor(context, recipient, onBlock, onBlockAndDelete),
AlertDialog.Builder::show);
}
public static void showUnblockFor(@NonNull Context context,
@NonNull Lifecycle lifecycle,
@NonNull Recipient recipient,
@NonNull Runnable onUnblock)
{
SimpleTask.run(lifecycle,
() -> buildUnblockFor(context, recipient, onUnblock),
AlertDialog.Builder::show);
}
@WorkerThread
private static AlertDialog.Builder buildBlockFor(@NonNull Context context,
@NonNull Recipient recipient,
@NonNull Runnable onBlock,
@Nullable Runnable onBlockAndDelete)
{
recipient = recipient.resolve();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
Resources resources = context.getResources();
if (recipient.isGroup()) {
if (DatabaseFactory.getGroupDatabase(context).isActive(recipient.requireGroupId())) {
builder.setTitle(resources.getString(R.string.BlockUnblockDialog_block_and_leave_s, recipient.getDisplayName(context)));
builder.setMessage(R.string.BlockUnblockDialog_you_will_no_longer_receive_messages_or_updates);
builder.setPositiveButton(R.string.BlockUnblockDialog_block_and_leave, ((dialog, which) -> onBlock.run()));
builder.setNegativeButton(android.R.string.cancel, null);
} else {
builder.setTitle(resources.getString(R.string.BlockUnblockDialog_block_s, recipient.getDisplayName(context)));
builder.setMessage(R.string.BlockUnblockDialog_group_members_wont_be_able_to_add_you);
builder.setPositiveButton(R.string.RecipientPreferenceActivity_block, ((dialog, which) -> onBlock.run()));
builder.setNegativeButton(android.R.string.cancel, null);
}
} else {
builder.setTitle(resources.getString(R.string.BlockUnblockDialog_block_s, recipient.getDisplayName(context)));
builder.setMessage(R.string.BlockUnblockDialog_blocked_people_wont_be_able_to_call_you_or_send_you_messages);
if (onBlockAndDelete != null) {
builder.setNeutralButton(android.R.string.cancel, null);
builder.setPositiveButton(R.string.BlockUnblockDialog_block_and_delete, (d, w) -> onBlockAndDelete.run());
builder.setNegativeButton(R.string.BlockUnblockDialog_block, (d, w) -> onBlock.run());
} else {
builder.setPositiveButton(R.string.BlockUnblockDialog_block, ((dialog, which) -> onBlock.run()));
builder.setNegativeButton(android.R.string.cancel, null);
}
}
return builder;
}
@WorkerThread
private static AlertDialog.Builder buildUnblockFor(@NonNull Context context,
@NonNull Recipient recipient,
@NonNull Runnable onUnblock)
{
recipient = recipient.resolve();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
Resources resources = context.getResources();
if (recipient.isGroup()) {
if (DatabaseFactory.getGroupDatabase(context).isActive(recipient.requireGroupId())) {
builder.setTitle(resources.getString(R.string.BlockUnblockDialog_unblock_s, recipient.getDisplayName(context)));
builder.setMessage(R.string.BlockUnblockDialog_group_members_will_be_able_to_add_you);
builder.setPositiveButton(R.string.RecipientPreferenceActivity_unblock, ((dialog, which) -> onUnblock.run()));
builder.setNegativeButton(android.R.string.cancel, null);
} else {
builder.setTitle(resources.getString(R.string.BlockUnblockDialog_unblock_s, recipient.getDisplayName(context)));
builder.setMessage(R.string.BlockUnblockDialog_group_members_will_be_able_to_add_you);
builder.setPositiveButton(R.string.RecipientPreferenceActivity_unblock, ((dialog, which) -> onUnblock.run()));
builder.setNegativeButton(android.R.string.cancel, null);
}
} else {
builder.setTitle(resources.getString(R.string.BlockUnblockDialog_unblock_s, recipient.getDisplayName(context)));
builder.setMessage(R.string.BlockUnblockDialog_you_will_be_able_to_call_and_message_each_other);
builder.setPositiveButton(R.string.RecipientPreferenceActivity_unblock, ((dialog, which) -> onUnblock.run()));
builder.setNegativeButton(android.R.string.cancel, null);
}
return builder;
}
}

View File

@@ -0,0 +1,140 @@
package org.thoughtcrime.securesms;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.cursoradapter.widget.CursorAdapter;
import androidx.fragment.app.ListFragment;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.loaders.BlockedContactsLoader;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.preferences.BlockedContactListItem;
import org.thoughtcrime.securesms.recipients.LiveRecipient;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.util.DynamicTheme;
public class BlockedContactsActivity extends PassphraseRequiredActionBarActivity {
private final DynamicTheme dynamicTheme = new DynamicTheme();
@Override
public void onPreCreate() {
dynamicTheme.onCreate(this);
}
@Override
public void onCreate(Bundle bundle, boolean ready) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(R.string.BlockedContactsActivity_blocked_contacts);
initFragment(android.R.id.content, new BlockedContactsFragment());
}
@Override
public void onResume() {
super.onResume();
dynamicTheme.onResume(this);
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
public static class BlockedContactsFragment
extends ListFragment
implements LoaderManager.LoaderCallbacks<Cursor>, ListView.OnItemClickListener
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
return inflater.inflate(R.layout.blocked_contacts_fragment, container, false);
}
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setListAdapter(new BlockedContactAdapter(requireActivity(), GlideApp.with(this), null));
LoaderManager.getInstance(this).initLoader(0, null, this);
}
@Override
public void onStart() {
super.onStart();
LoaderManager.getInstance(this).restartLoader(0, null, this);
}
@Override
public void onActivityCreated(Bundle bundle) {
super.onActivityCreated(bundle);
getListView().setOnItemClickListener(this);
}
@Override
public @NonNull Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new BlockedContactsLoader(getActivity());
}
@Override
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
if (getListAdapter() != null) {
((CursorAdapter) getListAdapter()).changeCursor(data);
}
}
@Override
public void onLoaderReset(@NonNull Loader<Cursor> loader) {
if (getListAdapter() != null) {
((CursorAdapter) getListAdapter()).changeCursor(null);
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Recipient recipient = ((BlockedContactListItem)view).getRecipient();
BlockUnblockDialog.showUnblockFor(requireContext(), getLifecycle(), recipient, () -> {
RecipientUtil.unblock(requireContext(), recipient);
LoaderManager.getInstance(this).restartLoader(0, null, this);
});
}
private static class BlockedContactAdapter extends CursorAdapter {
private final GlideRequests glideRequests;
BlockedContactAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests, @Nullable Cursor c) {
super(context, c);
this.glideRequests = glideRequests;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context)
.inflate(R.layout.blocked_contact_list_item, parent, false);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
RecipientId recipientId = RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(RecipientDatabase.ID)));
LiveRecipient recipient = Recipient.live(recipientId);
((BlockedContactListItem) view).set(glideRequests, recipient);
}
}
}
}

View File

@@ -0,0 +1,49 @@
package org.thoughtcrime.securesms;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextThemeWrapper;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.ThemeUtil;
public class ClearProfileAvatarActivity extends Activity {
private static final String ARG_TITLE = "arg_title";
public static Intent createForUserProfilePhoto() {
return new Intent("org.thoughtcrime.securesms.action.CLEAR_PROFILE_PHOTO");
}
public static Intent createForGroupProfilePhoto() {
Intent intent = new Intent("org.thoughtcrime.securesms.action.CLEAR_PROFILE_PHOTO");
intent.putExtra(ARG_TITLE, R.string.ClearProfileActivity_remove_group_photo);
return intent;
}
@Override
public void onResume() {
super.onResume();
int titleId = getIntent().getIntExtra(ARG_TITLE, R.string.ClearProfileActivity_remove_profile_photo);
new AlertDialog.Builder(new ContextThemeWrapper(this, DynamicTheme.isDarkTheme(this) ? R.style.TextSecure_DarkTheme : R.style.TextSecure_LightTheme))
.setMessage(titleId)
.setNegativeButton(android.R.string.cancel, (dialog, which) -> finish())
.setPositiveButton(R.string.ClearProfileActivity_remove, (dialog, which) -> {
Intent result = new Intent();
result.putExtra("delete", true);
setResult(Activity.RESULT_OK, result);
finish();
})
.setOnCancelListener(dialog -> finish())
.show();
}
}

View File

@@ -0,0 +1,201 @@
package org.thoughtcrime.securesms;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.os.AsyncTask;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
import org.thoughtcrime.securesms.database.PushDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobs.PushDecryptMessageJob;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.VerifySpan;
import org.whispersystems.libsignal.SignalProtocolAddress;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import java.io.IOException;
import static org.whispersystems.libsignal.SessionCipher.SESSION_LOCK;
public class ConfirmIdentityDialog extends AlertDialog {
@SuppressWarnings("unused")
private static final String TAG = ConfirmIdentityDialog.class.getSimpleName();
private OnClickListener callback;
public ConfirmIdentityDialog(Context context,
MessageRecord messageRecord,
IdentityKeyMismatch mismatch)
{
super(context);
Recipient recipient = Recipient.resolved(mismatch.getRecipientId(context));
String name = recipient.toShortString(context);
String introduction = context.getString(R.string.ConfirmIdentityDialog_your_safety_number_with_s_has_changed, name, name);
SpannableString spannableString = new SpannableString(introduction + " " +
context.getString(R.string.ConfirmIdentityDialog_you_may_wish_to_verify_your_safety_number_with_this_contact));
spannableString.setSpan(new VerifySpan(context, mismatch),
introduction.length()+1, spannableString.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
setTitle(name);
setMessage(spannableString);
setButton(AlertDialog.BUTTON_POSITIVE, context.getString(R.string.ConfirmIdentityDialog_accept), new AcceptListener(messageRecord, mismatch, recipient.getId()));
setButton(AlertDialog.BUTTON_NEGATIVE, context.getString(android.R.string.cancel), new CancelListener());
}
@Override
public void show() {
super.show();
((TextView)this.findViewById(android.R.id.message))
.setMovementMethod(LinkMovementMethod.getInstance());
}
public void setCallback(OnClickListener callback) {
this.callback = callback;
}
private class AcceptListener implements OnClickListener {
private final MessageRecord messageRecord;
private final IdentityKeyMismatch mismatch;
private final RecipientId recipientId;
private AcceptListener(MessageRecord messageRecord, IdentityKeyMismatch mismatch, RecipientId recipientId) {
this.messageRecord = messageRecord;
this.mismatch = mismatch;
this.recipientId = recipientId;
}
@SuppressLint("StaticFieldLeak")
@Override
public void onClick(DialogInterface dialog, int which) {
new AsyncTask<Void, Void, Void>()
{
@Override
protected Void doInBackground(Void... params) {
synchronized (SESSION_LOCK) {
SignalProtocolAddress mismatchAddress = new SignalProtocolAddress(Recipient.resolved(recipientId).requireServiceId(), 1);
TextSecureIdentityKeyStore identityKeyStore = new TextSecureIdentityKeyStore(getContext());
identityKeyStore.saveIdentity(mismatchAddress, mismatch.getIdentityKey(), true);
}
processMessageRecord(messageRecord);
processPendingMessageRecords(messageRecord.getThreadId(), mismatch);
return null;
}
private void processMessageRecord(MessageRecord messageRecord) {
if (messageRecord.isOutgoing()) processOutgoingMessageRecord(messageRecord);
else processIncomingMessageRecord(messageRecord);
}
private void processPendingMessageRecords(long threadId, IdentityKeyMismatch mismatch) {
MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(getContext());
Cursor cursor = mmsSmsDatabase.getIdentityConflictMessagesForThread(threadId);
MmsSmsDatabase.Reader reader = mmsSmsDatabase.readerFor(cursor);
MessageRecord record;
try {
while ((record = reader.getNext()) != null) {
for (IdentityKeyMismatch recordMismatch : record.getIdentityKeyMismatches()) {
if (mismatch.equals(recordMismatch)) {
processMessageRecord(record);
}
}
}
} finally {
if (reader != null)
reader.close();
}
}
private void processOutgoingMessageRecord(MessageRecord messageRecord) {
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(getContext());
MmsDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(getContext());
if (messageRecord.isMms()) {
mmsDatabase.removeMismatchedIdentity(messageRecord.getId(),
mismatch.getRecipientId(getContext()),
mismatch.getIdentityKey());
if (messageRecord.getRecipient().isPushGroup()) {
MessageSender.resendGroupMessage(getContext(), messageRecord, Recipient.resolved(mismatch.getRecipientId(getContext())).getId());
} else {
MessageSender.resend(getContext(), messageRecord);
}
} else {
smsDatabase.removeMismatchedIdentity(messageRecord.getId(),
mismatch.getRecipientId(getContext()),
mismatch.getIdentityKey());
MessageSender.resend(getContext(), messageRecord);
}
}
private void processIncomingMessageRecord(MessageRecord messageRecord) {
try {
PushDatabase pushDatabase = DatabaseFactory.getPushDatabase(getContext());
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(getContext());
smsDatabase.removeMismatchedIdentity(messageRecord.getId(),
mismatch.getRecipientId(getContext()),
mismatch.getIdentityKey());
boolean legacy = !messageRecord.isContentBundleKeyExchange();
SignalServiceEnvelope envelope = new SignalServiceEnvelope(SignalServiceProtos.Envelope.Type.PREKEY_BUNDLE_VALUE,
Optional.of(RecipientUtil.toSignalServiceAddress(getContext(), messageRecord.getIndividualRecipient())),
messageRecord.getRecipientDeviceId(),
messageRecord.getDateSent(),
legacy ? Base64.decode(messageRecord.getBody()) : null,
!legacy ? Base64.decode(messageRecord.getBody()) : null,
0, null);
long pushId = pushDatabase.insert(envelope);
ApplicationDependencies.getJobManager().add(new PushDecryptMessageJob(getContext(), pushId, messageRecord.getId()));
} catch (IOException e) {
throw new AssertionError(e);
}
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if (callback != null) callback.onClick(null, 0);
}
}
private class CancelListener implements OnClickListener {
@Override
public void onClick(DialogInterface dialog, int which) {
if (callback != null) callback.onClick(null, 0);
}
}
}

View File

@@ -0,0 +1,161 @@
/*
* Copyright (C) 2015 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.thoughtcrime.securesms.components.ContactFilterToolbar;
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode;
import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.util.guava.Optional;
import java.io.IOException;
import java.lang.ref.WeakReference;
/**
* Base activity container for selecting a list of contacts.
*
* @author Moxie Marlinspike
*
*/
public abstract class ContactSelectionActivity extends PassphraseRequiredActionBarActivity
implements SwipeRefreshLayout.OnRefreshListener,
ContactSelectionListFragment.OnContactSelectedListener,
ContactSelectionListFragment.ScrollCallback
{
private static final String TAG = ContactSelectionActivity.class.getSimpleName();
public static final String EXTRA_LAYOUT_RES_ID = "layout_res_id";
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
protected ContactSelectionListFragment contactsFragment;
private ContactFilterToolbar toolbar;
@Override
protected void onPreCreate() {
dynamicTheme.onCreate(this);
}
@Override
protected void onCreate(Bundle icicle, boolean ready) {
if (!getIntent().hasExtra(ContactSelectionListFragment.DISPLAY_MODE)) {
int displayMode = TextSecurePreferences.isSmsEnabled(this) ? DisplayMode.FLAG_ALL
: DisplayMode.FLAG_PUSH | DisplayMode.FLAG_ACTIVE_GROUPS | DisplayMode.FLAG_INACTIVE_GROUPS | DisplayMode.FLAG_SELF;
getIntent().putExtra(ContactSelectionListFragment.DISPLAY_MODE, displayMode);
}
setContentView(getIntent().getIntExtra(EXTRA_LAYOUT_RES_ID, R.layout.contact_selection_activity));
initializeToolbar();
initializeResources();
initializeSearch();
}
@Override
public void onResume() {
super.onResume();
dynamicTheme.onResume(this);
}
protected ContactFilterToolbar getToolbar() {
return toolbar;
}
private void initializeToolbar() {
this.toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setIcon(null);
getSupportActionBar().setLogo(null);
}
private void initializeResources() {
contactsFragment = (ContactSelectionListFragment) getSupportFragmentManager().findFragmentById(R.id.contact_selection_list_fragment);
contactsFragment.setOnContactSelectedListener(this);
contactsFragment.setOnRefreshListener(this);
}
private void initializeSearch() {
toolbar.setOnFilterChangedListener(filter -> contactsFragment.setQueryFilter(filter));
}
@Override
public void onRefresh() {
new RefreshDirectoryTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getApplicationContext());
}
@Override
public void onContactSelected(Optional<RecipientId> recipientId, String number) {}
@Override
public void onContactDeselected(Optional<RecipientId> recipientId, String number) {}
@Override
public void onBeginScroll() {
hideKeyboard();
}
private void hideKeyboard() {
ServiceUtil.getInputMethodManager(this)
.hideSoftInputFromWindow(toolbar.getWindowToken(), 0);
toolbar.clearFocus();
}
private static class RefreshDirectoryTask extends AsyncTask<Context, Void, Void> {
private final WeakReference<ContactSelectionActivity> activity;
private RefreshDirectoryTask(ContactSelectionActivity activity) {
this.activity = new WeakReference<>(activity);
}
@Override
protected Void doInBackground(Context... params) {
try {
DirectoryHelper.refreshDirectory(params[0], true);
} catch (IOException e) {
Log.w(TAG, e);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
ContactSelectionActivity activity = this.activity.get();
if (activity != null && !activity.isFinishing()) {
activity.toolbar.clear();
activity.contactsFragment.resetQueryFilter();
}
}
}
}

View File

@@ -0,0 +1,646 @@
/*
* Copyright (C) 2015 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms;
import android.Manifest;
import android.animation.LayoutTransition;
import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.CycleInterpolator;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.transition.AutoTransition;
import androidx.transition.TransitionManager;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import com.google.android.material.chip.ChipGroup;
import com.pnikosis.materialishprogress.ProgressWheel;
import org.thoughtcrime.securesms.components.RecyclerViewFastScroller;
import org.thoughtcrime.securesms.contacts.ContactChip;
import org.thoughtcrime.securesms.contacts.ContactSelectionListAdapter;
import org.thoughtcrime.securesms.contacts.ContactSelectionListItem;
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader;
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode;
import org.thoughtcrime.securesms.contacts.SelectedContact;
import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.recipients.LiveRecipient;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.UsernameUtil;
import org.thoughtcrime.securesms.util.adapter.FixedViewsAdapter;
import org.thoughtcrime.securesms.util.adapter.RecyclerViewConcatenateAdapterStickyHeader;
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
import org.whispersystems.libsignal.util.guava.Optional;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
/**
* Fragment for selecting a one or more contacts from a list.
*
* @author Moxie Marlinspike
*
*/
public final class ContactSelectionListFragment extends Fragment
implements LoaderManager.LoaderCallbacks<Cursor>
{
@SuppressWarnings("unused")
private static final String TAG = Log.tag(ContactSelectionListFragment.class);
private static final int CHIP_GROUP_EMPTY_CHILD_COUNT = 1;
private static final int CHIP_GROUP_REVEAL_DURATION_MS = 150;
public static final int NO_LIMIT = Integer.MAX_VALUE;
public static final String DISPLAY_MODE = "display_mode";
public static final String MULTI_SELECT = "multi_select";
public static final String REFRESHABLE = "refreshable";
public static final String RECENTS = "recents";
public static final String TOTAL_CAPACITY = "total_capacity";
public static final String CURRENT_SELECTION = "current_selection";
private ConstraintLayout constraintLayout;
private TextView emptyText;
private OnContactSelectedListener onContactSelectedListener;
private SwipeRefreshLayout swipeRefresh;
private View showContactsLayout;
private Button showContactsButton;
private TextView showContactsDescription;
private ProgressWheel showContactsProgress;
private String cursorFilter;
private RecyclerView recyclerView;
private RecyclerViewFastScroller fastScroller;
private ContactSelectionListAdapter cursorRecyclerViewAdapter;
private ChipGroup chipGroup;
private HorizontalScrollView chipGroupScrollContainer;
private TextView groupLimit;
@Nullable private FixedViewsAdapter headerAdapter;
@Nullable private FixedViewsAdapter footerAdapter;
@Nullable private ListCallback listCallback;
@Nullable private ScrollCallback scrollCallback;
private GlideRequests glideRequests;
private int selectionLimit;
private Set<RecipientId> currentSelection;
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
if (context instanceof ListCallback) {
listCallback = (ListCallback) context;
}
if (context instanceof ScrollCallback) {
scrollCallback = (ScrollCallback) context;
}
}
@Override
public void onActivityCreated(Bundle icicle) {
super.onActivityCreated(icicle);
initializeCursor();
}
@Override
public void onStart() {
super.onStart();
Permissions.with(this)
.request(Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_CONTACTS)
.ifNecessary()
.onAllGranted(() -> {
if (!TextSecurePreferences.hasSuccessfullyRetrievedDirectory(getActivity())) {
handleContactPermissionGranted();
} else {
LoaderManager.getInstance(this).initLoader(0, null, this);
}
})
.onAnyDenied(() -> {
FragmentActivity activity = requireActivity();
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
if (activity.getIntent().getBooleanExtra(RECENTS, false)) {
LoaderManager.getInstance(this).initLoader(0, null, ContactSelectionListFragment.this);
} else {
initializeNoContactsPermission();
}
})
.execute();
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.contact_selection_list_fragment, container, false);
emptyText = view.findViewById(android.R.id.empty);
recyclerView = view.findViewById(R.id.recycler_view);
swipeRefresh = view.findViewById(R.id.swipe_refresh);
fastScroller = view.findViewById(R.id.fast_scroller);
showContactsLayout = view.findViewById(R.id.show_contacts_container);
showContactsButton = view.findViewById(R.id.show_contacts_button);
showContactsDescription = view.findViewById(R.id.show_contacts_description);
showContactsProgress = view.findViewById(R.id.progress);
chipGroup = view.findViewById(R.id.chipGroup);
chipGroupScrollContainer = view.findViewById(R.id.chipGroupScrollContainer);
groupLimit = view.findViewById(R.id.group_limit);
constraintLayout = view.findViewById(R.id.container);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setItemAnimator(new DefaultItemAnimator() {
@Override
public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) {
return true;
}
});
swipeRefresh.setEnabled(requireActivity().getIntent().getBooleanExtra(REFRESHABLE, true));
selectionLimit = requireActivity().getIntent().getIntExtra(TOTAL_CAPACITY, NO_LIMIT);
currentSelection = getCurrentSelection();
updateGroupLimit(getChipCount());
return view;
}
private void updateGroupLimit(int chipCount) {
if (selectionLimit != NO_LIMIT) {
groupLimit.setText(String.format(Locale.getDefault(), "%d/%d", currentSelection.size() + chipCount, selectionLimit));
groupLimit.setVisibility(View.VISIBLE);
} else {
groupLimit.setVisibility(View.GONE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
public @NonNull List<SelectedContact> getSelectedContacts() {
if (cursorRecyclerViewAdapter == null) {
return Collections.emptyList();
}
return cursorRecyclerViewAdapter.getSelectedContacts();
}
public int getSelectedContactsCount() {
if (cursorRecyclerViewAdapter == null) {
return 0;
}
return cursorRecyclerViewAdapter.getSelectedContactsCount();
}
private Set<RecipientId> getCurrentSelection() {
List<RecipientId> currentSelection = requireActivity().getIntent().getParcelableArrayListExtra(CURRENT_SELECTION);
return currentSelection == null ? Collections.emptySet()
: Collections.unmodifiableSet(Stream.of(currentSelection).collect(Collectors.toSet()));
}
public boolean isMulti() {
return requireActivity().getIntent().getBooleanExtra(MULTI_SELECT, false);
}
private void initializeCursor() {
glideRequests = GlideApp.with(this);
cursorRecyclerViewAdapter = new ContactSelectionListAdapter(requireContext(),
glideRequests,
null,
new ListClickListener(),
isMulti(),
currentSelection);
RecyclerViewConcatenateAdapterStickyHeader concatenateAdapter = new RecyclerViewConcatenateAdapterStickyHeader();
if (listCallback != null && FeatureFlags.newGroupUI()) {
if (FeatureFlags.groupsV2create() && FeatureFlags.groupsV2internalTest()) {
headerAdapter = new FixedViewsAdapter(createNewGroupItem(listCallback), createNewGroupsV1GroupItem(listCallback));
} else {
headerAdapter = new FixedViewsAdapter(createNewGroupItem(listCallback));
}
headerAdapter.hide();
concatenateAdapter.addAdapter(headerAdapter);
}
concatenateAdapter.addAdapter(cursorRecyclerViewAdapter);
if (listCallback != null) {
footerAdapter = new FixedViewsAdapter(createInviteActionView(listCallback));
footerAdapter.hide();
concatenateAdapter.addAdapter(footerAdapter);
}
recyclerView.setAdapter(concatenateAdapter);
recyclerView.addItemDecoration(new StickyHeaderDecoration(concatenateAdapter, true, true));
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
if (scrollCallback != null) {
scrollCallback.onBeginScroll();
}
}
}
});
}
private View createInviteActionView(@NonNull ListCallback listCallback) {
View view = LayoutInflater.from(requireContext())
.inflate(R.layout.contact_selection_invite_action_item, (ViewGroup) requireView(), false);
view.setOnClickListener(v -> listCallback.onInvite());
return view;
}
private View createNewGroupItem(@NonNull ListCallback listCallback) {
View view = LayoutInflater.from(requireContext())
.inflate(R.layout.contact_selection_new_group_item, (ViewGroup) requireView(), false);
view.setOnClickListener(v -> listCallback.onNewGroup(false));
return view;
}
private View createNewGroupsV1GroupItem(@NonNull ListCallback listCallback) {
View view = LayoutInflater.from(requireContext())
.inflate(R.layout.contact_selection_new_group_v1_item, (ViewGroup) requireView(), false);
view.setOnClickListener(v -> listCallback.onNewGroup(true));
return view;
}
private void initializeNoContactsPermission() {
swipeRefresh.setVisibility(View.GONE);
showContactsLayout.setVisibility(View.VISIBLE);
showContactsProgress.setVisibility(View.INVISIBLE);
showContactsDescription.setText(R.string.contact_selection_list_fragment__signal_needs_access_to_your_contacts_in_order_to_display_them);
showContactsButton.setVisibility(View.VISIBLE);
showContactsButton.setOnClickListener(v -> {
Permissions.with(this)
.request(Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_CONTACTS)
.ifNecessary()
.withPermanentDenialDialog(getString(R.string.ContactSelectionListFragment_signal_requires_the_contacts_permission_in_order_to_display_your_contacts))
.onSomeGranted(permissions -> {
if (permissions.contains(Manifest.permission.WRITE_CONTACTS)) {
handleContactPermissionGranted();
}
})
.execute();
});
}
public void setQueryFilter(String filter) {
this.cursorFilter = filter;
LoaderManager.getInstance(this).restartLoader(0, null, this);
}
public void resetQueryFilter() {
setQueryFilter(null);
swipeRefresh.setRefreshing(false);
}
public boolean hasQueryFilter() {
return !TextUtils.isEmpty(cursorFilter);
}
public void setRefreshing(boolean refreshing) {
swipeRefresh.setRefreshing(refreshing);
}
public void reset() {
cursorRecyclerViewAdapter.clearSelectedContacts();
if (!isDetached() && !isRemoving() && getActivity() != null && !getActivity().isFinishing()) {
LoaderManager.getInstance(this).restartLoader(0, null, this);
}
}
@Override
public @NonNull Loader<Cursor> onCreateLoader(int id, Bundle args) {
FragmentActivity activity = requireActivity();
return new ContactsCursorLoader(activity,
activity.getIntent().getIntExtra(DISPLAY_MODE, DisplayMode.FLAG_ALL),
cursorFilter, activity.getIntent().getBooleanExtra(RECENTS, false));
}
@Override
public void onLoadFinished(@NonNull Loader<Cursor> loader, @Nullable Cursor data) {
swipeRefresh.setVisibility(View.VISIBLE);
showContactsLayout.setVisibility(View.GONE);
cursorRecyclerViewAdapter.changeCursor(data);
if (footerAdapter != null) {
footerAdapter.show();
}
if (headerAdapter != null) {
if (TextUtils.isEmpty(cursorFilter)) {
headerAdapter.show();
} else {
headerAdapter.hide();
}
}
emptyText.setText(R.string.contact_selection_group_activity__no_contacts);
boolean useFastScroller = data != null && data.getCount() > 20;
recyclerView.setVerticalScrollBarEnabled(!useFastScroller);
if (useFastScroller) {
fastScroller.setVisibility(View.VISIBLE);
fastScroller.setRecyclerView(recyclerView);
} else {
fastScroller.setRecyclerView(null);
fastScroller.setVisibility(View.GONE);
}
}
@Override
public void onLoaderReset(@NonNull Loader<Cursor> loader) {
cursorRecyclerViewAdapter.changeCursor(null);
fastScroller.setVisibility(View.GONE);
}
@SuppressLint("StaticFieldLeak")
private void handleContactPermissionGranted() {
final Context context = requireContext();
new AsyncTask<Void, Void, Boolean>() {
@Override
protected void onPreExecute() {
swipeRefresh.setVisibility(View.GONE);
showContactsLayout.setVisibility(View.VISIBLE);
showContactsButton.setVisibility(View.INVISIBLE);
showContactsDescription.setText(R.string.ConversationListFragment_loading);
showContactsProgress.setVisibility(View.VISIBLE);
showContactsProgress.spin();
}
@Override
protected Boolean doInBackground(Void... voids) {
try {
DirectoryHelper.refreshDirectory(context, false);
return true;
} catch (IOException e) {
Log.w(TAG, e);
}
return false;
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
showContactsLayout.setVisibility(View.GONE);
swipeRefresh.setVisibility(View.VISIBLE);
reset();
} else {
Toast.makeText(getContext(), R.string.ContactSelectionListFragment_error_retrieving_contacts_check_your_network_connection, Toast.LENGTH_LONG).show();
initializeNoContactsPermission();
}
}
}.execute();
}
private class ListClickListener implements ContactSelectionListAdapter.ItemClickListener {
@Override
public void onItemClick(ContactSelectionListItem contact) {
SelectedContact selectedContact = contact.isUsernameType() ? SelectedContact.forUsername(contact.getRecipientId().orNull(), contact.getNumber())
: SelectedContact.forPhone(contact.getRecipientId().orNull(), contact.getNumber());
if (!isMulti() || !cursorRecyclerViewAdapter.isSelectedContact(selectedContact)) {
if (selectionLimitReached()) {
Toast.makeText(requireContext(), R.string.ContactSelectionListFragment_the_group_is_full, Toast.LENGTH_SHORT).show();
groupLimit.animate().scaleX(1.3f).scaleY(1.3f).setInterpolator(new CycleInterpolator(0.5f)).start();
return;
}
if (contact.isUsernameType()) {
AlertDialog loadingDialog = SimpleProgressDialog.show(requireContext());
SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> {
return UsernameUtil.fetchUuidForUsername(requireContext(), contact.getNumber());
}, uuid -> {
loadingDialog.dismiss();
if (uuid.isPresent()) {
Recipient recipient = Recipient.externalUsername(requireContext(), uuid.get(), contact.getNumber());
SelectedContact selected = SelectedContact.forUsername(recipient.getId(), contact.getNumber());
markContactSelected(selected);
cursorRecyclerViewAdapter.notifyItemChanged(recyclerView.getChildAdapterPosition(contact), ContactSelectionListAdapter.PAYLOAD_SELECTION_CHANGE);
if (onContactSelectedListener != null) {
onContactSelectedListener.onContactSelected(Optional.of(recipient.getId()), null);
}
} else {
new AlertDialog.Builder(requireContext())
.setTitle(R.string.ContactSelectionListFragment_username_not_found)
.setMessage(getString(R.string.ContactSelectionListFragment_s_is_not_a_signal_user, contact.getNumber()))
.setPositiveButton(R.string.ContactSelectionListFragment_okay, (dialog, which) -> dialog.dismiss())
.show();
}
});
} else {
markContactSelected(selectedContact);
cursorRecyclerViewAdapter.notifyItemChanged(recyclerView.getChildAdapterPosition(contact), ContactSelectionListAdapter.PAYLOAD_SELECTION_CHANGE);
if (onContactSelectedListener != null) {
onContactSelectedListener.onContactSelected(contact.getRecipientId(), contact.getNumber());
}
}
} else {
markContactUnselected(selectedContact);
cursorRecyclerViewAdapter.notifyItemChanged(recyclerView.getChildAdapterPosition(contact), ContactSelectionListAdapter.PAYLOAD_SELECTION_CHANGE);
if (onContactSelectedListener != null) {
onContactSelectedListener.onContactDeselected(contact.getRecipientId(), contact.getNumber());
}
}}
}
private boolean selectionLimitReached() {
return getChipCount() >= selectionLimit;
}
private void markContactSelected(@NonNull SelectedContact selectedContact) {
cursorRecyclerViewAdapter.addSelectedContact(selectedContact);
if (isMulti() && FeatureFlags.newGroupUI()) {
addChipForSelectedContact(selectedContact);
}
}
private void markContactUnselected(@NonNull SelectedContact selectedContact) {
cursorRecyclerViewAdapter.removeFromSelectedContacts(selectedContact);
cursorRecyclerViewAdapter.notifyItemRangeChanged(0, cursorRecyclerViewAdapter.getItemCount(), ContactSelectionListAdapter.PAYLOAD_SELECTION_CHANGE);
removeChipForContact(selectedContact);
}
private void removeChipForContact(@NonNull SelectedContact contact) {
for (int i = chipGroup.getChildCount() - 1; i >= 0; i--) {
View v = chipGroup.getChildAt(i);
if (v instanceof ContactChip && contact.matches(((ContactChip) v).getContact())) {
chipGroup.removeView(v);
}
}
updateGroupLimit(getChipCount());
if (getChipCount() == 0) {
setChipGroupVisibility(ConstraintSet.GONE);
}
}
private void addChipForSelectedContact(@NonNull SelectedContact selectedContact) {
SimpleTask.run(getViewLifecycleOwner().getLifecycle(),
() -> Recipient.resolved(selectedContact.getOrCreateRecipientId(requireContext())),
resolved -> addChipForRecipient(resolved, selectedContact));
}
private void addChipForRecipient(@NonNull Recipient recipient, @NonNull SelectedContact selectedContact) {
final ContactChip chip = new ContactChip(requireContext());
if (getChipCount() == 0) {
setChipGroupVisibility(ConstraintSet.VISIBLE);
}
chip.setText(recipient.getShortDisplayName(requireContext()));
chip.setContact(selectedContact);
chip.setCloseIconVisible(true);
chip.setOnCloseIconClickListener(view -> {
markContactUnselected(selectedContact);
if (onContactSelectedListener != null) {
onContactSelectedListener.onContactDeselected(Optional.of(recipient.getId()), recipient.getE164().orNull());
}
});
chipGroup.getLayoutTransition().addTransitionListener(new LayoutTransition.TransitionListener() {
@Override
public void startTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
}
@Override
public void endTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
if (view == chip && transitionType == LayoutTransition.APPEARING) {
chipGroup.getLayoutTransition().removeTransitionListener(this);
registerChipRecipientObserver(chip, recipient.live());
chipGroup.post(ContactSelectionListFragment.this::smoothScrollChipsToEnd);
}
}
});
chip.setAvatar(glideRequests, recipient, () -> addChip(chip));
}
private void addChip(@NonNull ContactChip chip) {
chipGroup.addView(chip);
updateGroupLimit(getChipCount());
}
private int getChipCount() {
int count = chipGroup.getChildCount() - CHIP_GROUP_EMPTY_CHILD_COUNT;
if (count < 0) throw new AssertionError();
return count;
}
private void registerChipRecipientObserver(@NonNull ContactChip chip, @Nullable LiveRecipient recipient) {
if (recipient != null) {
recipient.observe(getViewLifecycleOwner(), resolved -> {
if (chip.isAttachedToWindow()) {
chip.setAvatar(glideRequests, resolved, null);
chip.setText(resolved.getShortDisplayName(chip.getContext()));
}
});
}
}
private void setChipGroupVisibility(int visibility) {
TransitionManager.beginDelayedTransition(constraintLayout, new AutoTransition().setDuration(CHIP_GROUP_REVEAL_DURATION_MS));
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(constraintLayout);
constraintSet.setVisibility(R.id.chipGroupScrollContainer, visibility);
constraintSet.applyTo(constraintLayout);
}
public void setOnContactSelectedListener(OnContactSelectedListener onContactSelectedListener) {
this.onContactSelectedListener = onContactSelectedListener;
}
public void setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener onRefreshListener) {
this.swipeRefresh.setOnRefreshListener(onRefreshListener);
}
private void smoothScrollChipsToEnd() {
int x = chipGroupScrollContainer.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR ? chipGroup.getWidth() : 0;
chipGroupScrollContainer.smoothScrollTo(x, 0);
}
public interface OnContactSelectedListener {
void onContactSelected(Optional<RecipientId> recipientId, String number);
void onContactDeselected(Optional<RecipientId> recipientId, String number);
}
public interface ListCallback {
void onInvite();
void onNewGroup(boolean forceV1);
}
public interface ScrollCallback {
void onBeginScroll();
}
}

View File

@@ -10,14 +10,13 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.NonNull;
import android.os.Parcelable;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.SmsMigrator.ProgressDescription;
import org.thoughtcrime.securesms.service.ApplicationMigrationService;
import org.thoughtcrime.securesms.service.ApplicationMigrationService.ImportState;
@@ -39,7 +38,7 @@ public class DatabaseMigrationActivity extends PassphraseRequiredActionBarActivi
private boolean isVisible = false;
@Override
protected void onCreate(Bundle bundle, @NonNull MasterSecret masterSecret) {
protected void onCreate(Bundle bundle, boolean ready) {
setContentView(R.layout.database_migration_activity);
initializeResources();
@@ -92,7 +91,7 @@ public class DatabaseMigrationActivity extends PassphraseRequiredActionBarActivi
public void onClick(View v) {
Intent intent = new Intent(DatabaseMigrationActivity.this, ApplicationMigrationService.class);
intent.setAction(ApplicationMigrationService.MIGRATE_DATABASE);
intent.putExtra("master_secret", getIntent().getParcelableExtra("master_secret"));
intent.putExtra("master_secret", (Parcelable)getIntent().getParcelableExtra("master_secret"));
startService(intent);
promptLayout.setVisibility(View.GONE);
@@ -150,7 +149,8 @@ public class DatabaseMigrationActivity extends PassphraseRequiredActionBarActivi
if (getIntent().hasExtra("next_intent")) {
startActivity((Intent)getIntent().getParcelableExtra("next_intent"));
} else {
startActivity(new Intent(this, ConversationListActivity.class));
// TODO [greyson] Navigation
startActivity(new Intent(this, MainActivity.class));
}
}

View File

@@ -0,0 +1,251 @@
package org.thoughtcrime.securesms;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Vibrator;
import android.text.TextUtils;
import android.transition.TransitionInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.push.AccountManagerFactory;
import org.thoughtcrime.securesms.qr.ScanListener;
import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
import org.whispersystems.libsignal.IdentityKeyPair;
import org.whispersystems.libsignal.InvalidKeyException;
import org.whispersystems.libsignal.ecc.Curve;
import org.whispersystems.libsignal.ecc.ECPublicKey;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.exceptions.NotFoundException;
import org.whispersystems.signalservice.internal.push.DeviceLimitExceededException;
import java.io.IOException;
public class DeviceActivity extends PassphraseRequiredActionBarActivity
implements Button.OnClickListener, ScanListener, DeviceLinkFragment.LinkClickedListener
{
private static final String TAG = DeviceActivity.class.getSimpleName();
private final DynamicTheme dynamicTheme = new DynamicTheme();
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
private DeviceAddFragment deviceAddFragment;
private DeviceListFragment deviceListFragment;
private DeviceLinkFragment deviceLinkFragment;
@Override
public void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
}
@Override
public void onCreate(Bundle bundle, boolean ready) {
getSupportActionBar().setHomeAsUpIndicator(ContextCompat.getDrawable(this, R.drawable.ic_arrow_left_24));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(R.string.AndroidManifest__linked_devices);
this.deviceAddFragment = new DeviceAddFragment();
this.deviceListFragment = new DeviceListFragment();
this.deviceLinkFragment = new DeviceLinkFragment();
this.deviceListFragment.setAddDeviceButtonListener(this);
this.deviceAddFragment.setScanListener(this);
if (getIntent().getBooleanExtra("add", false)) {
initFragment(android.R.id.content, deviceAddFragment, dynamicLanguage.getCurrentLocale());
} else {
initFragment(android.R.id.content, deviceListFragment, dynamicLanguage.getCurrentLocale());
}
overridePendingTransition(R.anim.slide_from_end, R.anim.slide_to_start);
}
@Override
protected void onPause() {
if (isFinishing()) {
overridePendingTransition(R.anim.slide_from_start, R.anim.slide_to_end);
}
super.onPause();
}
@Override
public void onResume() {
super.onResume();
dynamicTheme.onResume(this);
dynamicLanguage.onResume(this);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: finish(); return true;
}
return false;
}
@Override
public void onClick(View v) {
Permissions.with(this)
.request(Manifest.permission.CAMERA)
.ifNecessary()
.withPermanentDenialDialog(getString(R.string.DeviceActivity_signal_needs_the_camera_permission_in_order_to_scan_a_qr_code))
.onAllGranted(() -> {
getSupportFragmentManager().beginTransaction()
.replace(android.R.id.content, deviceAddFragment)
.addToBackStack(null)
.commitAllowingStateLoss();
})
.onAnyDenied(() -> Toast.makeText(this, R.string.DeviceActivity_unable_to_scan_a_qr_code_without_the_camera_permission, Toast.LENGTH_LONG).show())
.execute();
}
@Override
public void onQrDataFound(final String data) {
Util.runOnMain(() -> {
((Vibrator)getSystemService(Context.VIBRATOR_SERVICE)).vibrate(50);
Uri uri = Uri.parse(data);
deviceLinkFragment.setLinkClickedListener(uri, DeviceActivity.this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
deviceAddFragment.setSharedElementReturnTransition(TransitionInflater.from(DeviceActivity.this).inflateTransition(R.transition.fragment_shared));
deviceAddFragment.setExitTransition(TransitionInflater.from(DeviceActivity.this).inflateTransition(android.R.transition.fade));
deviceLinkFragment.setSharedElementEnterTransition(TransitionInflater.from(DeviceActivity.this).inflateTransition(R.transition.fragment_shared));
deviceLinkFragment.setEnterTransition(TransitionInflater.from(DeviceActivity.this).inflateTransition(android.R.transition.fade));
getSupportFragmentManager().beginTransaction()
.addToBackStack(null)
.addSharedElement(deviceAddFragment.getDevicesImage(), "devices")
.replace(android.R.id.content, deviceLinkFragment)
.commit();
} else {
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(R.anim.slide_from_bottom, R.anim.slide_to_bottom,
R.anim.slide_from_bottom, R.anim.slide_to_bottom)
.replace(android.R.id.content, deviceLinkFragment)
.addToBackStack(null)
.commit();
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
@SuppressLint("StaticFieldLeak")
@Override
public void onLink(final Uri uri) {
new ProgressDialogAsyncTask<Void, Void, Integer>(this,
R.string.DeviceProvisioningActivity_content_progress_title,
R.string.DeviceProvisioningActivity_content_progress_content)
{
private static final int SUCCESS = 0;
private static final int NO_DEVICE = 1;
private static final int NETWORK_ERROR = 2;
private static final int KEY_ERROR = 3;
private static final int LIMIT_EXCEEDED = 4;
private static final int BAD_CODE = 5;
@Override
protected Integer doInBackground(Void... params) {
boolean isMultiDevice = TextSecurePreferences.isMultiDevice(DeviceActivity.this);
try {
Context context = DeviceActivity.this;
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
String verificationCode = accountManager.getNewDeviceVerificationCode();
String ephemeralId = uri.getQueryParameter("uuid");
String publicKeyEncoded = uri.getQueryParameter("pub_key");
if (TextUtils.isEmpty(ephemeralId) || TextUtils.isEmpty(publicKeyEncoded)) {
Log.w(TAG, "UUID or Key is empty!");
return BAD_CODE;
}
ECPublicKey publicKey = Curve.decodePoint(Base64.decode(publicKeyEncoded), 0);
IdentityKeyPair identityKeyPair = IdentityKeyUtil.getIdentityKeyPair(context);
Optional<byte[]> profileKey = Optional.of(ProfileKeyUtil.getProfileKey(getContext()));
TextSecurePreferences.setMultiDevice(DeviceActivity.this, true);
TextSecurePreferences.setIsUnidentifiedDeliveryEnabled(context, false);
accountManager.addDevice(ephemeralId, publicKey, identityKeyPair, profileKey, verificationCode);
return SUCCESS;
} catch (NotFoundException e) {
Log.w(TAG, e);
TextSecurePreferences.setMultiDevice(DeviceActivity.this, isMultiDevice);
return NO_DEVICE;
} catch (DeviceLimitExceededException e) {
Log.w(TAG, e);
TextSecurePreferences.setMultiDevice(DeviceActivity.this, isMultiDevice);
return LIMIT_EXCEEDED;
} catch (IOException e) {
Log.w(TAG, e);
TextSecurePreferences.setMultiDevice(DeviceActivity.this, isMultiDevice);
return NETWORK_ERROR;
} catch (InvalidKeyException e) {
Log.w(TAG, e);
TextSecurePreferences.setMultiDevice(DeviceActivity.this, isMultiDevice);
return KEY_ERROR;
}
}
@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
Context context = DeviceActivity.this;
switch (result) {
case SUCCESS:
Toast.makeText(context, R.string.DeviceProvisioningActivity_content_progress_success, Toast.LENGTH_SHORT).show();
finish();
return;
case NO_DEVICE:
Toast.makeText(context, R.string.DeviceProvisioningActivity_content_progress_no_device, Toast.LENGTH_LONG).show();
break;
case NETWORK_ERROR:
Toast.makeText(context, R.string.DeviceProvisioningActivity_content_progress_network_error, Toast.LENGTH_LONG).show();
break;
case KEY_ERROR:
Toast.makeText(context, R.string.DeviceProvisioningActivity_content_progress_key_error, Toast.LENGTH_LONG).show();
break;
case LIMIT_EXCEEDED:
Toast.makeText(context, R.string.DeviceProvisioningActivity_sorry_you_have_too_many_devices_linked_already, Toast.LENGTH_LONG).show();
break;
case BAD_CODE:
Toast.makeText(context, R.string.DeviceActivity_sorry_this_is_not_a_valid_device_link_qr_code, Toast.LENGTH_LONG).show();
break;
}
getSupportFragmentManager().popBackStackImmediate();
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}

View File

@@ -2,15 +2,11 @@ package org.thoughtcrime.securesms;
import android.animation.Animator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewAnimationUtils;
@@ -19,21 +15,9 @@ import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import org.thoughtcrime.securesms.components.camera.CameraView;
import org.thoughtcrime.securesms.components.camera.CameraView.PreviewCallback;
import org.thoughtcrime.securesms.components.camera.CameraView.PreviewFrame;
import org.thoughtcrime.securesms.qr.ScanListener;
import org.thoughtcrime.securesms.qr.ScanningThread;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
public class DeviceAddFragment extends Fragment {
@@ -46,7 +30,7 @@ public class DeviceAddFragment extends Fragment {
private ScanListener scanListener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle) {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle) {
this.container = ViewUtil.inflate(inflater, viewGroup, R.layout.device_add_fragment);
this.overlay = ViewUtil.findById(this.container, R.id.overlay);
this.scannerView = ViewUtil.findById(this.container, R.id.scanner);

View File

@@ -3,7 +3,8 @@ package org.thoughtcrime.securesms;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -16,7 +17,7 @@ public class DeviceLinkFragment extends Fragment implements View.OnClickListener
private Uri uri;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle) {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle) {
this.container = (LinearLayout) inflater.inflate(R.layout.device_link_fragment, container, false);
this.container.findViewById(R.id.link_device).setOnClickListener(this);
@@ -31,6 +32,7 @@ public class DeviceLinkFragment extends Fragment implements View.OnClickListener
@Override
public void onConfigurationChanged(Configuration newConfiguration) {
super.onConfigurationChanged(newConfiguration);
if (newConfiguration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
container.setOrientation(LinearLayout.HORIZONTAL);
} else {
@@ -51,6 +53,6 @@ public class DeviceLinkFragment extends Fragment implements View.OnClickListener
}
public interface LinkClickedListener {
public void onLink(Uri uri);
void onLink(Uri uri);
}
}

View File

@@ -0,0 +1,221 @@
package org.thoughtcrime.securesms;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.ListFragment;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.appcompat.app.AlertDialog;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.devicelist.Device;
import org.thoughtcrime.securesms.logging.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import com.melnykov.fab.FloatingActionButton;
import org.thoughtcrime.securesms.database.loaders.DeviceListLoader;
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class DeviceListFragment extends ListFragment
implements LoaderManager.LoaderCallbacks<List<Device>>,
ListView.OnItemClickListener, Button.OnClickListener
{
private static final String TAG = DeviceListFragment.class.getSimpleName();
private SignalServiceAccountManager accountManager;
private Locale locale;
private View empty;
private View progressContainer;
private FloatingActionButton addDeviceButton;
private Button.OnClickListener addDeviceButtonListener;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.locale = (Locale) getArguments().getSerializable(PassphraseRequiredActionBarActivity.LOCALE_EXTRA);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.accountManager = ApplicationDependencies.getSignalServiceAccountManager();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
View view = inflater.inflate(R.layout.device_list_fragment, container, false);
this.empty = view.findViewById(R.id.empty);
this.progressContainer = view.findViewById(R.id.progress_container);
this.addDeviceButton = ViewUtil.findById(view, R.id.add_device);
this.addDeviceButton.setOnClickListener(this);
return view;
}
@Override
public void onActivityCreated(Bundle bundle) {
super.onActivityCreated(bundle);
getLoaderManager().initLoader(0, null, this);
getListView().setOnItemClickListener(this);
}
public void setAddDeviceButtonListener(Button.OnClickListener listener) {
this.addDeviceButtonListener = listener;
}
@Override
public @NonNull Loader<List<Device>> onCreateLoader(int id, Bundle args) {
empty.setVisibility(View.GONE);
progressContainer.setVisibility(View.VISIBLE);
return new DeviceListLoader(getActivity(), accountManager);
}
@Override
public void onLoadFinished(@NonNull Loader<List<Device>> loader, List<Device> data) {
progressContainer.setVisibility(View.GONE);
if (data == null) {
handleLoaderFailed();
return;
}
setListAdapter(new DeviceListAdapter(getActivity(), R.layout.device_list_item_view, data, locale));
if (data.isEmpty()) {
empty.setVisibility(View.VISIBLE);
TextSecurePreferences.setMultiDevice(getActivity(), false);
} else {
empty.setVisibility(View.GONE);
}
}
@Override
public void onLoaderReset(@NonNull Loader<List<Device>> loader) {
setListAdapter(null);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final String deviceName = ((DeviceListItem)view).getDeviceName();
final long deviceId = ((DeviceListItem)view).getDeviceId();
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getActivity().getString(R.string.DeviceListActivity_unlink_s, deviceName));
builder.setMessage(R.string.DeviceListActivity_by_unlinking_this_device_it_will_no_longer_be_able_to_send_or_receive);
builder.setNegativeButton(android.R.string.cancel, null);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
handleDisconnectDevice(deviceId);
}
});
builder.show();
}
private void handleLoaderFailed() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.DeviceListActivity_network_connection_failed);
builder.setPositiveButton(R.string.DeviceListActivity_try_again,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
getLoaderManager().restartLoader(0, null, DeviceListFragment.this);
}
});
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
DeviceListFragment.this.getActivity().onBackPressed();
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
DeviceListFragment.this.getActivity().onBackPressed();
}
});
builder.show();
}
@SuppressLint("StaticFieldLeak")
private void handleDisconnectDevice(final long deviceId) {
new ProgressDialogAsyncTask<Void, Void, Boolean>(getActivity(),
R.string.DeviceListActivity_unlinking_device_no_ellipsis,
R.string.DeviceListActivity_unlinking_device)
{
@Override
protected Boolean doInBackground(Void... params) {
try {
accountManager.removeDevice(deviceId);
return true;
} catch (IOException e) {
Log.w(TAG, e);
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (result) {
getLoaderManager().restartLoader(0, null, DeviceListFragment.this);
} else {
Toast.makeText(getActivity(), R.string.DeviceListActivity_network_failed, Toast.LENGTH_LONG).show();
}
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@Override
public void onClick(View v) {
if (addDeviceButtonListener != null) addDeviceButtonListener.onClick(v);
}
private static class DeviceListAdapter extends ArrayAdapter<Device> {
private final int resource;
private final Locale locale;
public DeviceListAdapter(Context context, int resource, List<Device> objects, Locale locale) {
super(context, resource, objects);
this.resource = resource;
this.locale = locale;
}
@Override
public @NonNull View getView(int position, View convertView, @NonNull ViewGroup parent) {
if (convertView == null) {
convertView = ((Activity)getContext()).getLayoutInflater().inflate(resource, parent, false);
}
((DeviceListItem)convertView).set(getItem(position), locale);
return convertView;
}
}
}

View File

@@ -6,8 +6,8 @@ import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.thoughtcrime.securesms.devicelist.Device;
import org.thoughtcrime.securesms.util.DateUtils;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceInfo;
import java.util.Locale;
@@ -34,7 +34,7 @@ public class DeviceListItem extends LinearLayout {
this.lastActive = (TextView) findViewById(R.id.active);
}
public void set(DeviceInfo deviceInfo, Locale locale) {
public void set(Device deviceInfo, Locale locale) {
if (TextUtils.isEmpty(deviceInfo.getName())) this.name.setText(R.string.DeviceListItem_unnamed_device);
else this.name.setText(deviceInfo.getName());

View File

@@ -0,0 +1,39 @@
package org.thoughtcrime.securesms;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
import android.view.Window;
public class DeviceProvisioningActivity extends PassphraseRequiredActionBarActivity {
@SuppressWarnings("unused")
private static final String TAG = DeviceProvisioningActivity.class.getSimpleName();
@Override
protected void onPreCreate() {
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
}
@Override
protected void onCreate(Bundle bundle, boolean ready) {
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle(getString(R.string.DeviceProvisioningActivity_link_a_signal_device))
.setMessage(getString(R.string.DeviceProvisioningActivity_it_looks_like_youre_trying_to_link_a_signal_device_using_a_3rd_party_scanner))
.setPositiveButton(R.string.DeviceProvisioningActivity_continue, (dialog1, which) -> {
Intent intent = new Intent(DeviceProvisioningActivity.this, DeviceActivity.class);
intent.putExtra("add", true);
startActivity(intent);
finish();
})
.setNegativeButton(R.string.DeviceProvisioningActivity_cancel, (dialog12, which) -> {
dialog12.dismiss();
finish();
})
.setOnDismissListener(dialog13 -> finish())
.create();
dialog.setIcon(getResources().getDrawable(R.drawable.icon_dialog));
dialog.show();
}
}

View File

@@ -0,0 +1,87 @@
package org.thoughtcrime.securesms;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import org.thoughtcrime.securesms.util.ExpirationUtil;
import cn.carbswang.android.numberpickerview.library.NumberPickerView;
public class ExpirationDialog extends AlertDialog {
protected ExpirationDialog(Context context) {
super(context);
}
protected ExpirationDialog(Context context, int theme) {
super(context, theme);
}
protected ExpirationDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
}
public static void show(final Context context,
final int currentExpiration,
final @NonNull OnClickListener listener)
{
final View view = createNumberPickerView(context, currentExpiration);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(context.getString(R.string.ExpirationDialog_disappearing_messages));
builder.setView(view);
builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
int selected = ((NumberPickerView)view.findViewById(R.id.expiration_number_picker)).getValue();
listener.onClick(context.getResources().getIntArray(R.array.expiration_times)[selected]);
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
}
private static View createNumberPickerView(final Context context, final int currentExpiration) {
final LayoutInflater inflater = LayoutInflater.from(context);
final View view = inflater.inflate(R.layout.expiration_dialog, null);
final NumberPickerView numberPickerView = view.findViewById(R.id.expiration_number_picker);
final TextView textView = view.findViewById(R.id.expiration_details);
final int[] expirationTimes = context.getResources().getIntArray(R.array.expiration_times);
final String[] expirationDisplayValues = new String[expirationTimes.length];
int selectedIndex = expirationTimes.length - 1;
for (int i=0;i<expirationTimes.length;i++) {
expirationDisplayValues[i] = ExpirationUtil.getExpirationDisplayValue(context, expirationTimes[i]);
if ((currentExpiration >= expirationTimes[i]) &&
(i == expirationTimes.length -1 || currentExpiration < expirationTimes[i+1])) {
selectedIndex = i;
}
}
numberPickerView.setDisplayedValues(expirationDisplayValues);
numberPickerView.setMinValue(0);
numberPickerView.setMaxValue(expirationTimes.length-1);
NumberPickerView.OnValueChangeListener listener = (picker, oldVal, newVal) -> {
if (newVal == 0) {
textView.setText(R.string.ExpirationDialog_your_messages_will_not_expire);
} else {
textView.setText(context.getString(R.string.ExpirationDialog_your_messages_will_disappear_s_after_they_have_been_seen, picker.getDisplayedValues()[newVal]));
}
};
numberPickerView.setOnValueChangedListener(listener);
numberPickerView.setValue(selectedIndex);
listener.onValueChange(numberPickerView, selectedIndex, selectedIndex);
return view;
}
public interface OnClickListener {
public void onClick(int expirationTime);
}
}

View File

@@ -0,0 +1,629 @@
/*
* Copyright (C) 2014 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import org.thoughtcrime.securesms.components.PushRecipientsPanel;
import org.thoughtcrime.securesms.components.PushRecipientsPanel.RecipientsPanelChangedListener;
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode;
import org.thoughtcrime.securesms.contacts.RecipientsEditor;
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
import org.thoughtcrime.securesms.conversation.ConversationActivity;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.groups.GroupId;
import org.thoughtcrime.securesms.groups.GroupManager;
import org.thoughtcrime.securesms.groups.GroupManager.GroupActionResult;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mediasend.AvatarSelectionActivity;
import org.thoughtcrime.securesms.mediasend.AvatarSelectionBottomSheetDialogFragment;
import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.profiles.AvatarHelper;
import org.thoughtcrime.securesms.profiles.edit.EditProfileActivity;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.SelectedRecipientsAdapter;
import org.thoughtcrime.securesms.util.SelectedRecipientsAdapter.OnRecipientDeletedListener;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
import org.whispersystems.libsignal.util.guava.Optional;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* Activity to create and update {@link GroupId.V1} groups
*
* @author Jake McGinty
*/
public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
implements OnRecipientDeletedListener,
RecipientsPanelChangedListener
{
private final static String TAG = GroupCreateActivity.class.getSimpleName();
private static final String GROUP_ID_EXTRA = "group_id";
private static final String GROUP_THREAD_EXTRA = "group_thread";
private final DynamicTheme dynamicTheme = new DynamicTheme();
private static final short REQUEST_CODE_SELECT_AVATAR = 26165;
private static final int PICK_CONTACT = 1;
private EditText groupName;
private ListView listView;
private ImageView avatar;
private TextView creatingText;
private Bitmap avatarBmp;
@NonNull private Optional<GroupData> groupToUpdate = Optional.absent();
public static Intent newEditGroupIntent(@NonNull Context context, @NonNull GroupId.V1 groupId) {
Intent intent = new Intent(context, GroupCreateActivity.class);
intent.putExtra(GroupCreateActivity.GROUP_ID_EXTRA, groupId.toString());
return intent;
}
@Override
protected void onPreCreate() {
dynamicTheme.onCreate(this);
}
@Override
protected void onCreate(Bundle state, boolean ready) {
setContentView(R.layout.group_create_activity);
//noinspection ConstantConditions
initializeAppBar();
initializeResources();
initializeExistingGroup();
}
@Override
public void onResume() {
super.onResume();
dynamicTheme.onResume(this);
updateViewState();
}
private boolean isSignalGroup() {
return TextSecurePreferences.isPushRegistered(this) && !getAdapter().hasNonPushMembers();
}
private void disableSignalGroupViews(int reasonResId) {
View pushDisabled = findViewById(R.id.push_disabled);
pushDisabled.setVisibility(View.VISIBLE);
((TextView) findViewById(R.id.push_disabled_reason)).setText(reasonResId);
avatar.setEnabled(false);
groupName.setEnabled(false);
}
private void enableSignalGroupViews() {
findViewById(R.id.push_disabled).setVisibility(View.GONE);
avatar.setEnabled(true);
groupName.setEnabled(true);
}
@SuppressWarnings("ConstantConditions")
private void updateViewState() {
if (!TextSecurePreferences.isPushRegistered(this)) {
disableSignalGroupViews(R.string.GroupCreateActivity_youre_not_registered_for_signal);
getSupportActionBar().setTitle(R.string.GroupCreateActivity_actionbar_mms_title);
} else if (getAdapter().hasNonPushMembers()) {
disableSignalGroupViews(R.string.GroupCreateActivity_contacts_dont_support_push);
getSupportActionBar().setTitle(R.string.GroupCreateActivity_actionbar_mms_title);
} else {
enableSignalGroupViews();
getSupportActionBar().setTitle(groupToUpdate.isPresent()
? R.string.GroupCreateActivity_actionbar_edit_title
: R.string.GroupCreateActivity_actionbar_title);
}
}
private static boolean isActiveInDirectory(Recipient recipient) {
return recipient.resolve().getRegistered() == RecipientDatabase.RegisteredState.REGISTERED;
}
private void addSelectedContacts(@NonNull Recipient... recipients) {
new AddMembersTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, recipients);
}
private void addSelectedContacts(@NonNull Collection<Recipient> recipients) {
addSelectedContacts(recipients.toArray(new Recipient[recipients.size()]));
}
private void initializeAppBar() {
Drawable upIcon = ContextCompat.getDrawable(this, R.drawable.ic_arrow_left_24);
getSupportActionBar().setHomeAsUpIndicator(upIcon);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void initializeResources() {
RecipientsEditor recipientsEditor = findViewById(R.id.recipients_text);
PushRecipientsPanel recipientsPanel = findViewById(R.id.recipients);
listView = findViewById(R.id.selected_contacts_list);
avatar = findViewById(R.id.avatar);
groupName = findViewById(R.id.group_name);
creatingText = findViewById(R.id.creating_group_text);
SelectedRecipientsAdapter adapter = new SelectedRecipientsAdapter(this);
adapter.setOnRecipientDeletedListener(this);
listView.setAdapter(adapter);
recipientsEditor.setHint(R.string.recipients_panel__add_members);
recipientsPanel.setPanelChangeListener(this);
findViewById(R.id.contacts_button).setOnClickListener(new AddRecipientButtonListener());
avatar.setImageDrawable(getDefaultGroupAvatar());
avatar.setOnClickListener(view -> AvatarSelectionBottomSheetDialogFragment.create(avatarBmp != null, false, REQUEST_CODE_SELECT_AVATAR, true).show(getSupportFragmentManager(), null));
}
private Drawable getDefaultGroupAvatar() {
return new ResourceContactPhoto(R.drawable.ic_group_outline_34, R.drawable.ic_group_outline_20).asDrawable(this, ContactColors.UNKNOWN_COLOR.toConversationColor(this));
}
private void initializeExistingGroup() {
final GroupId groupId = GroupId.parseNullableOrThrow(getIntent().getStringExtra(GROUP_ID_EXTRA));
if (groupId != null) {
GroupId.V1 groupIdV1 = groupId.requireV1();
new FillExistingGroupInfoAsyncTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, groupIdV1);
if (FeatureFlags.newGroupUI()) {
avatar.setOnClickListener(v -> startActivity(EditProfileActivity.getIntentForGroupProfile(this, groupIdV1)));
}
}
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuInflater inflater = this.getMenuInflater();
menu.clear();
inflater.inflate(R.menu.group_create, menu);
super.onPrepareOptionsMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.menu_create_group:
if (groupToUpdate.isPresent()) handleGroupUpdate();
else handleGroupCreate();
return true;
}
return false;
}
@Override
public void onRecipientDeleted(Recipient recipient) {
getAdapter().remove(recipient);
updateViewState();
}
@Override
public void onRecipientsPanelUpdate(List<Recipient> recipients) {
if (recipients != null && !recipients.isEmpty()) addSelectedContacts(recipients);
}
private void handleGroupCreate() {
if (getAdapter().getCount() < 1) {
Log.i(TAG, getString(R.string.GroupCreateActivity_contacts_no_members));
Toast.makeText(getApplicationContext(), R.string.GroupCreateActivity_contacts_no_members, Toast.LENGTH_SHORT).show();
return;
}
if (isSignalGroup()) {
new CreateSignalGroupTask(this, avatarBmp, getGroupName(), getAdapter().getRecipients()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new CreateMmsGroupTask(this, getAdapter().getRecipients()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
private void handleGroupUpdate() {
new UpdateSignalGroupV1Task(this, groupToUpdate.get().id, avatarBmp,
getGroupName(), getAdapter().getRecipients()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private void handleOpenConversation(long threadId, Recipient recipient) {
Intent intent = new Intent(this, ConversationActivity.class);
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
intent.putExtra(ConversationActivity.RECIPIENT_EXTRA, recipient.getId());
startActivity(intent);
finish();
}
private SelectedRecipientsAdapter getAdapter() {
return (SelectedRecipientsAdapter) listView.getAdapter();
}
private @Nullable String getGroupName() {
return groupName.getText() != null ? groupName.getText().toString() : null;
}
@Override
public void onActivityResult(int reqCode, int resultCode, final Intent data) {
super.onActivityResult(reqCode, resultCode, data);
if (data == null || resultCode != Activity.RESULT_OK)
return;
switch (reqCode) {
case PICK_CONTACT:
List<RecipientId> selected = data.getParcelableArrayListExtra(PushContactSelectionActivity.KEY_SELECTED_RECIPIENTS);
for (RecipientId contact : selected) {
Recipient recipient = Recipient.resolved(contact);
addSelectedContacts(recipient);
}
break;
case REQUEST_CODE_SELECT_AVATAR:
if (data.getBooleanExtra("delete", false)) {
avatarBmp = null;
avatar.setImageDrawable(getDefaultGroupAvatar());
return;
}
final Media result = data.getParcelableExtra(AvatarSelectionActivity.EXTRA_MEDIA);
final DecryptableUri decryptableUri = new DecryptableUri(result.getUri());
GlideApp.with(this)
.asBitmap()
.load(decryptableUri)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.centerCrop()
.override(AvatarHelper.AVATAR_DIMENSIONS, AvatarHelper.AVATAR_DIMENSIONS)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
setAvatar(decryptableUri, resource);
}
});
}
}
private class AddRecipientButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
Intent intent = new Intent(GroupCreateActivity.this, PushContactSelectionActivity.class);
if (groupToUpdate.isPresent()) {
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, DisplayMode.FLAG_PUSH);
} else {
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, DisplayMode.FLAG_PUSH | DisplayMode.FLAG_SMS);
}
startActivityForResult(intent, PICK_CONTACT);
}
}
private static class CreateMmsGroupTask extends AsyncTask<Void,Void,GroupActionResult> {
private final GroupCreateActivity activity;
private final Set<Recipient> members;
public CreateMmsGroupTask(GroupCreateActivity activity, Set<Recipient> members) {
this.activity = activity;
this.members = members;
}
@Override
protected GroupActionResult doInBackground(Void... avoid) {
List<RecipientId> memberAddresses = new LinkedList<>();
for (Recipient recipient : members) {
memberAddresses.add(recipient.getId());
}
memberAddresses.add(Recipient.self().getId());
GroupId.Mms groupId = DatabaseFactory.getGroupDatabase(activity).getOrCreateMmsGroupForMembers(memberAddresses);
RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(activity).getOrInsertFromGroupId(groupId);
Recipient groupRecipient = Recipient.resolved(groupRecipientId);
long threadId = DatabaseFactory.getThreadDatabase(activity).getThreadIdFor(groupRecipient, ThreadDatabase.DistributionTypes.DEFAULT);
return new GroupActionResult(groupRecipient, threadId);
}
@Override
protected void onPostExecute(GroupActionResult result) {
activity.handleOpenConversation(result.getThreadId(), result.getGroupRecipient());
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
private abstract static class SignalGroupTask extends AsyncTask<Void,Void,Optional<GroupActionResult>> {
protected GroupCreateActivity activity;
protected Bitmap avatar;
protected Set<Recipient> members;
protected String name;
public SignalGroupTask(GroupCreateActivity activity,
Bitmap avatar,
String name,
Set<Recipient> members)
{
this.activity = activity;
this.avatar = avatar;
this.name = name;
this.members = members;
}
@Override
protected void onPreExecute() {
activity.findViewById(R.id.group_details_layout).setVisibility(View.GONE);
activity.findViewById(R.id.creating_group_layout).setVisibility(View.VISIBLE);
activity.findViewById(R.id.menu_create_group).setVisibility(View.GONE);
final int titleResId = activity.groupToUpdate.isPresent()
? R.string.GroupCreateActivity_updating_group
: R.string.GroupCreateActivity_creating_group;
activity.creatingText.setText(activity.getString(titleResId, activity.getGroupName()));
}
@Override
protected void onPostExecute(Optional<GroupActionResult> groupActionResultOptional) {
if (activity.isFinishing()) return;
activity.findViewById(R.id.group_details_layout).setVisibility(View.VISIBLE);
activity.findViewById(R.id.creating_group_layout).setVisibility(View.GONE);
activity.findViewById(R.id.menu_create_group).setVisibility(View.VISIBLE);
}
}
private static class CreateSignalGroupTask extends SignalGroupTask {
public CreateSignalGroupTask(GroupCreateActivity activity, Bitmap avatar, String name, Set<Recipient> members) {
super(activity, avatar, name, members);
}
@Override
protected Optional<GroupActionResult> doInBackground(Void... aVoid) {
return Optional.of(GroupManager.createGroupV1(activity, members, BitmapUtil.toByteArray(avatar), name, false));
}
@Override
protected void onPostExecute(Optional<GroupActionResult> result) {
if (result.isPresent() && result.get().getThreadId() > -1) {
if (!activity.isFinishing()) {
activity.handleOpenConversation(result.get().getThreadId(), result.get().getGroupRecipient());
}
} else {
super.onPostExecute(result);
Toast.makeText(activity.getApplicationContext(),
R.string.GroupCreateActivity_contacts_invalid_number, Toast.LENGTH_LONG).show();
}
}
}
private static class UpdateSignalGroupV1Task extends SignalGroupTask {
private final GroupId.V1 groupId;
UpdateSignalGroupV1Task(GroupCreateActivity activity, GroupId.V1 groupId,
Bitmap avatar, String name, Set<Recipient> members)
{
super(activity, avatar, name, members);
this.groupId = groupId;
}
@Override
protected Optional<GroupActionResult> doInBackground(Void... aVoid) {
return Optional.fromNullable(GroupManager.updateGroup(activity, groupId, members, BitmapUtil.toByteArray(avatar), name));
}
@Override
protected void onPostExecute(Optional<GroupActionResult> result) {
if (result.isPresent() && result.get().getThreadId() > -1) {
if (!activity.isFinishing()) {
Intent intent = activity.getIntent();
intent.putExtra(GROUP_THREAD_EXTRA, result.get().getThreadId());
intent.putExtra(GROUP_ID_EXTRA, result.get().getGroupRecipient().requireGroupId().toString());
activity.setResult(RESULT_OK, intent);
activity.finish();
}
} else {
super.onPostExecute(result);
Toast.makeText(activity.getApplicationContext(),
R.string.GroupCreateActivity_contacts_invalid_number, Toast.LENGTH_LONG).show();
}
}
}
private static class AddMembersTask extends AsyncTask<Recipient,Void,List<AddMembersTask.Result>> {
static class Result {
Optional<Recipient> recipient;
boolean isPush;
String reason;
public Result(@Nullable Recipient recipient, boolean isPush, @Nullable String reason) {
this.recipient = Optional.fromNullable(recipient);
this.isPush = isPush;
this.reason = reason;
}
}
private GroupCreateActivity activity;
private boolean failIfNotPush;
public AddMembersTask(@NonNull GroupCreateActivity activity) {
this.activity = activity;
this.failIfNotPush = activity.groupToUpdate.isPresent();
}
@Override
protected List<Result> doInBackground(Recipient... recipients) {
final List<Result> results = new LinkedList<>();
for (Recipient recipient : recipients) {
boolean isPush = isActiveInDirectory(recipient);
if (failIfNotPush && !isPush) {
results.add(new Result(null, false, activity.getString(R.string.GroupCreateActivity_cannot_add_non_push_to_existing_group,
recipient.toShortString(activity))));
} else if (TextUtils.equals(TextSecurePreferences.getLocalNumber(activity), recipient.getE164().or(""))) {
results.add(new Result(null, false, activity.getString(R.string.GroupCreateActivity_youre_already_in_the_group)));
} else {
results.add(new Result(recipient, isPush, null));
}
}
return results;
}
@Override
protected void onPostExecute(List<Result> results) {
if (activity.isFinishing()) return;
for (Result result : results) {
if (result.recipient.isPresent()) {
activity.getAdapter().add(result.recipient.get(), result.isPush);
} else {
Toast.makeText(activity, result.reason, Toast.LENGTH_SHORT).show();
}
}
activity.updateViewState();
}
}
private static class FillExistingGroupInfoAsyncTask extends ProgressDialogAsyncTask<GroupId.V1, Void, Optional<GroupData>> {
private GroupCreateActivity activity;
public FillExistingGroupInfoAsyncTask(GroupCreateActivity activity) {
super(activity,
R.string.GroupCreateActivity_loading_group_details,
R.string.please_wait);
this.activity = activity;
}
@Override
protected Optional<GroupData> doInBackground(GroupId.V1... groupIds) {
final GroupDatabase db = DatabaseFactory.getGroupDatabase(activity);
final List<Recipient> recipients = db.getGroupMembers(groupIds[0], GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF);
final Optional<GroupRecord> group = db.getGroup(groupIds[0]);
final Set<Recipient> existingContacts = new HashSet<>(recipients.size());
existingContacts.addAll(recipients);
if (group.isPresent()) {
Bitmap avatar = null;
try {
avatar = BitmapFactory.decodeStream(AvatarHelper.getAvatar(getContext(), group.get().getRecipientId()));
} catch (IOException e) {
Log.w(TAG, "Failed to read avatar.");
}
return Optional.of(new GroupData(groupIds[0],
existingContacts,
avatar,
BitmapUtil.toByteArray(avatar),
group.get().getTitle()));
} else {
return Optional.absent();
}
}
@Override
protected void onPostExecute(Optional<GroupData> group) {
super.onPostExecute(group);
if (group.isPresent() && !activity.isFinishing()) {
activity.groupToUpdate = group;
activity.groupName.setText(group.get().name);
if (group.get().avatarBmp != null) {
activity.setAvatar(group.get().avatarBytes, group.get().avatarBmp);
}
SelectedRecipientsAdapter adapter = new SelectedRecipientsAdapter(activity, group.get().recipients);
adapter.setOnRecipientDeletedListener(activity);
activity.listView.setAdapter(adapter);
activity.updateViewState();
}
}
}
private <T> void setAvatar(T model, Bitmap bitmap) {
avatarBmp = bitmap;
GlideApp.with(this)
.load(model)
.circleCrop()
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(avatar);
}
private static class GroupData {
GroupId.V1 id;
Set<Recipient> recipients;
Bitmap avatarBmp;
byte[] avatarBytes;
String name;
GroupData(GroupId.V1 id, Set<Recipient> recipients, Bitmap avatarBmp, byte[] avatarBytes, String name) {
this.id = id;
this.recipients = recipients;
this.avatarBmp = avatarBmp;
this.avatarBytes = avatarBytes;
this.name = name;
}
}
}

View File

@@ -0,0 +1,57 @@
package org.thoughtcrime.securesms;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.LiveData;
import org.thoughtcrime.securesms.groups.LiveGroup;
import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry;
import org.thoughtcrime.securesms.groups.ui.GroupMemberListView;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.ui.bottomsheet.RecipientBottomSheetDialogFragment;
import java.util.List;
public final class GroupMembersDialog {
private final FragmentActivity fragmentActivity;
private final Recipient groupRecipient;
public GroupMembersDialog(@NonNull FragmentActivity activity,
@NonNull Recipient groupRecipient)
{
this.fragmentActivity = activity;
this.groupRecipient = groupRecipient;
}
public void display() {
AlertDialog dialog = new AlertDialog.Builder(fragmentActivity)
.setTitle(R.string.ConversationActivity_group_members)
.setIconAttribute(R.attr.group_members_dialog_icon)
.setCancelable(true)
.setView(R.layout.dialog_group_members)
.setPositiveButton(android.R.string.ok, null)
.show();
GroupMemberListView memberListView = dialog.findViewById(R.id.list_members);
LiveGroup liveGroup = new LiveGroup(groupRecipient.requireGroupId());
LiveData<List<GroupMemberEntry.FullMember>> fullMembers = liveGroup.getFullMembers();
//noinspection ConstantConditions
fullMembers.observe(fragmentActivity, memberListView::setMembers);
dialog.setOnDismissListener(d -> fullMembers.removeObservers(fragmentActivity));
memberListView.setRecipientClickListener(recipient -> {
dialog.dismiss();
contactClick(recipient);
});
}
private void contactClick(@NonNull Recipient recipient) {
RecipientBottomSheetDialogFragment.create(recipient.getId(), groupRecipient.requireGroupId())
.show(fragmentActivity.getSupportFragmentManager(), "BOTTOM");
}
}

View File

@@ -0,0 +1,291 @@
package org.thoughtcrime.securesms;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.AnimRes;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import org.thoughtcrime.securesms.components.ContactFilterToolbar;
import org.thoughtcrime.securesms.components.ContactFilterToolbar.OnFilterChangedListener;
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode;
import org.thoughtcrime.securesms.contacts.SelectedContact;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
import org.thoughtcrime.securesms.util.DynamicNoActionBarInviteTheme;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.ThemeUtil;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.WindowUtil;
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture.Listener;
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
import org.whispersystems.libsignal.util.guava.Optional;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class InviteActivity extends PassphraseRequiredActionBarActivity implements ContactSelectionListFragment.OnContactSelectedListener {
private ContactSelectionListFragment contactsFragment;
private EditText inviteText;
private ViewGroup smsSendFrame;
private Button smsSendButton;
private Animation slideInAnimation;
private Animation slideOutAnimation;
private DynamicTheme dynamicTheme = new DynamicNoActionBarInviteTheme();
private Toolbar primaryToolbar;
@Override
protected void onPreCreate() {
super.onPreCreate();
dynamicTheme.onCreate(this);
}
@Override
protected void onCreate(Bundle savedInstanceState, boolean ready) {
getIntent().putExtra(ContactSelectionListFragment.DISPLAY_MODE, DisplayMode.FLAG_SMS);
getIntent().putExtra(ContactSelectionListFragment.MULTI_SELECT, true);
getIntent().putExtra(ContactSelectionListFragment.REFRESHABLE, false);
setContentView(R.layout.invite_activity);
initializeAppBar();
initializeResources();
}
@Override
protected void onResume() {
super.onResume();
dynamicTheme.onResume(this);
}
private void initializeAppBar() {
primaryToolbar = findViewById(R.id.toolbar);
setSupportActionBar(primaryToolbar);
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(R.string.AndroidManifest__invite_friends);
}
private void initializeResources() {
slideInAnimation = loadAnimation(R.anim.slide_from_bottom);
slideOutAnimation = loadAnimation(R.anim.slide_to_bottom);
View shareButton = ViewUtil.findById(this, R.id.share_button);
View smsButton = ViewUtil.findById(this, R.id.sms_button);
Button smsCancelButton = ViewUtil.findById(this, R.id.cancel_sms_button);
ContactFilterToolbar contactFilter = ViewUtil.findById(this, R.id.contact_filter);
inviteText = ViewUtil.findById(this, R.id.invite_text);
smsSendFrame = ViewUtil.findById(this, R.id.sms_send_frame);
smsSendButton = ViewUtil.findById(this, R.id.send_sms_button);
contactsFragment = (ContactSelectionListFragment)getSupportFragmentManager().findFragmentById(R.id.contact_selection_list_fragment);
inviteText.setText(getString(R.string.InviteActivity_lets_switch_to_signal, getString(R.string.install_url)));
updateSmsButtonText();
contactsFragment.setOnContactSelectedListener(this);
shareButton.setOnClickListener(new ShareClickListener());
smsButton.setOnClickListener(new SmsClickListener());
smsCancelButton.setOnClickListener(new SmsCancelClickListener());
smsSendButton.setOnClickListener(new SmsSendClickListener());
contactFilter.setOnFilterChangedListener(new ContactFilterChangedListener());
contactFilter.setNavigationIcon(R.drawable.ic_search_conversation_24);
}
private Animation loadAnimation(@AnimRes int animResId) {
final Animation animation = AnimationUtils.loadAnimation(this, animResId);
animation.setInterpolator(new FastOutSlowInInterpolator());
return animation;
}
@Override
public void onContactSelected(Optional<RecipientId> recipientId, String number) {
updateSmsButtonText();
}
@Override
public void onContactDeselected(Optional<RecipientId> recipientId, String number) {
updateSmsButtonText();
}
private void sendSmsInvites() {
new SendSmsInvitesAsyncTask(this, inviteText.getText().toString())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
contactsFragment.getSelectedContacts()
.toArray(new SelectedContact[0]));
}
private void updateSmsButtonText() {
List<SelectedContact> selectedContacts = contactsFragment.getSelectedContacts();
smsSendButton.setText(getResources().getQuantityString(R.plurals.InviteActivity_send_sms_to_friends,
selectedContacts.size(),
selectedContacts.size()));
smsSendButton.setEnabled(!selectedContacts.isEmpty());
}
@Override public void onBackPressed() {
if (smsSendFrame.getVisibility() == View.VISIBLE) {
cancelSmsSelection();
} else {
super.onBackPressed();
}
}
private void cancelSmsSelection() {
setPrimaryColorsToolbarNormal();
contactsFragment.reset();
updateSmsButtonText();
ViewUtil.animateOut(smsSendFrame, slideOutAnimation, View.GONE);
}
private void setPrimaryColorsToolbarNormal() {
primaryToolbar.setBackgroundColor(0);
primaryToolbar.getNavigationIcon().setColorFilter(null);
primaryToolbar.setTitleTextColor(ThemeUtil.getThemedColor(this, R.attr.title_text_color_primary));
if (Build.VERSION.SDK_INT >= 23) {
getWindow().setStatusBarColor(ThemeUtil.getThemedColor(this, android.R.attr.statusBarColor));
getWindow().setNavigationBarColor(ThemeUtil.getThemedColor(this, android.R.attr.navigationBarColor));
WindowUtil.setLightStatusBarFromTheme(this);
}
WindowUtil.setLightNavigationBarFromTheme(this);
}
private void setPrimaryColorsToolbarForSms() {
primaryToolbar.setBackgroundColor(ContextCompat.getColor(this, R.color.core_ultramarine));
primaryToolbar.getNavigationIcon().setColorFilter(ThemeUtil.getThemedColor(this, R.attr.conversation_subtitle_color), PorterDuff.Mode.SRC_IN);
primaryToolbar.setTitleTextColor(ThemeUtil.getThemedColor(this, R.attr.conversation_title_color));
if (Build.VERSION.SDK_INT >= 23) {
getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.core_ultramarine));
WindowUtil.clearLightStatusBar(getWindow());
}
if (Build.VERSION.SDK_INT >= 27) {
getWindow().setNavigationBarColor(ContextCompat.getColor(this, R.color.core_ultramarine));
WindowUtil.clearLightNavigationBar(getWindow());
}
}
private class ShareClickListener implements OnClickListener {
@Override
public void onClick(View v) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, inviteText.getText().toString());
sendIntent.setType("text/plain");
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(Intent.createChooser(sendIntent, getString(R.string.InviteActivity_invite_to_signal)));
} else {
Toast.makeText(InviteActivity.this, R.string.InviteActivity_no_app_to_share_to, Toast.LENGTH_LONG).show();
}
}
}
private class SmsClickListener implements OnClickListener {
@Override
public void onClick(View v) {
setPrimaryColorsToolbarForSms();
ViewUtil.animateIn(smsSendFrame, slideInAnimation);
}
}
private class SmsCancelClickListener implements OnClickListener {
@Override
public void onClick(View v) {
cancelSmsSelection();
}
}
private class SmsSendClickListener implements OnClickListener {
@Override
public void onClick(View v) {
new AlertDialog.Builder(InviteActivity.this)
.setTitle(getResources().getQuantityString(R.plurals.InviteActivity_send_sms_invites,
contactsFragment.getSelectedContacts().size(),
contactsFragment.getSelectedContacts().size()))
.setMessage(inviteText.getText().toString())
.setPositiveButton(R.string.yes, (dialog, which) -> sendSmsInvites())
.setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss())
.show();
}
}
private class ContactFilterChangedListener implements OnFilterChangedListener {
@Override
public void onFilterChanged(String filter) {
contactsFragment.setQueryFilter(filter);
}
}
@SuppressLint("StaticFieldLeak")
private class SendSmsInvitesAsyncTask extends ProgressDialogAsyncTask<SelectedContact,Void,Void> {
private final String message;
SendSmsInvitesAsyncTask(Context context, String message) {
super(context, R.string.InviteActivity_sending, R.string.InviteActivity_sending);
this.message = message;
}
@Override
protected Void doInBackground(SelectedContact... contacts) {
final Context context = getContext();
if (context == null) return null;
for (SelectedContact contact : contacts) {
RecipientId recipientId = contact.getOrCreateRecipientId(context);
Recipient recipient = Recipient.resolved(recipientId);
int subscriptionId = recipient.getDefaultSubscriptionId().or(-1);
MessageSender.send(context, new OutgoingTextMessage(recipient, message, subscriptionId), -1L, true, null);
if (recipient.getContactUri() != null) {
DatabaseFactory.getRecipientDatabase(context).setHasSentInvite(recipient.getId());
}
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
final Context context = getContext();
if (context == null) return;
ViewUtil.animateOut(smsSendFrame, slideOutAnimation, View.GONE).addListener(new Listener<Boolean>() {
@Override
public void onSuccess(Boolean result) {
contactsFragment.reset();
}
@Override
public void onFailure(ExecutionException e) {}
});
Toast.makeText(context, R.string.InviteActivity_invitations_sent, Toast.LENGTH_LONG).show();
}
}
}

View File

@@ -0,0 +1,45 @@
package org.thoughtcrime.securesms;
import android.os.Bundle;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.DynamicTheme;
public class MainActivity extends PassphraseRequiredActionBarActivity {
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
private final MainNavigator navigator = new MainNavigator(this);
@Override
protected void onCreate(Bundle savedInstanceState, boolean ready) {
super.onCreate(savedInstanceState, ready);
setContentView(R.layout.main_activity);
navigator.onCreate(savedInstanceState);
}
@Override
protected void onPreCreate() {
super.onPreCreate();
dynamicTheme.onCreate(this);
}
@Override
protected void onResume() {
super.onResume();
dynamicTheme.onResume(this);
}
@Override
public void onBackPressed() {
if (!navigator.onBackPressed()) {
super.onBackPressed();
}
}
public @NonNull MainNavigator getNavigator() {
return navigator;
}
}

View File

@@ -0,0 +1,22 @@
package org.thoughtcrime.securesms;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
public class MainFragment extends Fragment {
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
if (!(requireActivity() instanceof MainActivity)) {
throw new IllegalStateException("Can only be used inside of MainActivity!");
}
}
protected @NonNull MainNavigator getNavigator() {
return MainNavigator.get(requireActivity());
}
}

View File

@@ -0,0 +1,104 @@
package org.thoughtcrime.securesms;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import org.thoughtcrime.securesms.conversation.ConversationActivity;
import org.thoughtcrime.securesms.conversationlist.ConversationListArchiveFragment;
import org.thoughtcrime.securesms.conversationlist.ConversationListFragment;
import org.thoughtcrime.securesms.groups.ui.creategroup.CreateGroupActivity;
import org.thoughtcrime.securesms.insights.InsightsLauncher;
import org.thoughtcrime.securesms.recipients.RecipientId;
public class MainNavigator {
private final MainActivity activity;
public MainNavigator(@NonNull MainActivity activity) {
this.activity = activity;
}
public static MainNavigator get(@NonNull Activity activity) {
if (!(activity instanceof MainActivity)) {
throw new IllegalArgumentException("Activity must be an instance of MainActivity!");
}
return ((MainActivity) activity).getNavigator();
}
public void onCreate(@Nullable Bundle savedInstanceState) {
if (savedInstanceState != null) {
return;
}
getFragmentManager().beginTransaction()
.add(R.id.fragment_container, ConversationListFragment.newInstance())
.commit();
}
/**
* @return True if the back pressed was handled in our own custom way, false if it should be given
* to the system to do the default behavior.
*/
public boolean onBackPressed() {
Fragment fragment = getFragmentManager().findFragmentById(R.id.fragment_container);
if (fragment instanceof BackHandler) {
return ((BackHandler) fragment).onBackPressed();
}
return false;
}
public void goToConversation(@NonNull RecipientId recipientId, long threadId, int distributionType, int startingPosition) {
Intent intent = ConversationActivity.buildIntent(activity, recipientId, threadId, distributionType, startingPosition);
activity.startActivity(intent);
activity.overridePendingTransition(R.anim.slide_from_end, R.anim.fade_scale_out);
}
public void goToAppSettings() {
Intent intent = new Intent(activity, ApplicationPreferencesActivity.class);
activity.startActivity(intent);
}
public void goToArchiveList() {
getFragmentManager().beginTransaction()
.setCustomAnimations(R.anim.slide_from_end, R.anim.slide_to_start, R.anim.slide_from_start, R.anim.slide_to_end)
.replace(R.id.fragment_container, ConversationListArchiveFragment.newInstance())
.addToBackStack(null)
.commit();
}
public void goToGroupCreation() {
activity.startActivity(CreateGroupActivity.newIntent(activity));
}
public void goToInvite() {
Intent intent = new Intent(activity, InviteActivity.class);
activity.startActivity(intent);
}
public void goToInsights() {
InsightsLauncher.showInsightsDashboard(activity.getSupportFragmentManager());
}
private @NonNull FragmentManager getFragmentManager() {
return activity.getSupportFragmentManager();
}
public interface BackHandler {
/**
* @return True if the back pressed was handled in our own custom way, false if it should be given
* to the system to do the default behavior.
*/
boolean onBackPressed();
}
}

View File

@@ -0,0 +1,809 @@
/*
* Copyright (C) 2014 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.util.Pair;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.lifecycle.ViewModelProviders;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.ViewPager;
import org.thoughtcrime.securesms.animation.DepthPageTransformer;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.components.viewpager.ExtendedOnPageChangedListener;
import org.thoughtcrime.securesms.database.MediaDatabase;
import org.thoughtcrime.securesms.database.MediaDatabase.MediaRecord;
import org.thoughtcrime.securesms.database.loaders.PagingMediaLoader;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mediaoverview.MediaOverviewActivity;
import org.thoughtcrime.securesms.mediapreview.MediaPreviewFragment;
import org.thoughtcrime.securesms.mediapreview.MediaPreviewViewModel;
import org.thoughtcrime.securesms.mediapreview.MediaRailAdapter;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.sharing.ShareActivity;
import org.thoughtcrime.securesms.util.AttachmentUtil;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
import org.thoughtcrime.securesms.util.SaveAttachmentTask.Attachment;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* Activity for displaying media attachments in-app
*/
public final class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
implements LoaderManager.LoaderCallbacks<Pair<Cursor, Integer>>,
MediaRailAdapter.RailItemListener,
MediaPreviewFragment.Events
{
private final static String TAG = MediaPreviewActivity.class.getSimpleName();
private static final int NOT_IN_A_THREAD = -2;
public static final String THREAD_ID_EXTRA = "thread_id";
public static final String DATE_EXTRA = "date";
public static final String SIZE_EXTRA = "size";
public static final String CAPTION_EXTRA = "caption";
public static final String LEFT_IS_RECENT_EXTRA = "left_is_recent";
public static final String HIDE_ALL_MEDIA_EXTRA = "came_from_all_media";
public static final String SHOW_THREAD_EXTRA = "show_thread";
public static final String SORTING_EXTRA = "sorting";
private ViewPager mediaPager;
private View detailsContainer;
private TextView caption;
private View captionContainer;
private RecyclerView albumRail;
private MediaRailAdapter albumRailAdapter;
private ViewGroup playbackControlsContainer;
private Uri initialMediaUri;
private String initialMediaType;
private long initialMediaSize;
private String initialCaption;
private boolean leftIsRecent;
private MediaPreviewViewModel viewModel;
private ViewPagerListener viewPagerListener;
private int restartItem = -1;
private long threadId = NOT_IN_A_THREAD;
private boolean cameFromAllMedia;
private boolean showThread;
private MediaDatabase.Sorting sorting;
public static @NonNull Intent intentFromMediaRecord(@NonNull Context context,
@NonNull MediaRecord mediaRecord,
boolean leftIsRecent)
{
Intent intent = new Intent(context, MediaPreviewActivity.class);
intent.putExtra(MediaPreviewActivity.THREAD_ID_EXTRA, mediaRecord.getThreadId());
intent.putExtra(MediaPreviewActivity.DATE_EXTRA, mediaRecord.getDate());
intent.putExtra(MediaPreviewActivity.SIZE_EXTRA, mediaRecord.getAttachment().getSize());
intent.putExtra(MediaPreviewActivity.CAPTION_EXTRA, mediaRecord.getAttachment().getCaption());
intent.putExtra(MediaPreviewActivity.LEFT_IS_RECENT_EXTRA, leftIsRecent);
intent.setDataAndType(mediaRecord.getAttachment().getDataUri(), mediaRecord.getContentType());
return intent;
}
@SuppressWarnings("ConstantConditions")
@Override
protected void onCreate(Bundle bundle, boolean ready) {
this.setTheme(R.style.TextSecure_MediaPreview);
setContentView(R.layout.media_preview_activity);
setSupportActionBar(findViewById(R.id.toolbar));
viewModel = ViewModelProviders.of(this).get(MediaPreviewViewModel.class);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
showSystemUI();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
initializeViews();
initializeResources();
initializeObservers();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
@Override
public void onRailItemClicked(int distanceFromActive) {
mediaPager.setCurrentItem(mediaPager.getCurrentItem() + distanceFromActive);
}
@Override
public void onRailItemDeleteClicked(int distanceFromActive) {
throw new UnsupportedOperationException("Callback unsupported.");
}
@SuppressWarnings("ConstantConditions")
private void initializeActionBar() {
MediaItem mediaItem = getCurrentMediaItem();
if (mediaItem != null) {
getSupportActionBar().setTitle(getTitleText(mediaItem));
getSupportActionBar().setSubtitle(getSubTitleText(mediaItem));
}
}
private @NonNull String getTitleText(@NonNull MediaItem mediaItem) {
String from;
if (mediaItem.outgoing) from = getString(R.string.MediaPreviewActivity_you);
else if (mediaItem.recipient != null) from = mediaItem.recipient.toShortString(this);
else from = "";
if (showThread) {
String to = null;
Recipient threadRecipient = mediaItem.threadRecipient;
if (threadRecipient != null) {
if (mediaItem.outgoing || threadRecipient.isGroup()) {
if (threadRecipient.isLocalNumber()) {
from = getString(R.string.note_to_self);
} else {
to = threadRecipient.toShortString(this);
}
} else {
to = getString(R.string.MediaPreviewActivity_you);
}
}
return to != null ? getString(R.string.MediaPreviewActivity_s_to_s, from, to)
: from;
} else {
return from;
}
}
private @NonNull String getSubTitleText(@NonNull MediaItem mediaItem) {
if (mediaItem.date > 0) {
return DateUtils.getExtendedRelativeTimeSpanString(this, Locale.getDefault(), mediaItem.date);
} else {
return getString(R.string.MediaPreviewActivity_draft);
}
}
@Override
public void onResume() {
super.onResume();
initializeMedia();
}
@Override
public void onPause() {
super.onPause();
restartItem = cleanupMedia();
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
initializeResources();
}
private void initializeViews() {
mediaPager = findViewById(R.id.media_pager);
mediaPager.setOffscreenPageLimit(1);
mediaPager.setPageTransformer(true, new DepthPageTransformer());
viewPagerListener = new ViewPagerListener();
mediaPager.addOnPageChangeListener(viewPagerListener);
albumRail = findViewById(R.id.media_preview_album_rail);
albumRailAdapter = new MediaRailAdapter(GlideApp.with(this), this, false);
albumRail.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
albumRail.setAdapter(albumRailAdapter);
detailsContainer = findViewById(R.id.media_preview_details_container);
caption = findViewById(R.id.media_preview_caption);
captionContainer = findViewById(R.id.media_preview_caption_container);
playbackControlsContainer = findViewById(R.id.media_preview_playback_controls_container);
View toolbarLayout = findViewById(R.id.toolbar_layout);
anchorMarginsToBottomInsets(detailsContainer);
anchorMarginsToTopInsets(toolbarLayout);
showAndHideWithSystemUI(getWindow(), detailsContainer, toolbarLayout);
}
private void initializeResources() {
Intent intent = getIntent();
threadId = intent.getLongExtra(THREAD_ID_EXTRA, NOT_IN_A_THREAD);
cameFromAllMedia = intent.getBooleanExtra(HIDE_ALL_MEDIA_EXTRA, false);
showThread = intent.getBooleanExtra(SHOW_THREAD_EXTRA, false);
sorting = MediaDatabase.Sorting.values()[intent.getIntExtra(SORTING_EXTRA, 0)];
initialMediaUri = intent.getData();
initialMediaType = intent.getType();
initialMediaSize = intent.getLongExtra(SIZE_EXTRA, 0);
initialCaption = intent.getStringExtra(CAPTION_EXTRA);
leftIsRecent = intent.getBooleanExtra(LEFT_IS_RECENT_EXTRA, false);
restartItem = -1;
}
private void initializeObservers() {
viewModel.getPreviewData().observe(this, previewData -> {
if (previewData == null || mediaPager == null || mediaPager.getAdapter() == null) {
return;
}
if (!((MediaItemAdapter) mediaPager.getAdapter()).hasFragmentFor(mediaPager.getCurrentItem())) {
Log.d(TAG, "MediaItemAdapter wasn't ready. Posting again...");
viewModel.resubmitPreviewData();
}
View playbackControls = ((MediaItemAdapter) mediaPager.getAdapter()).getPlaybackControls(mediaPager.getCurrentItem());
if (previewData.getAlbumThumbnails().isEmpty() && previewData.getCaption() == null && playbackControls == null) {
detailsContainer.setVisibility(View.GONE);
} else {
detailsContainer.setVisibility(View.VISIBLE);
}
albumRail.setVisibility(previewData.getAlbumThumbnails().isEmpty() ? View.GONE : View.VISIBLE);
albumRailAdapter.setMedia(previewData.getAlbumThumbnails(), previewData.getActivePosition());
albumRail.smoothScrollToPosition(previewData.getActivePosition());
captionContainer.setVisibility(previewData.getCaption() == null ? View.GONE : View.VISIBLE);
caption.setText(previewData.getCaption());
if (playbackControls != null) {
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
playbackControls.setLayoutParams(params);
playbackControlsContainer.removeAllViews();
playbackControlsContainer.addView(playbackControls);
} else {
playbackControlsContainer.removeAllViews();
}
});
}
private void initializeMedia() {
if (!isContentTypeSupported(initialMediaType)) {
Log.w(TAG, "Unsupported media type sent to MediaPreviewActivity, finishing.");
Toast.makeText(getApplicationContext(), R.string.MediaPreviewActivity_unssuported_media_type, Toast.LENGTH_LONG).show();
finish();
}
Log.i(TAG, "Loading Part URI: " + initialMediaUri);
if (isMediaInDb()) {
LoaderManager.getInstance(this).restartLoader(0, null, this);
} else {
mediaPager.setAdapter(new SingleItemPagerAdapter(getSupportFragmentManager(), initialMediaUri, initialMediaType, initialMediaSize));
if (initialCaption != null) {
detailsContainer.setVisibility(View.VISIBLE);
captionContainer.setVisibility(View.VISIBLE);
caption.setText(initialCaption);
}
}
}
private int cleanupMedia() {
int restartItem = mediaPager.getCurrentItem();
mediaPager.removeAllViews();
mediaPager.setAdapter(null);
return restartItem;
}
private void showOverview() {
startActivity(MediaOverviewActivity.forThread(this, threadId));
}
private void forward() {
MediaItem mediaItem = getCurrentMediaItem();
if (mediaItem != null) {
Intent composeIntent = new Intent(this, ShareActivity.class);
composeIntent.putExtra(Intent.EXTRA_STREAM, mediaItem.uri);
composeIntent.setType(mediaItem.type);
startActivity(composeIntent);
}
}
@SuppressWarnings("CodeBlock2Expr")
@SuppressLint("InlinedApi")
private void saveToDisk() {
MediaItem mediaItem = getCurrentMediaItem();
if (mediaItem != null) {
SaveAttachmentTask.showWarningDialog(this, (dialogInterface, i) -> {
Permissions.with(this)
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
.ifNecessary()
.withPermanentDenialDialog(getString(R.string.MediaPreviewActivity_signal_needs_the_storage_permission_in_order_to_write_to_external_storage_but_it_has_been_permanently_denied))
.onAnyDenied(() -> Toast.makeText(this, R.string.MediaPreviewActivity_unable_to_write_to_external_storage_without_permission, Toast.LENGTH_LONG).show())
.onAllGranted(() -> {
SaveAttachmentTask saveTask = new SaveAttachmentTask(MediaPreviewActivity.this);
long saveDate = (mediaItem.date > 0) ? mediaItem.date : System.currentTimeMillis();
saveTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Attachment(mediaItem.uri, mediaItem.type, saveDate, null));
})
.execute();
});
}
}
@SuppressLint("StaticFieldLeak")
private void deleteMedia() {
MediaItem mediaItem = getCurrentMediaItem();
if (mediaItem == null || mediaItem.attachment == null) {
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIconAttribute(R.attr.dialog_alert_icon);
builder.setTitle(R.string.MediaPreviewActivity_media_delete_confirmation_title);
builder.setMessage(R.string.MediaPreviewActivity_media_delete_confirmation_message);
builder.setCancelable(true);
builder.setPositiveButton(R.string.delete, (dialogInterface, which) -> {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
AttachmentUtil.deleteAttachment(MediaPreviewActivity.this.getApplicationContext(),
mediaItem.attachment);
return null;
}
}.execute();
finish();
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.clear();
MenuInflater inflater = this.getMenuInflater();
inflater.inflate(R.menu.media_preview, menu);
if (!isMediaInDb()) {
menu.findItem(R.id.media_preview__overview).setVisible(false);
menu.findItem(R.id.delete).setVisible(false);
}
if (cameFromAllMedia) {
menu.findItem(R.id.media_preview__overview).setVisible(false);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.media_preview__overview: showOverview(); return true;
case R.id.media_preview__forward: forward(); return true;
case R.id.save: saveToDisk(); return true;
case R.id.delete: deleteMedia(); return true;
case android.R.id.home: finish(); return true;
}
return false;
}
private boolean isMediaInDb() {
return threadId != NOT_IN_A_THREAD;
}
private @Nullable MediaItem getCurrentMediaItem() {
MediaItemAdapter adapter = (MediaItemAdapter)mediaPager.getAdapter();
if (adapter != null) {
return adapter.getMediaItemFor(mediaPager.getCurrentItem());
} else {
return null;
}
}
public static boolean isContentTypeSupported(final String contentType) {
return contentType != null && (contentType.startsWith("image/") || contentType.startsWith("video/"));
}
@Override
public @NonNull Loader<Pair<Cursor, Integer>> onCreateLoader(int id, Bundle args) {
return new PagingMediaLoader(this, threadId, initialMediaUri, leftIsRecent, sorting);
}
@Override
public void onLoadFinished(@NonNull Loader<Pair<Cursor, Integer>> loader, @Nullable Pair<Cursor, Integer> data) {
if (data != null) {
@SuppressWarnings("ConstantConditions")
CursorPagerAdapter adapter = new CursorPagerAdapter(getSupportFragmentManager(),this, data.first, data.second, leftIsRecent);
mediaPager.setAdapter(adapter);
adapter.setActive(true);
viewModel.setCursor(this, data.first, leftIsRecent);
int item = restartItem >= 0 ? restartItem : data.second;
mediaPager.setCurrentItem(item);
if (item == 0) {
viewPagerListener.onPageSelected(0);
}
}
}
@Override
public void onLoaderReset(@NonNull Loader<Pair<Cursor, Integer>> loader) {
}
@Override
public boolean singleTapOnMedia() {
toggleUiVisibility();
return true;
}
private void toggleUiVisibility() {
int systemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
if ((systemUiVisibility & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0) {
showSystemUI();
} else {
hideSystemUI();
}
}
private void hideSystemUI() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN );
}
private void showSystemUI() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN );
}
private class ViewPagerListener extends ExtendedOnPageChangedListener {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
MediaItemAdapter adapter = (MediaItemAdapter)mediaPager.getAdapter();
if (adapter != null) {
MediaItem item = adapter.getMediaItemFor(position);
if (item.recipient != null) item.recipient.live().observe(MediaPreviewActivity.this, r -> initializeActionBar());
viewModel.setActiveAlbumRailItem(MediaPreviewActivity.this, position);
initializeActionBar();
}
}
@Override
public void onPageUnselected(int position) {
MediaItemAdapter adapter = (MediaItemAdapter)mediaPager.getAdapter();
if (adapter != null) {
MediaItem item = adapter.getMediaItemFor(position);
if (item.recipient != null) item.recipient.live().removeObservers(MediaPreviewActivity.this);
adapter.pause(position);
}
}
}
private static class SingleItemPagerAdapter extends FragmentStatePagerAdapter implements MediaItemAdapter {
private final Uri uri;
private final String mediaType;
private final long size;
private MediaPreviewFragment mediaPreviewFragment;
SingleItemPagerAdapter(@NonNull FragmentManager fragmentManager,
@NonNull Uri uri,
@NonNull String mediaType,
long size)
{
super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.uri = uri;
this.mediaType = mediaType;
this.size = size;
}
@Override
public int getCount() {
return 1;
}
@NonNull
@Override
public Fragment getItem(int position) {
mediaPreviewFragment = MediaPreviewFragment.newInstance(uri, mediaType, size, true);
return mediaPreviewFragment;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
if (mediaPreviewFragment != null) {
mediaPreviewFragment.cleanUp();
mediaPreviewFragment = null;
}
}
@Override
public MediaItem getMediaItemFor(int position) {
return new MediaItem(null, null, null, uri, mediaType, -1, true);
}
@Override
public void pause(int position) {
if (mediaPreviewFragment != null) {
mediaPreviewFragment.pause();
}
}
@Override
public @Nullable View getPlaybackControls(int position) {
if (mediaPreviewFragment != null) {
return mediaPreviewFragment.getPlaybackControls();
}
return null;
}
@Override
public boolean hasFragmentFor(int position) {
return mediaPreviewFragment != null;
}
}
private static void anchorMarginsToBottomInsets(@NonNull View viewToAnchor) {
ViewCompat.setOnApplyWindowInsetsListener(viewToAnchor, (view, insets) -> {
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
layoutParams.setMargins(insets.getSystemWindowInsetLeft(),
layoutParams.topMargin,
insets.getSystemWindowInsetRight(),
insets.getSystemWindowInsetBottom());
view.setLayoutParams(layoutParams);
return insets;
});
}
private static void anchorMarginsToTopInsets(@NonNull View viewToAnchor) {
ViewCompat.setOnApplyWindowInsetsListener(viewToAnchor, (view, insets) -> {
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
layoutParams.setMargins(insets.getSystemWindowInsetLeft(),
insets.getSystemWindowInsetTop(),
insets.getSystemWindowInsetRight(),
layoutParams.bottomMargin);
view.setLayoutParams(layoutParams);
return insets;
});
}
private static void showAndHideWithSystemUI(@NonNull Window window, @NonNull View... views) {
window.getDecorView().setOnSystemUiVisibilityChangeListener(visibility -> {
boolean hide = (visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
for (View view : views) {
view.animate()
.alpha(hide ? 0 : 1)
.start();
}
});
}
private static class CursorPagerAdapter extends FragmentStatePagerAdapter implements MediaItemAdapter {
@SuppressLint("UseSparseArrays")
private final Map<Integer, MediaPreviewFragment> mediaFragments = new HashMap<>();
private final Context context;
private final Cursor cursor;
private final boolean leftIsRecent;
private boolean active;
private int autoPlayPosition;
CursorPagerAdapter(@NonNull FragmentManager fragmentManager,
@NonNull Context context,
@NonNull Cursor cursor,
int autoPlayPosition,
boolean leftIsRecent)
{
super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.context = context.getApplicationContext();
this.cursor = cursor;
this.autoPlayPosition = autoPlayPosition;
this.leftIsRecent = leftIsRecent;
}
public void setActive(boolean active) {
this.active = active;
notifyDataSetChanged();
}
@Override
public int getCount() {
if (!active) return 0;
else return cursor.getCount();
}
@NonNull
@Override
public Fragment getItem(int position) {
boolean autoPlay = autoPlayPosition == position;
int cursorPosition = getCursorPosition(position);
autoPlayPosition = -1;
cursor.moveToPosition(cursorPosition);
MediaDatabase.MediaRecord mediaRecord = MediaDatabase.MediaRecord.from(context, cursor);
DatabaseAttachment attachment = mediaRecord.getAttachment();
MediaPreviewFragment fragment = MediaPreviewFragment.newInstance(attachment, autoPlay);
mediaFragments.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
MediaPreviewFragment removed = mediaFragments.remove(position);
if (removed != null) {
removed.cleanUp();
}
super.destroyItem(container, position, object);
}
public MediaItem getMediaItemFor(int position) {
cursor.moveToPosition(getCursorPosition(position));
MediaRecord mediaRecord = MediaRecord.from(context, cursor);
RecipientId recipientId = mediaRecord.getRecipientId();
RecipientId threadRecipientId = mediaRecord.getThreadRecipientId();
if (mediaRecord.getAttachment().getDataUri() == null) throw new AssertionError();
return new MediaItem(Recipient.live(recipientId).get(),
Recipient.live(threadRecipientId).get(),
mediaRecord.getAttachment(),
mediaRecord.getAttachment().getDataUri(),
mediaRecord.getContentType(),
mediaRecord.getDate(),
mediaRecord.isOutgoing());
}
@Override
public void pause(int position) {
MediaPreviewFragment mediaView = mediaFragments.get(position);
if (mediaView != null) mediaView.pause();
}
@Override
public @Nullable View getPlaybackControls(int position) {
MediaPreviewFragment mediaView = mediaFragments.get(position);
if (mediaView != null) return mediaView.getPlaybackControls();
return null;
}
@Override
public boolean hasFragmentFor(int position) {
return mediaFragments.containsKey(position);
}
private int getCursorPosition(int position) {
if (leftIsRecent) return position;
else return cursor.getCount() - 1 - position;
}
}
private static class MediaItem {
private final @Nullable Recipient recipient;
private final @Nullable Recipient threadRecipient;
private final @Nullable DatabaseAttachment attachment;
private final @NonNull Uri uri;
private final @NonNull String type;
private final long date;
private final boolean outgoing;
private MediaItem(@Nullable Recipient recipient,
@Nullable Recipient threadRecipient,
@Nullable DatabaseAttachment attachment,
@NonNull Uri uri,
@NonNull String type,
long date,
boolean outgoing)
{
this.recipient = recipient;
this.threadRecipient = threadRecipient;
this.attachment = attachment;
this.uri = uri;
this.type = type;
this.date = date;
this.outgoing = outgoing;
}
}
interface MediaItemAdapter {
MediaItem getMediaItemFor(int position);
void pause(int position);
@Nullable View getPlaybackControls(int position);
boolean hasFragmentFor(int position);
}
}

View File

@@ -0,0 +1,451 @@
/*
* Copyright (C) 2015 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.database.Cursor;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.loader.app.LoaderManager.LoaderCallbacks;
import androidx.loader.content.Loader;
import org.thoughtcrime.securesms.conversation.ConversationItem;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.logging.Log;
import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;
import org.thoughtcrime.securesms.MessageDetailsRecipientAdapter.RecipientDeliveryStatus;
import org.thoughtcrime.securesms.color.MaterialColor;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
import org.thoughtcrime.securesms.database.GroupReceiptDatabase.GroupReceiptInfo;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.loaders.MessageDetailsLoader;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.recipients.LiveRecipient;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.DynamicDarkActionBarTheme;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.ExpirationUtil;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
import org.whispersystems.libsignal.util.guava.Optional;
import java.lang.ref.WeakReference;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
/**
* @author Jake McGinty
*/
public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity implements LoaderCallbacks<Cursor> {
private final static String TAG = MessageDetailsActivity.class.getSimpleName();
public static final String MESSAGE_ID_EXTRA = "message_id";
public static final String THREAD_ID_EXTRA = "thread_id";
public static final String IS_PUSH_GROUP_EXTRA = "is_push_group";
public static final String TYPE_EXTRA = "type";
public static final String RECIPIENT_EXTRA = "recipient_id";
private GlideRequests glideRequests;
private long threadId;
private boolean isPushGroup;
private ConversationItem conversationItem;
private ViewGroup itemParent;
private View metadataContainer;
private View expiresContainer;
private TextView errorText;
private View resendButton;
private TextView sentDate;
private TextView receivedDate;
private TextView expiresInText;
private View receivedContainer;
private TextView transport;
private TextView toFrom;
private ListView recipientsList;
private LayoutInflater inflater;
private DynamicTheme dynamicTheme = new DynamicDarkActionBarTheme();
private DynamicLanguage dynamicLanguage = new DynamicLanguage();
private boolean running;
@Override
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
}
@Override
public void onCreate(Bundle bundle, boolean ready) {
setContentView(R.layout.message_details_activity);
running = true;
initializeResources();
initializeActionBar();
getSupportLoaderManager().initLoader(0, null, this);
}
@Override
protected void onResume() {
super.onResume();
dynamicTheme.onResume(this);
dynamicLanguage.onResume(this);
assert getSupportActionBar() != null;
getSupportActionBar().setTitle(R.string.AndroidManifest__message_details);
ApplicationDependencies.getMessageNotifier().setVisibleThread(threadId);
}
@Override
protected void onPause() {
super.onPause();
ApplicationDependencies.getMessageNotifier().clearVisibleThread();
}
@Override
protected void onDestroy() {
super.onDestroy();
running = false;
}
private void initializeActionBar() {
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
LiveRecipient recipient = Recipient.live(getIntent().getParcelableExtra(RECIPIENT_EXTRA));
recipient.observe(this, r -> setActionBarColor(r.getColor()));
setActionBarColor(recipient.get().getColor());
}
private void setActionBarColor(MaterialColor color) {
assert getSupportActionBar() != null;
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(color.toActionBarColor(this)));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(color.toStatusBarColor(this));
}
}
private void initializeResources() {
inflater = LayoutInflater.from(this);
View header = inflater.inflate(R.layout.message_details_header, recipientsList, false);
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
isPushGroup = getIntent().getBooleanExtra(IS_PUSH_GROUP_EXTRA, false);
glideRequests = GlideApp.with(this);
itemParent = header.findViewById(R.id.item_container);
recipientsList = findViewById(R.id.recipients_list);
metadataContainer = header.findViewById(R.id.metadata_container);
errorText = header.findViewById(R.id.error_text);
resendButton = header.findViewById(R.id.resend_button);
sentDate = header.findViewById(R.id.sent_time);
receivedContainer = header.findViewById(R.id.received_container);
receivedDate = header.findViewById(R.id.received_time);
transport = header.findViewById(R.id.transport);
toFrom = header.findViewById(R.id.tofrom);
expiresContainer = header.findViewById(R.id.expires_container);
expiresInText = header.findViewById(R.id.expires_in);
recipientsList.setHeaderDividersEnabled(false);
recipientsList.addHeaderView(header, null, false);
}
private void updateTransport(MessageRecord messageRecord) {
final String transportText;
if (messageRecord.isOutgoing() && messageRecord.isFailed()) {
transportText = "-";
} else if (messageRecord.isPending()) {
transportText = getString(R.string.ConversationFragment_pending);
} else if (messageRecord.isPush()) {
transportText = getString(R.string.ConversationFragment_push);
} else if (messageRecord.isMms()) {
transportText = getString(R.string.ConversationFragment_mms);
} else {
transportText = getString(R.string.ConversationFragment_sms);
}
transport.setText(transportText);
}
private void updateTime(MessageRecord messageRecord) {
sentDate.setOnLongClickListener(null);
receivedDate.setOnLongClickListener(null);
if (messageRecord.isPending() || messageRecord.isFailed()) {
sentDate.setText("-");
receivedContainer.setVisibility(View.GONE);
} else {
Locale dateLocale = dynamicLanguage.getCurrentLocale();
SimpleDateFormat dateFormatter = DateUtils.getDetailedDateFormatter(this, dateLocale);
sentDate.setText(dateFormatter.format(new Date(messageRecord.getDateSent())));
sentDate.setOnLongClickListener(v -> {
copyToClipboard(String.valueOf(messageRecord.getDateSent()));
return true;
});
if (messageRecord.getDateReceived() != messageRecord.getDateSent() && !messageRecord.isOutgoing()) {
receivedDate.setText(dateFormatter.format(new Date(messageRecord.getDateReceived())));
receivedDate.setOnLongClickListener(v -> {
copyToClipboard(String.valueOf(messageRecord.getDateReceived()));
return true;
});
receivedContainer.setVisibility(View.VISIBLE);
} else {
receivedContainer.setVisibility(View.GONE);
}
}
}
private void updateExpirationTime(final MessageRecord messageRecord) {
if (messageRecord.getExpiresIn() <= 0 || messageRecord.getExpireStarted() <= 0) {
expiresContainer.setVisibility(View.GONE);
return;
}
expiresContainer.setVisibility(View.VISIBLE);
Util.runOnMain(new Runnable() {
@Override
public void run() {
long elapsed = System.currentTimeMillis() - messageRecord.getExpireStarted();
long remaining = messageRecord.getExpiresIn() - elapsed;
String duration = ExpirationUtil.getExpirationDisplayValue(MessageDetailsActivity.this, Math.max((int)(remaining / 1000), 1));
expiresInText.setText(duration);
if (running) {
Util.runOnMainDelayed(this, 500);
}
}
});
}
private void updateRecipients(MessageRecord messageRecord, Recipient recipient, List<RecipientDeliveryStatus> recipients) {
final int toFromRes;
if (messageRecord.isMms() && !messageRecord.isPush() && !messageRecord.isOutgoing()) {
toFromRes = R.string.message_details_header__with;
} else if (messageRecord.isOutgoing()) {
toFromRes = R.string.message_details_header__to;
} else {
toFromRes = R.string.message_details_header__from;
}
toFrom.setText(toFromRes);
conversationItem.bind(messageRecord, Optional.absent(), Optional.absent(), glideRequests, dynamicLanguage.getCurrentLocale(), new HashSet<>(), recipient, null, false);
Parcelable state = recipientsList.onSaveInstanceState();
recipientsList.setAdapter(new MessageDetailsRecipientAdapter(this, glideRequests, messageRecord, recipients, isPushGroup));
recipientsList.onRestoreInstanceState(state);
}
private void inflateMessageViewIfAbsent(MessageRecord messageRecord) {
if (conversationItem == null) {
if (messageRecord.isGroupAction()) {
conversationItem = (ConversationItem) inflater.inflate(R.layout.conversation_item_update, itemParent, false);
} else if (messageRecord.isOutgoing()) {
conversationItem = (ConversationItem) inflater.inflate(R.layout.conversation_item_sent_multimedia, itemParent, false);
} else {
conversationItem = (ConversationItem) inflater.inflate(R.layout.conversation_item_received_multimedia, itemParent, false);
}
itemParent.addView(conversationItem);
}
}
private @Nullable MessageRecord getMessageRecord(Context context, Cursor cursor, String type) {
switch (type) {
case MmsSmsDatabase.SMS_TRANSPORT:
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context);
SmsDatabase.Reader reader = smsDatabase.readerFor(cursor);
return reader.getNext();
case MmsSmsDatabase.MMS_TRANSPORT:
MmsDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context);
MmsDatabase.Reader mmsReader = mmsDatabase.readerFor(cursor);
return mmsReader.getNext();
default:
throw new AssertionError("no valid message type specified");
}
}
private void copyToClipboard(@NonNull String text) {
((ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText("text", text));
}
@Override
public @NonNull Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new MessageDetailsLoader(this, getIntent().getStringExtra(TYPE_EXTRA),
getIntent().getLongExtra(MESSAGE_ID_EXTRA, -1));
}
@Override
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor cursor) {
MessageRecord messageRecord = getMessageRecord(this, cursor, getIntent().getStringExtra(TYPE_EXTRA));
if (messageRecord == null) {
finish();
} else {
new MessageRecipientAsyncTask(this, messageRecord).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
@Override
public void onLoaderReset(@NonNull Loader<Cursor> loader) {
recipientsList.setAdapter(null);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case android.R.id.home: finish(); return true;
}
return false;
}
@SuppressLint("StaticFieldLeak")
private class MessageRecipientAsyncTask extends AsyncTask<Void,Void,List<RecipientDeliveryStatus>> {
private final WeakReference<Context> weakContext;
private final MessageRecord messageRecord;
MessageRecipientAsyncTask(@NonNull Context context, @NonNull MessageRecord messageRecord) {
this.weakContext = new WeakReference<>(context);
this.messageRecord = messageRecord;
}
protected Context getContext() {
return weakContext.get();
}
@Override
public List<RecipientDeliveryStatus> doInBackground(Void... voids) {
Context context = getContext();
if (context == null) {
Log.w(TAG, "associated context is destroyed, finishing early");
return null;
}
List<RecipientDeliveryStatus> recipients = new LinkedList<>();
if (!messageRecord.getRecipient().isGroup()) {
recipients.add(new RecipientDeliveryStatus(messageRecord.getRecipient(), getStatusFor(messageRecord.getDeliveryReceiptCount(), messageRecord.getReadReceiptCount(), messageRecord.isPending()), messageRecord.isUnidentified(), -1));
} else {
List<GroupReceiptInfo> receiptInfoList = DatabaseFactory.getGroupReceiptDatabase(context).getGroupReceiptInfo(messageRecord.getId());
if (receiptInfoList.isEmpty()) {
List<Recipient> group = DatabaseFactory.getGroupDatabase(context).getGroupMembers(messageRecord.getRecipient().requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF);
for (Recipient recipient : group) {
recipients.add(new RecipientDeliveryStatus(recipient, RecipientDeliveryStatus.Status.UNKNOWN, false, -1));
}
} else {
for (GroupReceiptInfo info : receiptInfoList) {
recipients.add(new RecipientDeliveryStatus(Recipient.resolved(info.getRecipientId()),
getStatusFor(info.getStatus(), messageRecord.isPending(), messageRecord.isFailed()),
info.isUnidentified(),
info.getTimestamp()));
}
}
}
return recipients;
}
@Override
public void onPostExecute(List<RecipientDeliveryStatus> recipients) {
if (getContext() == null) {
Log.w(TAG, "AsyncTask finished with a destroyed context, leaving early.");
return;
}
inflateMessageViewIfAbsent(messageRecord);
updateRecipients(messageRecord, messageRecord.getRecipient(), recipients);
boolean isGroupNetworkFailure = messageRecord.isFailed() && !messageRecord.getNetworkFailures().isEmpty();
boolean isIndividualNetworkFailure = messageRecord.isFailed() && !isPushGroup && messageRecord.getIdentityKeyMismatches().isEmpty();
if (isGroupNetworkFailure || isIndividualNetworkFailure) {
errorText.setVisibility(View.VISIBLE);
resendButton.setVisibility(View.VISIBLE);
resendButton.setOnClickListener(this::onResendClicked);
metadataContainer.setVisibility(View.GONE);
} else if (messageRecord.isFailed()) {
errorText.setVisibility(View.VISIBLE);
resendButton.setVisibility(View.GONE);
resendButton.setOnClickListener(null);
metadataContainer.setVisibility(View.GONE);
} else {
updateTransport(messageRecord);
updateTime(messageRecord);
updateExpirationTime(messageRecord);
errorText.setVisibility(View.GONE);
resendButton.setVisibility(View.GONE);
resendButton.setOnClickListener(null);
metadataContainer.setVisibility(View.VISIBLE);
}
}
private RecipientDeliveryStatus.Status getStatusFor(int deliveryReceiptCount, int readReceiptCount, boolean pending) {
if (readReceiptCount > 0) return RecipientDeliveryStatus.Status.READ;
else if (deliveryReceiptCount > 0) return RecipientDeliveryStatus.Status.DELIVERED;
else if (!pending) return RecipientDeliveryStatus.Status.SENT;
else return RecipientDeliveryStatus.Status.PENDING;
}
private RecipientDeliveryStatus.Status getStatusFor(int groupStatus, boolean pending, boolean failed) {
if (groupStatus == GroupReceiptDatabase.STATUS_READ) return RecipientDeliveryStatus.Status.READ;
else if (groupStatus == GroupReceiptDatabase.STATUS_DELIVERED) return RecipientDeliveryStatus.Status.DELIVERED;
else if (groupStatus == GroupReceiptDatabase.STATUS_UNDELIVERED && failed) return RecipientDeliveryStatus.Status.UNKNOWN;
else if (groupStatus == GroupReceiptDatabase.STATUS_UNDELIVERED && !pending) return RecipientDeliveryStatus.Status.SENT;
else if (groupStatus == GroupReceiptDatabase.STATUS_UNDELIVERED) return RecipientDeliveryStatus.Status.PENDING;
else if (groupStatus == GroupReceiptDatabase.STATUS_UNKNOWN) return RecipientDeliveryStatus.Status.UNKNOWN;
throw new AssertionError();
}
private void onResendClicked(View v) {
resendButton.setVisibility(View.GONE);
SignalExecutors.BOUNDED.execute(() -> MessageSender.resend(MessageDetailsActivity.this, messageRecord));
}
}
}

View File

@@ -0,0 +1,112 @@
package org.thoughtcrime.securesms;
import android.content.Context;
import androidx.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.Conversions;
import org.thoughtcrime.securesms.util.adapter.StableIdGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
class MessageDetailsRecipientAdapter extends BaseAdapter implements AbsListView.RecyclerListener {
private final Context context;
private final GlideRequests glideRequests;
private final MessageRecord record;
private final List<RecipientDeliveryStatus> members;
private final boolean isPushGroup;
private final StableIdGenerator<RecipientId> idGenerator;
MessageDetailsRecipientAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests,
@NonNull MessageRecord record, @NonNull List<RecipientDeliveryStatus> members,
boolean isPushGroup)
{
this.context = context;
this.glideRequests = glideRequests;
this.record = record;
this.isPushGroup = isPushGroup;
this.members = members;
this.idGenerator = new StableIdGenerator<>();
}
@Override
public int getCount() {
return members.size();
}
@Override
public Object getItem(int position) {
return members.get(position);
}
@Override
public long getItemId(int position) {
return idGenerator.getId(members.get(position).recipient.getId());
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.message_recipient_list_item, parent, false);
}
RecipientDeliveryStatus member = members.get(position);
((MessageRecipientListItem)convertView).set(glideRequests, record, member, isPushGroup);
return convertView;
}
@Override
public void onMovedToScrapHeap(View view) {
((MessageRecipientListItem)view).unbind();
}
static class RecipientDeliveryStatus {
enum Status {
UNKNOWN, PENDING, SENT, DELIVERED, READ
}
private final Recipient recipient;
private final Status deliveryStatus;
private final boolean isUnidentified;
private final long timestamp;
RecipientDeliveryStatus(Recipient recipient, Status deliveryStatus, boolean isUnidentified, long timestamp) {
this.recipient = recipient;
this.deliveryStatus = deliveryStatus;
this.isUnidentified = isUnidentified;
this.timestamp = timestamp;
}
Status getDeliveryStatus() {
return deliveryStatus;
}
boolean isUnidentified() {
return isUnidentified;
}
public long getTimestamp() {
return timestamp;
}
public Recipient getRecipient() {
return recipient;
}
}
}

View File

@@ -0,0 +1,200 @@
/*
* Copyright (C) 2014 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.MessageDetailsRecipientAdapter.RecipientDeliveryStatus;
import org.thoughtcrime.securesms.components.AvatarImageView;
import org.thoughtcrime.securesms.components.DeliveryStatusView;
import org.thoughtcrime.securesms.components.FromTextView;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
/**
* A simple view to show the recipients of a message
*
* @author Jake McGinty
*/
public class MessageRecipientListItem extends RelativeLayout
implements RecipientForeverObserver
{
@SuppressWarnings("unused")
private final static String TAG = MessageRecipientListItem.class.getSimpleName();
private RecipientDeliveryStatus member;
private GlideRequests glideRequests;
private FromTextView fromView;
private TextView errorDescription;
private TextView actionDescription;
private Button conflictButton;
private AvatarImageView contactPhotoImage;
private ImageView unidentifiedDeliveryIcon;
private DeliveryStatusView deliveryStatusView;
public MessageRecipientListItem(Context context) {
super(context);
}
public MessageRecipientListItem(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
this.fromView = findViewById(R.id.from);
this.errorDescription = findViewById(R.id.error_description);
this.actionDescription = findViewById(R.id.action_description);
this.contactPhotoImage = findViewById(R.id.contact_photo_image);
this.conflictButton = findViewById(R.id.conflict_button);
this.unidentifiedDeliveryIcon = findViewById(R.id.ud_indicator);
this.deliveryStatusView = findViewById(R.id.delivery_status);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
observeMember();
}
@Override
protected void onDetachedFromWindow() {
unsubscribeFromMember();
super.onDetachedFromWindow();
}
public void set(final GlideRequests glideRequests,
final MessageRecord record,
final RecipientDeliveryStatus member,
final boolean isPushGroup)
{
unsubscribeFromMember();
this.glideRequests = glideRequests;
this.member = member;
observeMember();
fromView.setText(member.getRecipient());
contactPhotoImage.setAvatar(glideRequests, member.getRecipient(), false);
setIssueIndicators(record, isPushGroup);
unidentifiedDeliveryIcon.setVisibility(TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(getContext()) && member.isUnidentified() ? VISIBLE : GONE);
}
private void observeMember() {
if (isAttachedToWindow() && member != null && member.getRecipient() != null) {
member.getRecipient().live().observeForever(this);
}
}
private void unsubscribeFromMember() {
if (member != null && member.getRecipient() != null) member.getRecipient().live().removeForeverObserver(this);
}
private void setIssueIndicators(final MessageRecord record,
final boolean isPushGroup)
{
final NetworkFailure networkFailure = getNetworkFailure(record);
final IdentityKeyMismatch keyMismatch = networkFailure == null ? getKeyMismatch(record) : null;
String errorText = "";
if (keyMismatch != null) {
conflictButton.setVisibility(View.VISIBLE);
errorText = getContext().getString(R.string.MessageDetailsRecipient_new_safety_number);
conflictButton.setOnClickListener(v -> new ConfirmIdentityDialog(getContext(), record, keyMismatch).show());
} else if ((networkFailure != null && !record.isPending()) || (!isPushGroup && record.isFailed())) {
conflictButton.setVisibility(View.GONE);
errorText = getContext().getString(R.string.MessageDetailsRecipient_failed_to_send);
} else {
if (record.isOutgoing()) {
if (member.getDeliveryStatus() == RecipientDeliveryStatus.Status.PENDING || member.getDeliveryStatus() == RecipientDeliveryStatus.Status.UNKNOWN) {
deliveryStatusView.setVisibility(View.GONE);
} else if (member.getDeliveryStatus() == RecipientDeliveryStatus.Status.READ) {
deliveryStatusView.setRead();
deliveryStatusView.setVisibility(View.VISIBLE);
} else if (member.getDeliveryStatus() == RecipientDeliveryStatus.Status.DELIVERED) {
deliveryStatusView.setDelivered();
deliveryStatusView.setVisibility(View.VISIBLE);
} else if (member.getDeliveryStatus() == RecipientDeliveryStatus.Status.SENT) {
deliveryStatusView.setSent();
deliveryStatusView.setVisibility(View.VISIBLE);
}
} else {
deliveryStatusView.setVisibility(View.GONE);
}
conflictButton.setVisibility(View.GONE);
}
errorDescription.setText(errorText);
errorDescription.setVisibility(TextUtils.isEmpty(errorText) ? View.GONE : View.VISIBLE);
}
private NetworkFailure getNetworkFailure(final MessageRecord record) {
if (record.hasNetworkFailures()) {
for (final NetworkFailure failure : record.getNetworkFailures()) {
if (failure.getRecipientId(getContext()).equals(member.getRecipient().getId())) {
return failure;
}
}
}
return null;
}
private IdentityKeyMismatch getKeyMismatch(final MessageRecord record) {
if (record.isIdentityMismatchFailure()) {
for (final IdentityKeyMismatch mismatch : record.getIdentityKeyMismatches()) {
if (mismatch.getRecipientId(getContext()).equals(member.getRecipient().getId())) {
return mismatch;
}
}
}
return null;
}
public void unbind() {
unsubscribeFromMember();
}
@Override
public void onRecipientChanged(@NonNull Recipient recipient) {
if (this.member != null && this.member.getRecipient().equals(recipient)) {
Log.d(TAG, "onRecipientChanged -- valid");
fromView.setText(recipient);
contactPhotoImage.setAvatar(glideRequests, recipient, false);
} else {
Log.d(TAG, "onRecipientChanged -- invalid");
}
}
}

View File

@@ -1,9 +1,11 @@
package org.thoughtcrime.securesms;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import java.util.concurrent.TimeUnit;
@@ -23,6 +25,10 @@ public class MuteDialog extends AlertDialog {
}
public static void show(final Context context, final @NonNull MuteSelectionListener listener) {
show(context, listener, null);
}
public static void show(final Context context, final @NonNull MuteSelectionListener listener, @Nullable Runnable cancelListener) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.MuteDialog_mute_notifications);
builder.setItems(R.array.mute_durations, new DialogInterface.OnClickListener() {
@@ -43,6 +49,13 @@ public class MuteDialog extends AlertDialog {
}
});
if (cancelListener != null) {
builder.setOnCancelListener(dialog -> {
cancelListener.run();
dialog.dismiss();
});
}
builder.show();
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2015 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import org.thoughtcrime.securesms.conversation.ConversationActivity;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.groups.ui.creategroup.CreateGroupActivity;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.whispersystems.libsignal.util.guava.Optional;
/**
* Activity container for starting a new conversation.
*
* @author Moxie Marlinspike
*
*/
public class NewConversationActivity extends ContactSelectionActivity
implements ContactSelectionListFragment.ListCallback
{
@SuppressWarnings("unused")
private static final String TAG = NewConversationActivity.class.getSimpleName();
@Override
public void onCreate(Bundle bundle, boolean ready) {
super.onCreate(bundle, ready);
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public void onContactSelected(Optional<RecipientId> recipientId, String number) {
Recipient recipient;
if (recipientId.isPresent()) {
recipient = Recipient.resolved(recipientId.get());
} else {
Log.i(TAG, "[onContactSelected] Maybe creating a new recipient.");
recipient = Recipient.external(this, number);
}
launch(recipient);
}
private void launch(Recipient recipient) {
Intent intent = new Intent(this, ConversationActivity.class);
intent.putExtra(ConversationActivity.RECIPIENT_EXTRA, recipient.getId());
intent.putExtra(ConversationActivity.TEXT_EXTRA, getIntent().getStringExtra(ConversationActivity.TEXT_EXTRA));
intent.setDataAndType(getIntent().getData(), getIntent().getType());
long existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient);
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, existingThread);
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
startActivity(intent);
finish();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case android.R.id.home: super.onBackPressed(); return true;
case R.id.menu_refresh: handleManualRefresh(); return true;
case R.id.menu_new_group: handleCreateGroup(); return true;
case R.id.menu_invite: handleInvite(); return true;
}
return false;
}
private void handleManualRefresh() {
contactsFragment.setRefreshing(true);
onRefresh();
}
private void handleCreateGroup() {
startActivity(CreateGroupActivity.newIntent(this));
}
private void handleInvite() {
startActivity(new Intent(this, InviteActivity.class));
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
getMenuInflater().inflate(R.menu.new_conversation_activity, menu);
super.onPrepareOptionsMenu(menu);
return true;
}
@Override
public void onInvite() {
handleInvite();
finish();
}
@Override
public void onNewGroup(boolean forceV1) {
handleCreateGroup();
finish();
}
}

View File

@@ -21,7 +21,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.service.KeyCachingService;
@@ -34,6 +34,8 @@ import org.thoughtcrime.securesms.service.KeyCachingService;
*/
public abstract class PassphraseActivity extends BaseActionBarActivity {
private static final String TAG = PassphraseActivity.class.getSimpleName();
private KeyCachingService keyCachingService;
private MasterSecret masterSecret;
@@ -62,8 +64,7 @@ public abstract class PassphraseActivity extends BaseActionBarActivity {
try {
startActivity(nextIntent);
} catch (java.lang.SecurityException e) {
Log.w("PassphraseActivity",
"Access permission not passed from PassphraseActivity, retry sharing.");
Log.w(TAG, "Access permission not passed from PassphraseActivity, retry sharing.");
}
}
finish();

View File

@@ -20,7 +20,7 @@ import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.util.Log;
import org.thoughtcrime.securesms.logging.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
@@ -41,6 +41,8 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
public class PassphraseChangeActivity extends PassphraseActivity {
private static final String TAG = Log.tag(PassphraseChangeActivity.class);
private DynamicTheme dynamicTheme = new DynamicTheme();
private DynamicLanguage dynamicLanguage = new DynamicLanguage();
@@ -108,7 +110,7 @@ public class PassphraseChangeActivity extends PassphraseActivity {
this.newPassphrase.setError(getString(R.string.PassphraseChangeActivity_enter_new_passphrase_exclamation));
this.newPassphrase.requestFocus();
} else {
new ChangePassphraseTask(this).execute(original, passphrase);
new ChangePassphraseTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, original, passphrase);
}
}
@@ -145,7 +147,7 @@ public class PassphraseChangeActivity extends PassphraseActivity {
return masterSecret;
} catch (InvalidPassphraseException e) {
Log.w(PassphraseChangeActivity.class.getSimpleName(), e);
Log.w(TAG, e);
return null;
}
}

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