Page MenuHomePhabricator

Increase min code version so that we can safely ignore unconvenient android notification structure edge case
ClosedPublic

Authored by marcin on Aug 3 2022, 7:30 AM.
Tags
None
Referenced Files
F3376631: D4732.id15311.diff
Wed, Nov 27, 1:24 AM
F3376551: D4732.id15804.diff
Wed, Nov 27, 12:56 AM
F3375926: D4732.diff
Tue, Nov 26, 9:26 PM
Unknown Object (File)
Sat, Nov 23, 11:51 AM
Unknown Object (File)
Sat, Nov 23, 8:55 AM
Unknown Object (File)
Sat, Nov 23, 8:49 AM
Unknown Object (File)
Sat, Nov 23, 8:48 AM
Unknown Object (File)
Sat, Nov 23, 8:43 AM

Details

Summary

This differential increases minimal code version so that we can safely drop support for 'custom_notification' field in Android notification and thus make code simpler

Test Plan

Since code version below 31 is considered very old, we should expect that nothing happens and application cotinues to work correctly both in debug and production builds

Diff Detail

Repository
rCOMM Comm
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

Rebase to include differential link in commit description

marcin requested review of this revision.Aug 3 2022, 7:51 AM
tomek requested changes to this revision.Aug 3 2022, 9:51 AM
tomek added inline comments.
keyserver/src/session/version.js
13 ↗(On Diff #15266)

Have you verified that all the places with older versions were cleaned?

This revision now requires changes to proceed.Aug 3 2022, 9:51 AM

As @tomek suggests, you should go through the codebase and find all cases where we check if the codeVersion is 32 or lower, and remove those cases. You can probably just add all of those to this same diff, no need for a separate diff in this case. I would also include the changes to keyserver/src/push/send.js to remove the case there (currently in D4643).

Remove dependencies on code version below 31

@ashoat I decided to continue looping in the case of an older android version in rescind.js. But I am wondering if we can just omit the else if for this. I am not sure whether it is possible that delivery attribute of notifications table row can have both androidID and deviceType === 'android' set? Or are those mutually exclusive? If yes then we can remove the check. If not we need the check and continue looping. delivery attribute is a JSON field so I am not sure how do we structure this.

tomek requested changes to this revision.Aug 4 2022, 5:15 AM

Please check all the usages of hasMinCodeVersion. There's at least one more - we're checking version 30 there.

This revision now requires changes to proceed.Aug 4 2022, 5:15 AM

Bump code version in multimedia-message-specs

I run git grep --ignore-case codeVersion. Apart from recently updated multimedia-message-spec.js no other file checks for code version lower than 32.

ashoat requested changes to this revision.Aug 4 2022, 10:15 PM
ashoat added inline comments.
keyserver/src/push/rescind.js
75–76 ↗(On Diff #15311)

Why was this change made?

lib/shared/messages/multimedia-message-spec.js
195 ↗(On Diff #15311)

Why did we increase the number here?

This revision now requires changes to proceed.Aug 4 2022, 10:15 PM
marcin requested review of this revision.Aug 5 2022, 4:08 AM
keyserver/src/push/rescind.js
75–76 ↗(On Diff #15311)

I have mentioned this change here:

@ashoat I decided to continue looping in the case of an older android version in rescind.js. But I am wondering if we can just omit the else if for this. I am not sure whether it is possible that delivery attribute of notifications table row can have both androidID and deviceType === 'android' set? Or are those mutually exclusive? If yes then we can remove the check. If not we need the check and continue looping. delivery attribute is a JSON field so I am not sure how do we structure this.

The reason I decided to do so is that code in this else branch used to send notification for android in old format containing "custom_notification'. It did so since codeVersion parameter of prepareAndroidNotification function was set to null. By dropping support for code version below 31 we decided to drop support for android clients requiring notification with custom_notification property (this is done by child differential for this one). Therefor I decided to continue looping in this else branch since we probably do not want to send notification in new format to client that cannot handle it.

lib/shared/messages/multimedia-message-spec.js
195 ↗(On Diff #15311)

This change was requested by @tomek. It is reasonable since we are dropping support for anything lower than 31 in this differential. This change does not change functionality since anything greater or equal to 32 is simultaneously greater than 30, but it makes the code more consistent.

tomek requested changes to this revision.Aug 5 2022, 4:59 AM
tomek added inline comments.
lib/shared/messages/multimedia-message-spec.js
195 ↗(On Diff #15311)

I don't remember suggesting to increase this number, but if that happened then it was my mistake. If we're dropping support for older clients, we should remove the code that handles versions < 32. In this case only the early return should stay.

This change does not change functionality since anything greater or equal to 32 is simultaneously greater than 30

This isn't correct. If one branch is used for code < 30 and other for >= 31 it might be the case that a client with code = 31 would receive something invalid for him. If we maintained backward compatibility we could do that, but we're not maintaining it. By backward compatibility I understand the approach where a client with version N is able to consume any data which clients < N could consume.

This revision now requires changes to proceed.Aug 5 2022, 4:59 AM
ashoat requested changes to this revision.Aug 5 2022, 9:22 AM
ashoat added inline comments.
keyserver/src/push/rescind.js
75–76 ↗(On Diff #15311)

I am not sure whether it is possible that delivery attribute of notifications table row can have both androidID and deviceType === 'android' set? Or are those mutually exclusive?

I don't recall unfortunately. If you want to get an answer you can do some "code archaeology" and look at the Git history to see what the code did in the past.

this is done by child differential for this one

I can't find what diff you're referring to here. In general you should always link things to make it easier for your reviewers...

By dropping support for code version below 31 we decided to drop support for android clients requiring notification with custom_notification property

  1. Is it the case that delivery.androidID will only appear if the notif that is being rescinded was sent to a codeVersion below 31? If so, can you please link the code (potentially old code that has been deleted, so you may have to check Git history) that would set delivery.androidID?
  2. I don't see any codeVersion checks in fcmPush. I'm confused why you're claiming that a null codeVersion will result in a custom_notification property... can you link the code that shows that?
lib/shared/messages/multimedia-message-spec.js
195 ↗(On Diff #15311)

It would also be good to check where this function in lib is used, and whether it's only used in keyserver. I assume yes, since keyserver is the only place it makes sense to do codeVersion checks... but I want to make sure before we delete the condition

keyserver/src/push/rescind.js
75–76 ↗(On Diff #15311)

I don't see any codeVersion checks in fcmPush. I'm confused why you're claiming that a null codeVersion will result in a custom_notification property... can you link the code that shows that?

The code that is deleted here calls prepareAndroidNotification with codeVersion parameter set to null. If you look at the code currently being run on keyserver: https://github.com/CommE2E/comm/blob/master/keyserver/src/push/rescind.js#L202 calling prepareAndroidNotification with codeVersion as null results in notifications with custom_notification property - the one we want to drop support for in this differential. This is the reason I decided to delete this code.

Is it the case that delivery.androidID will only appear if the notif that is being rescinded was sent to a codeVersion below 31? If so, can you please link the code (potentially old code that has been deleted, so you may have to check Git history) that would set delivery.androidID?

In fact we can do two things here: we delete entire else if branch or just deactivate it by continue. The first is only safe if we are sure notification handled that would be handled by this branch will not be handled by any other (by else if(delivery.deviceType == 'android'). This is why I was asking whether delivery.androidID` and delivery.deviceType == 'android' are mutually exclusive. I was not able to find an answer to this question, however I found commit that introduced androidID` to delivery: https://github.com/CommE2E/comm/commit/174bf6f6c3988ed315dc070d48fe0115bcb23fd5, and another one that removed it: https://github.com/CommE2E/comm/commit/49c18d09225d7700085bc5e68b632cfb124d0d23. So my guest is that this field is no longer added to delivery. The only concern that I have here is that the first commit uses index 4, while the second uses 5. I could not find another commit that changed those indexes, not user whether it is relevant but my guess is that this entire else if branch can be removed

lib/shared/messages/multimedia-message-spec.js
195 ↗(On Diff #15311)

I executed git grep shimUnsupportedMessageInfo in comm root directory. The only places I found that mentioned this function were messageSpec abstract class definition, implementation of this function for concrete message specs, and shimUnsupportedRawMessageInfos function definition in message-utils.js. So I concluded I have to run git grep shimUnsupportedRawMessageInfos. This is only mentioned in keyserver directory.

Chenges according to reviewers comments

ashoat requested changes to this revision.Aug 18 2022, 6:16 AM
ashoat added inline comments.
keyserver/src/push/rescind.js
69–82 ↗(On Diff #15710)

I don't think we should remove this code. First of all, we still have many unrescinded notifs with androidID and iosID set on my production keyserver:

MariaDB [comm]> SELECT COUNT(*) FROM notifications WHERE JSON_EXTRACT(delivery, '$.androidID') IS NOT NULL AND rescinded = 0;
+----------+
| COUNT(*) |
+----------+
|      380 |
+----------+
1 row in set (0.020 sec)

MariaDB [comm]> SELECT COUNT(*) FROM notifications WHERE JSON_EXTRACT(delivery, '$.iosID') IS NOT NULL AND rescinded = 0;
+----------+
| COUNT(*) |
+----------+
|      544 |
+----------+
1 row in set (0.015 sec)

Second of all, it's important to understand the significance of codeVersion here. The codeVersion we have in the delivery column is the codeVersion of the device at the time the notif was sent. That's not necessarily the codeVersion at the time the rescind is sent.

In fact, the code should probably be different... it would be better if we try to match up the cookie of the device to which the original notif was sent. If we can't find one, then there's probably no point rescinding the notif since the device is probably not online anymore. If we can find a cookie row then we could check the codeVersion there, and then we would know how to process the rescind.

Regardless this potential improvement is outside the scope of this work. My larger point is that I don't see a reason to delete this code. If for whatever reason we end up rescinding one of these notifs, if we assume the device is still online then I think it's fair to also assume its codeVersion is higher than 30.

Looking at my production keyserver, it appears that the oldest codeVersion currently active is 128:

MariaDB [comm]> SELECT COUNT(*), JSON_EXTRACT(versions, '$.codeVersion') AS code_version FROM cookies WHERE platform != 'web' GROUP BY code_version;
+----------+--------------+
| COUNT(*) | code_version |
+----------+--------------+
|        1 | 128          |
|       89 | 131          |
|        1 | 136          |
|       19 | 137          |
|        1 | 138          |
|        3 | 139          |
|       10 | 140          |
|       16 | 141          |
+----------+--------------+
8 rows in set (0.004 sec)
keyserver/src/session/version.js
13 ↗(On Diff #15710)

Why 32 instead of 31? Did we decide on 32 specifically?

This revision now requires changes to proceed.Aug 18 2022, 6:16 AM

Bring necessary else if branch back

Looks great, thank you!!

This revision is now accepted and ready to land.Aug 19 2022, 10:49 AM