tbb-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 18632 discussions

[Git][tpo/applications/tor-browser-build] Pushed new tag tbb-13.0.7-build1
by Pier Angelo Vendrame (@pierov) 15 Dec '23
by Pier Angelo Vendrame (@pierov) 15 Dec '23
15 Dec '23
Pier Angelo Vendrame pushed new tag tbb-13.0.7-build1 at The Tor Project / Applications / tor-browser-build
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/tree/tbb…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser-build][maint-13.0] Bug 41028: Prepare Tor Browser Release 13.0.7 (updated tags)
by Pier Angelo Vendrame (@pierov) 15 Dec '23
by Pier Angelo Vendrame (@pierov) 15 Dec '23
15 Dec '23
Pier Angelo Vendrame pushed to branch maint-13.0 at The Tor Project / Applications / tor-browser-build
Commits:
7f87af20 by Pier Angelo Vendrame at 2023-12-15T13:07:04+01:00
Bug 41028: Prepare Tor Browser Release 13.0.7 (updated tags)
Bumped the tags to include the changes in handling self-signed
certificates for onion sites and the Android backports.
Also, updated the translations to prevent possible Android build
failures.
- - - - -
6 changed files:
- projects/browser/Bundle-Data/Docs-TBB/ChangeLog.txt
- projects/browser/allowed_addons.json
- projects/firefox-android/config
- projects/firefox/config
- projects/geckoview/config
- projects/translation/config
Changes:
=====================================
projects/browser/Bundle-Data/Docs-TBB/ChangeLog.txt
=====================================
@@ -5,12 +5,14 @@ Tor Browser 13.0.7 - December 19 2023
* Bug 42042: view-source:http://ip-address does not work because of HTTPS Only [tor-browser]
* Bug 42261: Update the icon of Startpage search engine [tor-browser]
* Bug 42330: Rebase stable browsers to 115.6.0esr [tor-browser]
+ * Bug 42334: Keep returning ERROR_ONION_WITH_SELF_SIGNED_CERT only for .onion sites whose cert throws ERROR_UNKNOWN_ISSUER [tor-browser]
* Windows + macOS + Linux
* Updated Firefox to 115.6.0esr
* Bug 42283: Tor Browser shouldn't ship blockchair by default [tor-browser]
* Android
* Updated GekcoView to 115.6.0esr
* Bug 42285: Update the gitignore to use the correct paths for tor stuff [tor-browser]
+ * Bug 42339: Backport Android security fixes from Firefox 121 to 115.6 - based Tor Browser [tor-browser]
* Build System
* All Platforms
* Update Go to 1.21.5
=====================================
projects/browser/allowed_addons.json
=====================================
@@ -17,7 +17,7 @@
"picture_url": "https://addons.mozilla.org/user-media/userpics/34/9734/13299734/13299734.pn…"
}
],
- "average_daily_users": 1111769,
+ "average_daily_users": 1111341,
"categories": {
"firefox": [
"web-development",
@@ -218,10 +218,10 @@
"category": "recommended"
},
"ratings": {
- "average": 4.552,
- "bayesian_average": 4.550875275168652,
- "count": 5297,
- "text_count": 1665
+ "average": 4.5516,
+ "bayesian_average": 4.550475504261017,
+ "count": 5303,
+ "text_count": 1667
},
"ratings_url": "https://addons.mozilla.org/en-US/firefox/addon/darkreader/reviews/",
"requires_payment": false,
@@ -318,7 +318,7 @@
"type": "extension",
"url": "https://addons.mozilla.org/en-US/firefox/addon/darkreader/",
"versions_url": "https://addons.mozilla.org/en-US/firefox/addon/darkreader/versions/",
- "weekly_downloads": 42800
+ "weekly_downloads": 41426
},
"notes": null
},
@@ -334,7 +334,7 @@
"picture_url": "https://addons.mozilla.org/user-media/userpics/56/7656/6937656/6937656.png?…"
}
],
- "average_daily_users": 265194,
+ "average_daily_users": 264619,
"categories": {
"firefox": [
"privacy-security"
@@ -547,9 +547,9 @@
"category": "recommended"
},
"ratings": {
- "average": 4.8033,
- "bayesian_average": 4.798698964990932,
- "count": 1378,
+ "average": 4.8036,
+ "bayesian_average": 4.7989944298239395,
+ "count": 1380,
"text_count": 245
},
"ratings_url": "https://addons.mozilla.org/en-US/firefox/addon/decentraleyes/reviews/",
@@ -635,7 +635,7 @@
"type": "extension",
"url": "https://addons.mozilla.org/en-US/firefox/addon/decentraleyes/",
"versions_url": "https://addons.mozilla.org/en-US/firefox/addon/decentraleyes/versions/",
- "weekly_downloads": 3697
+ "weekly_downloads": 3583
},
"notes": null
},
@@ -651,7 +651,7 @@
"picture_url": "https://addons.mozilla.org/user-media/userpics/73/4073/5474073/5474073.png?…"
}
],
- "average_daily_users": 1201690,
+ "average_daily_users": 1200452,
"categories": {
"firefox": [
"privacy-security"
@@ -1170,10 +1170,10 @@
"category": "recommended"
},
"ratings": {
- "average": 4.7985,
- "bayesian_average": 4.795793986966051,
- "count": 2343,
- "text_count": 443
+ "average": 4.799,
+ "bayesian_average": 4.79629496440493,
+ "count": 2348,
+ "text_count": 444
},
"ratings_url": "https://addons.mozilla.org/en-US/firefox/addon/privacy-badger17/reviews/",
"requires_payment": false,
@@ -1197,7 +1197,7 @@
"type": "extension",
"url": "https://addons.mozilla.org/en-US/firefox/addon/privacy-badger17/",
"versions_url": "https://addons.mozilla.org/en-US/firefox/addon/privacy-badger17/versions/",
- "weekly_downloads": 25575
+ "weekly_downloads": 24321
},
"notes": null
},
@@ -1213,7 +1213,7 @@
"picture_url": null
}
],
- "average_daily_users": 7393705,
+ "average_daily_users": 7388167,
"categories": {
"firefox": [
"privacy-security"
@@ -1378,7 +1378,7 @@
},
"is_disabled": false,
"is_experimental": false,
- "last_updated": "2023-12-10T20:30:30Z",
+ "last_updated": "2023-12-14T22:05:25Z",
"name": {
"ar": "uBlock Origin",
"bg": "uBlock Origin",
@@ -1523,10 +1523,10 @@
"category": "recommended"
},
"ratings": {
- "average": 4.7859,
- "bayesian_average": 4.785524571334245,
- "count": 16855,
- "text_count": 4394
+ "average": 4.7863,
+ "bayesian_average": 4.7859243673114,
+ "count": 16865,
+ "text_count": 4397
},
"ratings_url": "https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/reviews/",
"requires_payment": false,
@@ -1589,7 +1589,7 @@
"type": "extension",
"url": "https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/",
"versions_url": "https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/versions/",
- "weekly_downloads": 227435
+ "weekly_downloads": 205700
},
"notes": null
},
@@ -1605,7 +1605,7 @@
"picture_url": null
}
],
- "average_daily_users": 175266,
+ "average_daily_users": 175062,
"categories": {
"firefox": [
"photos-music-videos",
@@ -1701,10 +1701,10 @@
"category": "recommended"
},
"ratings": {
- "average": 4.4836,
- "bayesian_average": 4.4785450179775905,
- "count": 1156,
- "text_count": 433
+ "average": 4.4845,
+ "bayesian_average": 4.479449733868465,
+ "count": 1158,
+ "text_count": 434
},
"ratings_url": "https://addons.mozilla.org/en-US/firefox/addon/video-background-play-fix/re…",
"requires_payment": false,
@@ -1726,7 +1726,7 @@
"type": "extension",
"url": "https://addons.mozilla.org/en-US/firefox/addon/video-background-play-fix/",
"versions_url": "https://addons.mozilla.org/en-US/firefox/addon/video-background-play-fix/ve…",
- "weekly_downloads": 371
+ "weekly_downloads": 374
},
"notes": null
},
@@ -1742,7 +1742,7 @@
"picture_url": null
}
],
- "average_daily_users": 86834,
+ "average_daily_users": 86192,
"categories": {
"firefox": [
"privacy-security",
@@ -1877,7 +1877,7 @@
"type": "extension",
"url": "https://addons.mozilla.org/en-US/firefox/addon/privacy-possum/",
"versions_url": "https://addons.mozilla.org/en-US/firefox/addon/privacy-possum/versions/",
- "weekly_downloads": 1422
+ "weekly_downloads": 1054
},
"notes": null
},
@@ -1893,7 +1893,7 @@
"picture_url": "https://addons.mozilla.org/user-media/userpics/64/9064/12929064/12929064.pn…"
}
],
- "average_daily_users": 288739,
+ "average_daily_users": 288741,
"categories": {
"firefox": [
"search-tools",
@@ -2110,10 +2110,10 @@
"category": "recommended"
},
"ratings": {
- "average": 4.6497,
- "bayesian_average": 4.645209362164032,
- "count": 1359,
- "text_count": 264
+ "average": 4.65,
+ "bayesian_average": 4.645504940520216,
+ "count": 1360,
+ "text_count": 265
},
"ratings_url": "https://addons.mozilla.org/en-US/firefox/addon/search_by_image/reviews/",
"requires_payment": false,
@@ -2134,7 +2134,7 @@
"type": "extension",
"url": "https://addons.mozilla.org/en-US/firefox/addon/search_by_image/",
"versions_url": "https://addons.mozilla.org/en-US/firefox/addon/search_by_image/versions/",
- "weekly_downloads": 6249
+ "weekly_downloads": 6343
},
"notes": null
},
@@ -2157,7 +2157,7 @@
"picture_url": null
}
],
- "average_daily_users": 118894,
+ "average_daily_users": 118713,
"categories": {
"firefox": [
"search-tools",
@@ -2438,10 +2438,10 @@
"category": "recommended"
},
"ratings": {
- "average": 4.3694,
- "bayesian_average": 4.364995316323036,
- "count": 1286,
- "text_count": 363
+ "average": 4.3699,
+ "bayesian_average": 4.36549570183314,
+ "count": 1287,
+ "text_count": 364
},
"ratings_url": "https://addons.mozilla.org/en-US/firefox/addon/google-search-fixer/reviews/",
"requires_payment": false,
@@ -2461,7 +2461,7 @@
"type": "extension",
"url": "https://addons.mozilla.org/en-US/firefox/addon/google-search-fixer/",
"versions_url": "https://addons.mozilla.org/en-US/firefox/addon/google-search-fixer/versions/",
- "weekly_downloads": 49
+ "weekly_downloads": 81
},
"notes": null
},
@@ -2477,7 +2477,7 @@
"picture_url": "https://addons.mozilla.org/user-media/userpics/43/0143/143/143.png?modified…"
}
],
- "average_daily_users": 314227,
+ "average_daily_users": 313680,
"categories": {
"firefox": [
"web-development",
@@ -2488,18 +2488,18 @@
"contributions_url": "https://www.paypal.com/donate/?hosted_button_id=9ERKTU5MBH4EW&utm_content=p…",
"created": "2005-05-13T10:51:32Z",
"current_version": {
- "id": 5634098,
+ "id": 5661865,
"compatibility": {
"firefox": {
"min": "59.0",
"max": "*"
},
"android": {
- "min": "59.0",
+ "min": "113.0",
"max": "*"
}
},
- "edit_url": "https://addons.mozilla.org/en-US/developers/addon/noscript/versions/5634098",
+ "edit_url": "https://addons.mozilla.org/en-US/developers/addon/noscript/versions/5661865",
"is_strict_compatibility_enabled": false,
"license": {
"id": 13,
@@ -2510,22 +2510,22 @@
"url": "http://www.gnu.org/licenses/gpl-2.0.html"
},
"release_notes": {
- "en-US": "v 11.4.28\n============================================================\nx Prevent URL leaks from media placeholders (thanks NDevTK\n for report)\nx [nscl] Support for in-tree TLDs updates"
+ "en-US": "v 11.4.29\n============================================================\nx [nscl] Updated TLDs\nx [nscl] Improved reliability of TLD updater\nx Removed theme.js console noise\nx Fix beta channel updates breakage due to\n browser_specific_settings override\nx [nscl] Several content-side performance improvements\nx Reduce synchronous policy retrieval impact on file: and\n ftp: document loading performance\nx More commands for which a keyboard shortcut can be\n configured\nx [L10n] Updated de, fi, mk, nl, pl, ru, sq, tr, uk,\n pt_BR, zh_CN, zh_TW\nx Explicit Android compatibility declaration"
},
- "reviewed": "2023-10-10T11:09:38Z",
- "version": "11.4.28",
+ "reviewed": "2023-12-12T09:47:41Z",
+ "version": "11.4.29",
"files": [
{
- "id": 4178438,
- "created": "2023-10-08T20:33:10Z",
- "hash": "sha256:54d076b3226d454216117547f6441d2f95af3057d20f726e55d94b0f22573c14",
+ "id": 4206186,
+ "created": "2023-12-07T23:12:27Z",
+ "hash": "sha256:05b98840b05ef2acbac333543e4b7c3d40fee2ce5fb4e29260b05e2ff6fe24cd",
"is_restart_required": false,
"is_webextension": true,
"is_mozilla_signed_extension": false,
"platform": "all",
- "size": 950895,
+ "size": 952701,
"status": "public",
- "url": "https://addons.mozilla.org/firefox/downloads/file/4178438/noscript-11.4.28.…",
+ "url": "https://addons.mozilla.org/firefox/downloads/file/4206186/noscript-11.4.29.…",
"permissions": [
"contextMenus",
"storage",
@@ -2592,7 +2592,7 @@
},
"is_disabled": false,
"is_experimental": false,
- "last_updated": "2023-12-07T23:00:20Z",
+ "last_updated": "2023-12-12T09:47:41Z",
"name": {
"de": "NoScript",
"el": "NoScript",
@@ -2664,9 +2664,9 @@
"category": "recommended"
},
"ratings": {
- "average": 4.399,
- "bayesian_average": 4.396341521516985,
- "count": 2148,
+ "average": 4.3984,
+ "bayesian_average": 4.395742595786679,
+ "count": 2151,
"text_count": 830
},
"ratings_url": "https://addons.mozilla.org/en-US/firefox/addon/noscript/reviews/",
@@ -2711,7 +2711,7 @@
"type": "extension",
"url": "https://addons.mozilla.org/en-US/firefox/addon/noscript/",
"versions_url": "https://addons.mozilla.org/en-US/firefox/addon/noscript/versions/",
- "weekly_downloads": 8349
+ "weekly_downloads": 8167
},
"notes": null
},
@@ -2727,7 +2727,7 @@
"picture_url": null
}
],
- "average_daily_users": 158952,
+ "average_daily_users": 158779,
"categories": {
"firefox": [
"photos-music-videos",
@@ -2836,10 +2836,10 @@
"category": "recommended"
},
"ratings": {
- "average": 3.8698,
- "bayesian_average": 3.865729231191426,
- "count": 1198,
- "text_count": 433
+ "average": 3.8682,
+ "bayesian_average": 3.864132502143421,
+ "count": 1199,
+ "text_count": 434
},
"ratings_url": "https://addons.mozilla.org/en-US/firefox/addon/youtube-high-definition/revi…",
"requires_payment": false,
@@ -2858,7 +2858,7 @@
"type": "extension",
"url": "https://addons.mozilla.org/en-US/firefox/addon/youtube-high-definition/",
"versions_url": "https://addons.mozilla.org/en-US/firefox/addon/youtube-high-definition/vers…",
- "weekly_downloads": 2642
+ "weekly_downloads": 2542
},
"notes": null
}
=====================================
projects/firefox-android/config
=====================================
@@ -16,7 +16,7 @@ container:
var:
fenix_version: 115.2.1
browser_branch: 13.0-1
- browser_build: 10
+ browser_build: 11
variant: Beta
# This should be updated when the list of gradle dependencies is changed.
gradle_dependencies_version: 1
=====================================
projects/firefox/config
=====================================
@@ -18,7 +18,7 @@ var:
firefox_version: '[% c("var/firefox_platform_version") %]esr'
browser_series: '13.0'
browser_branch: '[% c("var/browser_series") %]-1'
- browser_build: 1
+ browser_build: 2
branding_directory_prefix: 'tb'
copyright_year: '[% exec("git show -s --format=%ci").remove("-.*") %]'
nightly_updates_publish_dir: '[% c("var/nightly_updates_publish_dir_prefix") %]nightly-[% c("var/osname") %]'
=====================================
projects/geckoview/config
=====================================
@@ -16,7 +16,7 @@ container:
var:
geckoview_version: 115.6.0esr
browser_branch: 13.0-1
- browser_build: 1
+ browser_build: 2
copyright_year: '[% exec("git show -s --format=%ci").remove("-.*") %]'
gitlab_project: https://gitlab.torproject.org/tpo/applications/tor-browser
git_commit: '[% exec("git rev-parse HEAD") %]'
=====================================
projects/translation/config
=====================================
@@ -12,13 +12,13 @@ compress_tar: 'gz'
steps:
base-browser:
base-browser: '[% INCLUDE build %]'
- git_hash: a4220760127d38e8bde9bc1bbc38b591f0663e98
+ git_hash: 5490489a8d356a44d792300b4dfddba792d10f2e
targets:
nightly:
git_hash: 'base-browser'
tor-browser:
tor-browser: '[% INCLUDE build %]'
- git_hash: 1183d5c88ef5f05eca5087c1f1a2ef689bac0094
+ git_hash: 273592eca488ca3bf535d3789b1130fd1970f09a
targets:
nightly:
git_hash: 'tor-browser'
@@ -32,7 +32,7 @@ steps:
fenix: '[% INCLUDE build %]'
# We need to bump the commit before releasing but just pointing to a branch
# might cause too much rebuidling of the Firefox part.
- git_hash: a1051f0d646a5e957e4b120c6dfa3199995e8ee8
+ git_hash: 2fbc645d4efb7ccb2de92394d59e99a32ecfa3ba
compress_tar: 'zst'
targets:
nightly:
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/7…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/7…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser] Pushed new tag tor-browser-115.6.0esr-13.0-1-build2
by Pier Angelo Vendrame (@pierov) 15 Dec '23
by Pier Angelo Vendrame (@pierov) 15 Dec '23
15 Dec '23
Pier Angelo Vendrame pushed new tag tor-browser-115.6.0esr-13.0-1-build2 at The Tor Project / Applications / Tor Browser
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/tree/tor-brows…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser-build][main] Bug 41048: Remove the kcp-go project
by Pier Angelo Vendrame (@pierov) 15 Dec '23
by Pier Angelo Vendrame (@pierov) 15 Dec '23
15 Dec '23
Pier Angelo Vendrame pushed to branch main at The Tor Project / Applications / tor-browser-build
Commits:
959bdfb9 by Pier Angelo Vendrame at 2023-12-15T09:15:18+00:00
Bug 41048: Remove the kcp-go project
- - - - -
1 changed file:
- − projects/kcp-go/remove-crypt-fec.patch
Changes:
=====================================
projects/kcp-go/remove-crypt-fec.patch deleted
=====================================
@@ -1,1019 +0,0 @@
-From 0b9d0759f979a5d828b747ea51771f307c53d221 Mon Sep 17 00:00:00 2001
-From: David Fifield <david(a)bamsoftware.com>
-Date: Thu, 9 Apr 2020 11:27:44 -0600
-Subject: [PATCH] Remove crypt and FEC dependencies.
-
----
- crypt.go | 618 -----------------------------------------------------
- fec.go | 337 -----------------------------
- removed.go | 29 +++
- 3 files changed, 29 insertions(+), 955 deletions(-)
- delete mode 100644 crypt.go
- delete mode 100644 fec.go
- create mode 100644 removed.go
-
-diff --git a/crypt.go b/crypt.go
-deleted file mode 100644
-index d882852..0000000
---- a/crypt.go
-+++ /dev/null
-@@ -1,618 +0,0 @@
--package kcp
--
--import (
-- "crypto/aes"
-- "crypto/cipher"
-- "crypto/des"
-- "crypto/sha1"
-- "unsafe"
--
-- xor "github.com/templexxx/xorsimd"
-- "github.com/tjfoc/gmsm/sm4"
--
-- "golang.org/x/crypto/blowfish"
-- "golang.org/x/crypto/cast5"
-- "golang.org/x/crypto/pbkdf2"
-- "golang.org/x/crypto/salsa20"
-- "golang.org/x/crypto/tea"
-- "golang.org/x/crypto/twofish"
-- "golang.org/x/crypto/xtea"
--)
--
--var (
-- initialVector = []byte{167, 115, 79, 156, 18, 172, 27, 1, 164, 21, 242, 193, 252, 120, 230, 107}
-- saltxor = `sH3CIVoF#rWLtJo6`
--)
--
--// BlockCrypt defines encryption/decryption methods for a given byte slice.
--// Notes on implementing: the data to be encrypted contains a builtin
--// nonce at the first 16 bytes
--type BlockCrypt interface {
-- // Encrypt encrypts the whole block in src into dst.
-- // Dst and src may point at the same memory.
-- Encrypt(dst, src []byte)
--
-- // Decrypt decrypts the whole block in src into dst.
-- // Dst and src may point at the same memory.
-- Decrypt(dst, src []byte)
--}
--
--type salsa20BlockCrypt struct {
-- key [32]byte
--}
--
--// NewSalsa20BlockCrypt https://en.wikipedia.org/wiki/Salsa20
--func NewSalsa20BlockCrypt(key []byte) (BlockCrypt, error) {
-- c := new(salsa20BlockCrypt)
-- copy(c.key[:], key)
-- return c, nil
--}
--
--func (c *salsa20BlockCrypt) Encrypt(dst, src []byte) {
-- salsa20.XORKeyStream(dst[8:], src[8:], src[:8], &c.key)
-- copy(dst[:8], src[:8])
--}
--func (c *salsa20BlockCrypt) Decrypt(dst, src []byte) {
-- salsa20.XORKeyStream(dst[8:], src[8:], src[:8], &c.key)
-- copy(dst[:8], src[:8])
--}
--
--type sm4BlockCrypt struct {
-- encbuf [sm4.BlockSize]byte // 64bit alignment enc/dec buffer
-- decbuf [2 * sm4.BlockSize]byte
-- block cipher.Block
--}
--
--// NewSM4BlockCrypt https://github.com/tjfoc/gmsm/tree/master/sm4
--func NewSM4BlockCrypt(key []byte) (BlockCrypt, error) {
-- c := new(sm4BlockCrypt)
-- block, err := sm4.NewCipher(key)
-- if err != nil {
-- return nil, err
-- }
-- c.block = block
-- return c, nil
--}
--
--func (c *sm4BlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
--func (c *sm4BlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
--
--type twofishBlockCrypt struct {
-- encbuf [twofish.BlockSize]byte
-- decbuf [2 * twofish.BlockSize]byte
-- block cipher.Block
--}
--
--// NewTwofishBlockCrypt https://en.wikipedia.org/wiki/Twofish
--func NewTwofishBlockCrypt(key []byte) (BlockCrypt, error) {
-- c := new(twofishBlockCrypt)
-- block, err := twofish.NewCipher(key)
-- if err != nil {
-- return nil, err
-- }
-- c.block = block
-- return c, nil
--}
--
--func (c *twofishBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
--func (c *twofishBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
--
--type tripleDESBlockCrypt struct {
-- encbuf [des.BlockSize]byte
-- decbuf [2 * des.BlockSize]byte
-- block cipher.Block
--}
--
--// NewTripleDESBlockCrypt https://en.wikipedia.org/wiki/Triple_DES
--func NewTripleDESBlockCrypt(key []byte) (BlockCrypt, error) {
-- c := new(tripleDESBlockCrypt)
-- block, err := des.NewTripleDESCipher(key)
-- if err != nil {
-- return nil, err
-- }
-- c.block = block
-- return c, nil
--}
--
--func (c *tripleDESBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
--func (c *tripleDESBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
--
--type cast5BlockCrypt struct {
-- encbuf [cast5.BlockSize]byte
-- decbuf [2 * cast5.BlockSize]byte
-- block cipher.Block
--}
--
--// NewCast5BlockCrypt https://en.wikipedia.org/wiki/CAST-128
--func NewCast5BlockCrypt(key []byte) (BlockCrypt, error) {
-- c := new(cast5BlockCrypt)
-- block, err := cast5.NewCipher(key)
-- if err != nil {
-- return nil, err
-- }
-- c.block = block
-- return c, nil
--}
--
--func (c *cast5BlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
--func (c *cast5BlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
--
--type blowfishBlockCrypt struct {
-- encbuf [blowfish.BlockSize]byte
-- decbuf [2 * blowfish.BlockSize]byte
-- block cipher.Block
--}
--
--// NewBlowfishBlockCrypt https://en.wikipedia.org/wiki/Blowfish_(cipher)
--func NewBlowfishBlockCrypt(key []byte) (BlockCrypt, error) {
-- c := new(blowfishBlockCrypt)
-- block, err := blowfish.NewCipher(key)
-- if err != nil {
-- return nil, err
-- }
-- c.block = block
-- return c, nil
--}
--
--func (c *blowfishBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
--func (c *blowfishBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
--
--type aesBlockCrypt struct {
-- encbuf [aes.BlockSize]byte
-- decbuf [2 * aes.BlockSize]byte
-- block cipher.Block
--}
--
--// NewAESBlockCrypt https://en.wikipedia.org/wiki/Advanced_Encryption_Standard
--func NewAESBlockCrypt(key []byte) (BlockCrypt, error) {
-- c := new(aesBlockCrypt)
-- block, err := aes.NewCipher(key)
-- if err != nil {
-- return nil, err
-- }
-- c.block = block
-- return c, nil
--}
--
--func (c *aesBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
--func (c *aesBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
--
--type teaBlockCrypt struct {
-- encbuf [tea.BlockSize]byte
-- decbuf [2 * tea.BlockSize]byte
-- block cipher.Block
--}
--
--// NewTEABlockCrypt https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
--func NewTEABlockCrypt(key []byte) (BlockCrypt, error) {
-- c := new(teaBlockCrypt)
-- block, err := tea.NewCipherWithRounds(key, 16)
-- if err != nil {
-- return nil, err
-- }
-- c.block = block
-- return c, nil
--}
--
--func (c *teaBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
--func (c *teaBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
--
--type xteaBlockCrypt struct {
-- encbuf [xtea.BlockSize]byte
-- decbuf [2 * xtea.BlockSize]byte
-- block cipher.Block
--}
--
--// NewXTEABlockCrypt https://en.wikipedia.org/wiki/XTEA
--func NewXTEABlockCrypt(key []byte) (BlockCrypt, error) {
-- c := new(xteaBlockCrypt)
-- block, err := xtea.NewCipher(key)
-- if err != nil {
-- return nil, err
-- }
-- c.block = block
-- return c, nil
--}
--
--func (c *xteaBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
--func (c *xteaBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
--
--type simpleXORBlockCrypt struct {
-- xortbl []byte
--}
--
--// NewSimpleXORBlockCrypt simple xor with key expanding
--func NewSimpleXORBlockCrypt(key []byte) (BlockCrypt, error) {
-- c := new(simpleXORBlockCrypt)
-- c.xortbl = pbkdf2.Key(key, []byte(saltxor), 32, mtuLimit, sha1.New)
-- return c, nil
--}
--
--func (c *simpleXORBlockCrypt) Encrypt(dst, src []byte) { xor.Bytes(dst, src, c.xortbl) }
--func (c *simpleXORBlockCrypt) Decrypt(dst, src []byte) { xor.Bytes(dst, src, c.xortbl) }
--
--type noneBlockCrypt struct{}
--
--// NewNoneBlockCrypt does nothing but copying
--func NewNoneBlockCrypt(key []byte) (BlockCrypt, error) {
-- return new(noneBlockCrypt), nil
--}
--
--func (c *noneBlockCrypt) Encrypt(dst, src []byte) { copy(dst, src) }
--func (c *noneBlockCrypt) Decrypt(dst, src []byte) { copy(dst, src) }
--
--// packet encryption with local CFB mode
--func encrypt(block cipher.Block, dst, src, buf []byte) {
-- switch block.BlockSize() {
-- case 8:
-- encrypt8(block, dst, src, buf)
-- case 16:
-- encrypt16(block, dst, src, buf)
-- default:
-- panic("unsupported cipher block size")
-- }
--}
--
--// optimized encryption for the ciphers which works in 8-bytes
--func encrypt8(block cipher.Block, dst, src, buf []byte) {
-- tbl := buf[:8]
-- block.Encrypt(tbl, initialVector)
-- n := len(src) / 8
-- base := 0
-- repeat := n / 8
-- left := n % 8
-- ptr_tbl := (*uint64)(unsafe.Pointer(&tbl[0]))
--
-- for i := 0; i < repeat; i++ {
-- s := src[base:][0:64]
-- d := dst[base:][0:64]
-- // 1
-- *(*uint64)(unsafe.Pointer(&d[0])) = *(*uint64)(unsafe.Pointer(&s[0])) ^ *ptr_tbl
-- block.Encrypt(tbl, d[0:8])
-- // 2
-- *(*uint64)(unsafe.Pointer(&d[8])) = *(*uint64)(unsafe.Pointer(&s[8])) ^ *ptr_tbl
-- block.Encrypt(tbl, d[8:16])
-- // 3
-- *(*uint64)(unsafe.Pointer(&d[16])) = *(*uint64)(unsafe.Pointer(&s[16])) ^ *ptr_tbl
-- block.Encrypt(tbl, d[16:24])
-- // 4
-- *(*uint64)(unsafe.Pointer(&d[24])) = *(*uint64)(unsafe.Pointer(&s[24])) ^ *ptr_tbl
-- block.Encrypt(tbl, d[24:32])
-- // 5
-- *(*uint64)(unsafe.Pointer(&d[32])) = *(*uint64)(unsafe.Pointer(&s[32])) ^ *ptr_tbl
-- block.Encrypt(tbl, d[32:40])
-- // 6
-- *(*uint64)(unsafe.Pointer(&d[40])) = *(*uint64)(unsafe.Pointer(&s[40])) ^ *ptr_tbl
-- block.Encrypt(tbl, d[40:48])
-- // 7
-- *(*uint64)(unsafe.Pointer(&d[48])) = *(*uint64)(unsafe.Pointer(&s[48])) ^ *ptr_tbl
-- block.Encrypt(tbl, d[48:56])
-- // 8
-- *(*uint64)(unsafe.Pointer(&d[56])) = *(*uint64)(unsafe.Pointer(&s[56])) ^ *ptr_tbl
-- block.Encrypt(tbl, d[56:64])
-- base += 64
-- }
--
-- switch left {
-- case 7:
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
-- block.Encrypt(tbl, dst[base:])
-- base += 8
-- fallthrough
-- case 6:
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
-- block.Encrypt(tbl, dst[base:])
-- base += 8
-- fallthrough
-- case 5:
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
-- block.Encrypt(tbl, dst[base:])
-- base += 8
-- fallthrough
-- case 4:
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
-- block.Encrypt(tbl, dst[base:])
-- base += 8
-- fallthrough
-- case 3:
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
-- block.Encrypt(tbl, dst[base:])
-- base += 8
-- fallthrough
-- case 2:
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
-- block.Encrypt(tbl, dst[base:])
-- base += 8
-- fallthrough
-- case 1:
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
-- block.Encrypt(tbl, dst[base:])
-- base += 8
-- fallthrough
-- case 0:
-- xorBytes(dst[base:], src[base:], tbl)
-- }
--}
--
--// optimized encryption for the ciphers which works in 16-bytes
--func encrypt16(block cipher.Block, dst, src, buf []byte) {
-- tbl := buf[:16]
-- block.Encrypt(tbl, initialVector)
-- n := len(src) / 16
-- base := 0
-- repeat := n / 8
-- left := n % 8
-- for i := 0; i < repeat; i++ {
-- s := src[base:][0:128]
-- d := dst[base:][0:128]
-- // 1
-- xor.Bytes16Align(d[0:16], s[0:16], tbl)
-- block.Encrypt(tbl, d[0:16])
-- // 2
-- xor.Bytes16Align(d[16:32], s[16:32], tbl)
-- block.Encrypt(tbl, d[16:32])
-- // 3
-- xor.Bytes16Align(d[32:48], s[32:48], tbl)
-- block.Encrypt(tbl, d[32:48])
-- // 4
-- xor.Bytes16Align(d[48:64], s[48:64], tbl)
-- block.Encrypt(tbl, d[48:64])
-- // 5
-- xor.Bytes16Align(d[64:80], s[64:80], tbl)
-- block.Encrypt(tbl, d[64:80])
-- // 6
-- xor.Bytes16Align(d[80:96], s[80:96], tbl)
-- block.Encrypt(tbl, d[80:96])
-- // 7
-- xor.Bytes16Align(d[96:112], s[96:112], tbl)
-- block.Encrypt(tbl, d[96:112])
-- // 8
-- xor.Bytes16Align(d[112:128], s[112:128], tbl)
-- block.Encrypt(tbl, d[112:128])
-- base += 128
-- }
--
-- switch left {
-- case 7:
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- block.Encrypt(tbl, dst[base:])
-- base += 16
-- fallthrough
-- case 6:
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- block.Encrypt(tbl, dst[base:])
-- base += 16
-- fallthrough
-- case 5:
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- block.Encrypt(tbl, dst[base:])
-- base += 16
-- fallthrough
-- case 4:
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- block.Encrypt(tbl, dst[base:])
-- base += 16
-- fallthrough
-- case 3:
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- block.Encrypt(tbl, dst[base:])
-- base += 16
-- fallthrough
-- case 2:
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- block.Encrypt(tbl, dst[base:])
-- base += 16
-- fallthrough
-- case 1:
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- block.Encrypt(tbl, dst[base:])
-- base += 16
-- fallthrough
-- case 0:
-- xorBytes(dst[base:], src[base:], tbl)
-- }
--}
--
--// decryption
--func decrypt(block cipher.Block, dst, src, buf []byte) {
-- switch block.BlockSize() {
-- case 8:
-- decrypt8(block, dst, src, buf)
-- case 16:
-- decrypt16(block, dst, src, buf)
-- default:
-- panic("unsupported cipher block size")
-- }
--}
--
--// decrypt 8 bytes block, all byte slices are supposed to be 64bit aligned
--func decrypt8(block cipher.Block, dst, src, buf []byte) {
-- tbl := buf[0:8]
-- next := buf[8:16]
-- block.Encrypt(tbl, initialVector)
-- n := len(src) / 8
-- base := 0
-- repeat := n / 8
-- left := n % 8
-- ptr_tbl := (*uint64)(unsafe.Pointer(&tbl[0]))
-- ptr_next := (*uint64)(unsafe.Pointer(&next[0]))
--
-- for i := 0; i < repeat; i++ {
-- s := src[base:][0:64]
-- d := dst[base:][0:64]
-- // 1
-- block.Encrypt(next, s[0:8])
-- *(*uint64)(unsafe.Pointer(&d[0])) = *(*uint64)(unsafe.Pointer(&s[0])) ^ *ptr_tbl
-- // 2
-- block.Encrypt(tbl, s[8:16])
-- *(*uint64)(unsafe.Pointer(&d[8])) = *(*uint64)(unsafe.Pointer(&s[8])) ^ *ptr_next
-- // 3
-- block.Encrypt(next, s[16:24])
-- *(*uint64)(unsafe.Pointer(&d[16])) = *(*uint64)(unsafe.Pointer(&s[16])) ^ *ptr_tbl
-- // 4
-- block.Encrypt(tbl, s[24:32])
-- *(*uint64)(unsafe.Pointer(&d[24])) = *(*uint64)(unsafe.Pointer(&s[24])) ^ *ptr_next
-- // 5
-- block.Encrypt(next, s[32:40])
-- *(*uint64)(unsafe.Pointer(&d[32])) = *(*uint64)(unsafe.Pointer(&s[32])) ^ *ptr_tbl
-- // 6
-- block.Encrypt(tbl, s[40:48])
-- *(*uint64)(unsafe.Pointer(&d[40])) = *(*uint64)(unsafe.Pointer(&s[40])) ^ *ptr_next
-- // 7
-- block.Encrypt(next, s[48:56])
-- *(*uint64)(unsafe.Pointer(&d[48])) = *(*uint64)(unsafe.Pointer(&s[48])) ^ *ptr_tbl
-- // 8
-- block.Encrypt(tbl, s[56:64])
-- *(*uint64)(unsafe.Pointer(&d[56])) = *(*uint64)(unsafe.Pointer(&s[56])) ^ *ptr_next
-- base += 64
-- }
--
-- switch left {
-- case 7:
-- block.Encrypt(next, src[base:])
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
-- tbl, next = next, tbl
-- base += 8
-- fallthrough
-- case 6:
-- block.Encrypt(next, src[base:])
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
-- tbl, next = next, tbl
-- base += 8
-- fallthrough
-- case 5:
-- block.Encrypt(next, src[base:])
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
-- tbl, next = next, tbl
-- base += 8
-- fallthrough
-- case 4:
-- block.Encrypt(next, src[base:])
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
-- tbl, next = next, tbl
-- base += 8
-- fallthrough
-- case 3:
-- block.Encrypt(next, src[base:])
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
-- tbl, next = next, tbl
-- base += 8
-- fallthrough
-- case 2:
-- block.Encrypt(next, src[base:])
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
-- tbl, next = next, tbl
-- base += 8
-- fallthrough
-- case 1:
-- block.Encrypt(next, src[base:])
-- *(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
-- tbl, next = next, tbl
-- base += 8
-- fallthrough
-- case 0:
-- xorBytes(dst[base:], src[base:], tbl)
-- }
--}
--
--func decrypt16(block cipher.Block, dst, src, buf []byte) {
-- tbl := buf[0:16]
-- next := buf[16:32]
-- block.Encrypt(tbl, initialVector)
-- n := len(src) / 16
-- base := 0
-- repeat := n / 8
-- left := n % 8
-- for i := 0; i < repeat; i++ {
-- s := src[base:][0:128]
-- d := dst[base:][0:128]
-- // 1
-- block.Encrypt(next, s[0:16])
-- xor.Bytes16Align(d[0:16], s[0:16], tbl)
-- // 2
-- block.Encrypt(tbl, s[16:32])
-- xor.Bytes16Align(d[16:32], s[16:32], next)
-- // 3
-- block.Encrypt(next, s[32:48])
-- xor.Bytes16Align(d[32:48], s[32:48], tbl)
-- // 4
-- block.Encrypt(tbl, s[48:64])
-- xor.Bytes16Align(d[48:64], s[48:64], next)
-- // 5
-- block.Encrypt(next, s[64:80])
-- xor.Bytes16Align(d[64:80], s[64:80], tbl)
-- // 6
-- block.Encrypt(tbl, s[80:96])
-- xor.Bytes16Align(d[80:96], s[80:96], next)
-- // 7
-- block.Encrypt(next, s[96:112])
-- xor.Bytes16Align(d[96:112], s[96:112], tbl)
-- // 8
-- block.Encrypt(tbl, s[112:128])
-- xor.Bytes16Align(d[112:128], s[112:128], next)
-- base += 128
-- }
--
-- switch left {
-- case 7:
-- block.Encrypt(next, src[base:])
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- tbl, next = next, tbl
-- base += 16
-- fallthrough
-- case 6:
-- block.Encrypt(next, src[base:])
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- tbl, next = next, tbl
-- base += 16
-- fallthrough
-- case 5:
-- block.Encrypt(next, src[base:])
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- tbl, next = next, tbl
-- base += 16
-- fallthrough
-- case 4:
-- block.Encrypt(next, src[base:])
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- tbl, next = next, tbl
-- base += 16
-- fallthrough
-- case 3:
-- block.Encrypt(next, src[base:])
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- tbl, next = next, tbl
-- base += 16
-- fallthrough
-- case 2:
-- block.Encrypt(next, src[base:])
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- tbl, next = next, tbl
-- base += 16
-- fallthrough
-- case 1:
-- block.Encrypt(next, src[base:])
-- xor.Bytes16Align(dst[base:], src[base:], tbl)
-- tbl, next = next, tbl
-- base += 16
-- fallthrough
-- case 0:
-- xorBytes(dst[base:], src[base:], tbl)
-- }
--}
--
--// per bytes xors
--func xorBytes(dst, a, b []byte) int {
-- n := len(a)
-- if len(b) < n {
-- n = len(b)
-- }
-- if n == 0 {
-- return 0
-- }
--
-- for i := 0; i < n; i++ {
-- dst[i] = a[i] ^ b[i]
-- }
-- return n
--}
-diff --git a/fec.go b/fec.go
-deleted file mode 100644
-index 97cd40b..0000000
---- a/fec.go
-+++ /dev/null
-@@ -1,337 +0,0 @@
--package kcp
--
--import (
-- "encoding/binary"
-- "sync/atomic"
--
-- "github.com/klauspost/reedsolomon"
--)
--
--const (
-- fecHeaderSize = 6
-- fecHeaderSizePlus2 = fecHeaderSize + 2 // plus 2B data size
-- typeData = 0xf1
-- typeParity = 0xf2
-- fecExpire = 60000
--)
--
--// fecPacket is a decoded FEC packet
--type fecPacket []byte
--
--func (bts fecPacket) seqid() uint32 { return binary.LittleEndian.Uint32(bts) }
--func (bts fecPacket) flag() uint16 { return binary.LittleEndian.Uint16(bts[4:]) }
--func (bts fecPacket) data() []byte { return bts[6:] }
--
--// fecElement has auxcilliary time field
--type fecElement struct {
-- fecPacket
-- ts uint32
--}
--
--// fecDecoder for decoding incoming packets
--type fecDecoder struct {
-- rxlimit int // queue size limit
-- dataShards int
-- parityShards int
-- shardSize int
-- rx []fecElement // ordered receive queue
--
-- // caches
-- decodeCache [][]byte
-- flagCache []bool
--
-- // zeros
-- zeros []byte
--
-- // RS decoder
-- codec reedsolomon.Encoder
--}
--
--func newFECDecoder(rxlimit, dataShards, parityShards int) *fecDecoder {
-- if dataShards <= 0 || parityShards <= 0 {
-- return nil
-- }
-- if rxlimit < dataShards+parityShards {
-- return nil
-- }
--
-- dec := new(fecDecoder)
-- dec.rxlimit = rxlimit
-- dec.dataShards = dataShards
-- dec.parityShards = parityShards
-- dec.shardSize = dataShards + parityShards
-- codec, err := reedsolomon.New(dataShards, parityShards)
-- if err != nil {
-- return nil
-- }
-- dec.codec = codec
-- dec.decodeCache = make([][]byte, dec.shardSize)
-- dec.flagCache = make([]bool, dec.shardSize)
-- dec.zeros = make([]byte, mtuLimit)
-- return dec
--}
--
--// decode a fec packet
--func (dec *fecDecoder) decode(in fecPacket) (recovered [][]byte) {
-- // insertion
-- n := len(dec.rx) - 1
-- insertIdx := 0
-- for i := n; i >= 0; i-- {
-- if in.seqid() == dec.rx[i].seqid() { // de-duplicate
-- return nil
-- } else if _itimediff(in.seqid(), dec.rx[i].seqid()) > 0 { // insertion
-- insertIdx = i + 1
-- break
-- }
-- }
--
-- // make a copy
-- pkt := fecPacket(xmitBuf.Get().([]byte)[:len(in)])
-- copy(pkt, in)
-- elem := fecElement{pkt, currentMs()}
--
-- // insert into ordered rx queue
-- if insertIdx == n+1 {
-- dec.rx = append(dec.rx, elem)
-- } else {
-- dec.rx = append(dec.rx, fecElement{})
-- copy(dec.rx[insertIdx+1:], dec.rx[insertIdx:]) // shift right
-- dec.rx[insertIdx] = elem
-- }
--
-- // shard range for current packet
-- shardBegin := pkt.seqid() - pkt.seqid()%uint32(dec.shardSize)
-- shardEnd := shardBegin + uint32(dec.shardSize) - 1
--
-- // max search range in ordered queue for current shard
-- searchBegin := insertIdx - int(pkt.seqid()%uint32(dec.shardSize))
-- if searchBegin < 0 {
-- searchBegin = 0
-- }
-- searchEnd := searchBegin + dec.shardSize - 1
-- if searchEnd >= len(dec.rx) {
-- searchEnd = len(dec.rx) - 1
-- }
--
-- // re-construct datashards
-- if searchEnd-searchBegin+1 >= dec.dataShards {
-- var numshard, numDataShard, first, maxlen int
--
-- // zero caches
-- shards := dec.decodeCache
-- shardsflag := dec.flagCache
-- for k := range dec.decodeCache {
-- shards[k] = nil
-- shardsflag[k] = false
-- }
--
-- // shard assembly
-- for i := searchBegin; i <= searchEnd; i++ {
-- seqid := dec.rx[i].seqid()
-- if _itimediff(seqid, shardEnd) > 0 {
-- break
-- } else if _itimediff(seqid, shardBegin) >= 0 {
-- shards[seqid%uint32(dec.shardSize)] = dec.rx[i].data()
-- shardsflag[seqid%uint32(dec.shardSize)] = true
-- numshard++
-- if dec.rx[i].flag() == typeData {
-- numDataShard++
-- }
-- if numshard == 1 {
-- first = i
-- }
-- if len(dec.rx[i].data()) > maxlen {
-- maxlen = len(dec.rx[i].data())
-- }
-- }
-- }
--
-- if numDataShard == dec.dataShards {
-- // case 1: no loss on data shards
-- dec.rx = dec.freeRange(first, numshard, dec.rx)
-- } else if numshard >= dec.dataShards {
-- // case 2: loss on data shards, but it's recoverable from parity shards
-- for k := range shards {
-- if shards[k] != nil {
-- dlen := len(shards[k])
-- shards[k] = shards[k][:maxlen]
-- copy(shards[k][dlen:], dec.zeros)
-- } else if k < dec.dataShards {
-- shards[k] = xmitBuf.Get().([]byte)[:0]
-- }
-- }
-- if err := dec.codec.ReconstructData(shards); err == nil {
-- for k := range shards[:dec.dataShards] {
-- if !shardsflag[k] {
-- // recovered data should be recycled
-- recovered = append(recovered, shards[k])
-- }
-- }
-- }
-- dec.rx = dec.freeRange(first, numshard, dec.rx)
-- }
-- }
--
-- // keep rxlimit
-- if len(dec.rx) > dec.rxlimit {
-- if dec.rx[0].flag() == typeData { // track the unrecoverable data
-- atomic.AddUint64(&DefaultSnmp.FECShortShards, 1)
-- }
-- dec.rx = dec.freeRange(0, 1, dec.rx)
-- }
--
-- // timeout policy
-- current := currentMs()
-- numExpired := 0
-- for k := range dec.rx {
-- if _itimediff(current, dec.rx[k].ts) > fecExpire {
-- numExpired++
-- continue
-- }
-- break
-- }
-- if numExpired > 0 {
-- dec.rx = dec.freeRange(0, numExpired, dec.rx)
-- }
-- return
--}
--
--// free a range of fecPacket
--func (dec *fecDecoder) freeRange(first, n int, q []fecElement) []fecElement {
-- for i := first; i < first+n; i++ { // recycle buffer
-- xmitBuf.Put([]byte(q[i].fecPacket))
-- }
--
-- if first == 0 && n < cap(q)/2 {
-- return q[n:]
-- }
-- copy(q[first:], q[first+n:])
-- return q[:len(q)-n]
--}
--
--// release all segments back to xmitBuf
--func (dec *fecDecoder) release() {
-- if n := len(dec.rx); n > 0 {
-- dec.rx = dec.freeRange(0, n, dec.rx)
-- }
--}
--
--type (
-- // fecEncoder for encoding outgoing packets
-- fecEncoder struct {
-- dataShards int
-- parityShards int
-- shardSize int
-- paws uint32 // Protect Against Wrapped Sequence numbers
-- next uint32 // next seqid
--
-- shardCount int // count the number of datashards collected
-- maxSize int // track maximum data length in datashard
--
-- headerOffset int // FEC header offset
-- payloadOffset int // FEC payload offset
--
-- // caches
-- shardCache [][]byte
-- encodeCache [][]byte
--
-- // zeros
-- zeros []byte
--
-- // RS encoder
-- codec reedsolomon.Encoder
-- }
--)
--
--func newFECEncoder(dataShards, parityShards, offset int) *fecEncoder {
-- if dataShards <= 0 || parityShards <= 0 {
-- return nil
-- }
-- enc := new(fecEncoder)
-- enc.dataShards = dataShards
-- enc.parityShards = parityShards
-- enc.shardSize = dataShards + parityShards
-- enc.paws = 0xffffffff / uint32(enc.shardSize) * uint32(enc.shardSize)
-- enc.headerOffset = offset
-- enc.payloadOffset = enc.headerOffset + fecHeaderSize
--
-- codec, err := reedsolomon.New(dataShards, parityShards)
-- if err != nil {
-- return nil
-- }
-- enc.codec = codec
--
-- // caches
-- enc.encodeCache = make([][]byte, enc.shardSize)
-- enc.shardCache = make([][]byte, enc.shardSize)
-- for k := range enc.shardCache {
-- enc.shardCache[k] = make([]byte, mtuLimit)
-- }
-- enc.zeros = make([]byte, mtuLimit)
-- return enc
--}
--
--// encodes the packet, outputs parity shards if we have collected quorum datashards
--// notice: the contents of 'ps' will be re-written in successive calling
--func (enc *fecEncoder) encode(b []byte) (ps [][]byte) {
-- // The header format:
-- // | FEC SEQID(4B) | FEC TYPE(2B) | SIZE (2B) | PAYLOAD(SIZE-2) |
-- // |<-headerOffset |<-payloadOffset
-- enc.markData(b[enc.headerOffset:])
-- binary.LittleEndian.PutUint16(b[enc.payloadOffset:], uint16(len(b[enc.payloadOffset:])))
--
-- // copy data from payloadOffset to fec shard cache
-- sz := len(b)
-- enc.shardCache[enc.shardCount] = enc.shardCache[enc.shardCount][:sz]
-- copy(enc.shardCache[enc.shardCount][enc.payloadOffset:], b[enc.payloadOffset:])
-- enc.shardCount++
--
-- // track max datashard length
-- if sz > enc.maxSize {
-- enc.maxSize = sz
-- }
--
-- // Generation of Reed-Solomon Erasure Code
-- if enc.shardCount == enc.dataShards {
-- // fill '0' into the tail of each datashard
-- for i := 0; i < enc.dataShards; i++ {
-- shard := enc.shardCache[i]
-- slen := len(shard)
-- copy(shard[slen:enc.maxSize], enc.zeros)
-- }
--
-- // construct equal-sized slice with stripped header
-- cache := enc.encodeCache
-- for k := range cache {
-- cache[k] = enc.shardCache[k][enc.payloadOffset:enc.maxSize]
-- }
--
-- // encoding
-- if err := enc.codec.Encode(cache); err == nil {
-- ps = enc.shardCache[enc.dataShards:]
-- for k := range ps {
-- enc.markParity(ps[k][enc.headerOffset:])
-- ps[k] = ps[k][:enc.maxSize]
-- }
-- }
--
-- // counters resetting
-- enc.shardCount = 0
-- enc.maxSize = 0
-- }
--
-- return
--}
--
--func (enc *fecEncoder) markData(data []byte) {
-- binary.LittleEndian.PutUint32(data, enc.next)
-- binary.LittleEndian.PutUint16(data[4:], typeData)
-- enc.next++
--}
--
--func (enc *fecEncoder) markParity(data []byte) {
-- binary.LittleEndian.PutUint32(data, enc.next)
-- binary.LittleEndian.PutUint16(data[4:], typeParity)
-- // sequence wrap will only happen at parity shard
-- enc.next = (enc.next + 1) % enc.paws
--}
-diff --git a/removed.go b/removed.go
-new file mode 100644
-index 0000000..5ecf446
---- /dev/null
-+++ b/removed.go
-@@ -0,0 +1,29 @@
-+package kcp
-+
-+// Dummy implementations for types from crypt.go and fec.go, removed to reduce
-+// dependencies.
-+
-+const (
-+ fecHeaderSize = 6
-+ fecHeaderSizePlus2 = fecHeaderSize + 2
-+ typeData = 0xf1
-+ typeParity = 0xf2
-+)
-+
-+type (
-+ BlockCrypt interface {
-+ Encrypt(_, _ []byte)
-+ Decrypt(_, _ []byte)
-+ }
-+ fecDecoder struct{}
-+ fecEncoder struct{}
-+ fecPacket []byte
-+)
-+
-+func newFECDecoder(rxlimit, dataShards, parityShards int) *fecDecoder { return nil }
-+func newFECEncoder(dataShards, parityShards, offset int) *fecEncoder { return nil }
-+
-+func (_ *fecDecoder) decode(in fecPacket) [][]byte { panic("disabled") }
-+func (_ *fecDecoder) release() { panic("disabled") }
-+func (_ *fecEncoder) encode(b []byte) [][]byte { panic("disabled") }
-+func (_ fecPacket) flag() uint16 { panic("disabled") }
---
-2.20.1
-
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/9…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/9…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/firefox-android] Pushed new tag firefox-android-115.2.1-13.5-1-build3
by ma1 (@ma1) 14 Dec '23
by ma1 (@ma1) 14 Dec '23
14 Dec '23
ma1 pushed new tag firefox-android-115.2.1-13.5-1-build3 at The Tor Project / Applications / firefox-android
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/tree/firef…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/firefox-android] Pushed new tag firefox-android-115.2.1-13.0-1-build11
by ma1 (@ma1) 14 Dec '23
by ma1 (@ma1) 14 Dec '23
14 Dec '23
ma1 pushed new tag firefox-android-115.2.1-13.0-1-build11 at The Tor Project / Applications / firefox-android
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/tree/firef…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/firefox-android][firefox-android-115.2.1-13.5-1] 2 commits: Bug 1823316 - Use 'Snackbar' themed Dialog to notify on making app full-screen
by ma1 (@ma1) 14 Dec '23
by ma1 (@ma1) 14 Dec '23
14 Dec '23
ma1 pushed to branch firefox-android-115.2.1-13.5-1 at The Tor Project / Applications / firefox-android
Commits:
af11e480 by t-p-white at 2023-12-14T20:08:19+01:00
Bug 1823316 - Use 'Snackbar' themed Dialog to notify on making app full-screen
- - - - -
068e68e8 by Tarik Eshaq at 2023-12-14T20:09:55+01:00
Bug 1865488: Adds server parameter to push subscription
(cherry picked from commit f66bc9d4981d9bba7091389d9f0a6864291d38fe)
- - - - -
9 changed files:
- + android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationDialog.kt
- android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFeature.kt
- fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
- fenix/app/src/main/java/org/mozilla/fenix/push/WebPushEngineIntegration.kt
- + fenix/app/src/main/res/layout/full_screen_notification_dialog.xml
- focus-android/app/src/main/java/org/mozilla/focus/browser/integration/FullScreenIntegration.kt
- focus-android/app/src/main/java/org/mozilla/focus/fragment/BrowserFragment.kt
- + focus-android/app/src/main/res/layout/dialog_full_screen_notification.xml
- focus-android/app/src/test/java/org/mozilla/focus/browser/integration/FullScreenIntegrationTest.kt
Changes:
=====================================
android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationDialog.kt
=====================================
@@ -0,0 +1,69 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.prompts.dialog
+
+import android.app.Dialog
+import android.os.Bundle
+import android.view.Gravity
+import android.view.WindowManager
+import androidx.annotation.LayoutRes
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.DialogFragment
+import androidx.fragment.app.FragmentManager
+import androidx.lifecycle.lifecycleScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+private const val TAG = "mozac_feature_prompts_full_screen_notification_dialog"
+private const val SNACKBAR_DURATION_LONG_MS = 3000L
+
+/**
+ * UI to show a 'full screen mode' notification.
+ */
+interface FullScreenNotification {
+ /**
+ * Show the notification.
+ *
+ * @param fragmentManager the [FragmentManager] to add this notification to.
+ */
+ fun show(fragmentManager: FragmentManager)
+}
+
+/**
+ * [DialogFragment] that is configured to match the style and behaviour of a Snackbar.
+ *
+ * @property layout the layout to use for the dialog.
+ */
+class FullScreenNotificationDialog(@LayoutRes val layout: Int) :
+ DialogFragment(), FullScreenNotification {
+ override fun show(fragmentManager: FragmentManager) = super.show(fragmentManager, TAG)
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = requireActivity().let {
+ val view = layoutInflater.inflate(layout, null)
+ AlertDialog.Builder(it).setView(view).create()
+ }
+
+ override fun onStart() {
+ super.onStart()
+
+ dialog?.let { dialog ->
+ dialog.window?.let { window ->
+ // Prevent any user input from key or other button events to it.
+ window.setFlags(
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ )
+
+ window.setGravity(Gravity.BOTTOM)
+ window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
+ }
+
+ lifecycleScope.launch {
+ delay(SNACKBAR_DURATION_LONG_MS)
+ dismiss()
+ }
+ }
+ }
+}
=====================================
android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFeature.kt
=====================================
@@ -70,7 +70,9 @@ import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import java.security.InvalidParameterException
import mozilla.components.ui.icons.R as iconsR
-internal const val FRAGMENT_TAG = "mozac_feature_sitepermissions_prompt_dialog"
+internal const val PROMPT_FRAGMENT_TAG = "mozac_feature_sitepermissions_prompt_dialog"
+
+private const val FULL_SCREEN_NOTIFICATION_TAG = "mozac_feature_prompts_full_screen_notification_dialog"
@VisibleForTesting
internal const val STORAGE_ACCESS_DOCUMENTATION_URL =
@@ -124,7 +126,7 @@ class SitePermissionsFeature(
private var loadingScope: CoroutineScope? = null
override fun start() {
- fragmentManager.findFragmentByTag(FRAGMENT_TAG)?.let { fragment ->
+ fragmentManager.findFragmentByTag(PROMPT_FRAGMENT_TAG)?.let { fragment ->
// There's still a [SitePermissionsDialogFragment] visible from the last time. Re-attach
// this feature so that the fragment can invoke the callback on this feature once the user
// makes a selection. This can happen when the app was in the background and on resume
@@ -439,8 +441,16 @@ class SitePermissionsFeature(
} else {
handleNoRuledFlow(permissionFromStorage, permissionRequest, origin)
}
- prompt?.show(fragmentManager, FRAGMENT_TAG)
- return prompt
+
+ val fullScreenNotificationDisplayed =
+ fragmentManager.fragments.any { fragment -> fragment.tag == FULL_SCREEN_NOTIFICATION_TAG }
+
+ return if (fullScreenNotificationDisplayed || prompt == null) {
+ null
+ } else {
+ prompt.show(fragmentManager, PROMPT_FRAGMENT_TAG)
+ prompt
+ }
}
@VisibleForTesting
=====================================
fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
=====================================
@@ -17,7 +17,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.accessibility.AccessibilityManager
-import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.CallSuper
import androidx.annotation.VisibleForTesting
@@ -74,6 +73,7 @@ import mozilla.components.feature.prompts.PromptFeature
import mozilla.components.feature.prompts.PromptFeature.Companion.PIN_REQUEST
import mozilla.components.feature.prompts.address.AddressDelegate
import mozilla.components.feature.prompts.creditcard.CreditCardDelegate
+import mozilla.components.feature.prompts.dialog.FullScreenNotificationDialog
import mozilla.components.feature.prompts.login.LoginDelegate
import mozilla.components.feature.prompts.share.ShareDelegate
import mozilla.components.feature.readerview.ReaderViewFeature
@@ -1465,10 +1465,11 @@ abstract class BaseBrowserFragment :
if (inFullScreen) {
// Close find in page bar if opened
findInPageIntegration.onBackPressed()
- Toast
- .makeText(requireContext(), R.string.full_screen_notification, Toast.LENGTH_SHORT)
- .show()
- activity?.enterToImmersiveMode()
+
+ FullScreenNotificationDialog(R.layout.full_screen_notification_dialog).show(
+ parentFragmentManager,
+ )
+
(view as? SwipeGestureLayout)?.isSwipeEnabled = false
browserToolbarView.collapse()
browserToolbarView.view.isVisible = false
=====================================
fenix/app/src/main/java/org/mozilla/fenix/push/WebPushEngineIntegration.kt
=====================================
@@ -58,8 +58,6 @@ internal class WebPushEngineDelegate(
private val logger = Logger("WebPushEngineDelegate")
override fun onGetSubscription(scope: String, onSubscription: (WebPushSubscription?) -> Unit) {
- // We don't have the appServerKey unless an app is creating a new subscription so we
- // allow the key to be null since it won't be overridden from a previous subscription.
pushFeature.getSubscription(scope) {
onSubscription(it?.toEnginePushSubscription())
}
@@ -72,9 +70,7 @@ internal class WebPushEngineDelegate(
) {
pushFeature.subscribe(
scope = scope,
- // See the full note at the implementation of `toEnginePushSubscription`.
- // Issue: https://github.com/mozilla/application-services/issues/2698
- appServerKey = null,
+ appServerKey = serverKey?.toEncodedBase64String(),
onSubscribeError = {
logger.error("Error on push onSubscribe.")
onSubscribe(null)
@@ -104,13 +100,12 @@ internal fun AutoPushSubscription.toEnginePushSubscription() = WebPushSubscripti
publicKey = this.publicKey.toDecodedByteArray(),
endpoint = this.endpoint,
authSecret = this.authKey.toDecodedByteArray(),
- // We don't send the `serverKey` because the code path from that will query
- // the push database for this key, which leads to an exception thrown.
- // Our workaround for now is to not put the server key in to begin with (which
- // will probably break a lot of sites).
- // See: https://github.com/mozilla/application-services/issues/2698
+ // We don't have the appServerKey unless an app is creating a new subscription so we
+ // allow the key to be null since it won't be overridden from a previous subscription.
appServerKey = null,
)
private fun String.toDecodedByteArray() =
Base64.decode(this.toByteArray(), Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP)
+private fun ByteArray.toEncodedBase64String() =
+ Base64.encodeToString(this, Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP)
=====================================
fenix/app/src/main/res/layout/full_screen_notification_dialog.xml
=====================================
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/full_screen_notification"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dp"
+ android:background="@drawable/fenix_snackbar_background"
+ android:elevation="4dp"
+ android:minHeight="48dp"
+ android:orientation="horizontal"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp">
+
+ <TextView
+ android:id="@+id/full_screen_notification_text"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:letterSpacing="0.05"
+ android:maxLines="2"
+ android:minHeight="46dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:text="@string/full_screen_notification"
+ android:textAlignment="textStart"
+ android:textColor="@color/photonWhite"
+ android:textSize="18sp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:text="@string/full_screen_notification" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
=====================================
focus-android/app/src/main/java/org/mozilla/focus/browser/integration/FullScreenIntegration.kt
=====================================
@@ -7,12 +7,14 @@ package org.mozilla.focus.browser.integration
import android.app.Activity
import android.os.Build
import android.view.View
-import android.widget.Toast
import androidx.annotation.VisibleForTesting
import androidx.core.view.isVisible
+import androidx.fragment.app.FragmentManager
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.concept.engine.EngineView
+import mozilla.components.feature.prompts.dialog.FullScreenNotification
+import mozilla.components.feature.prompts.dialog.FullScreenNotificationDialog
import mozilla.components.feature.session.FullScreenFeature
import mozilla.components.feature.session.SessionUseCases
import mozilla.components.support.base.feature.LifecycleAwareFeature
@@ -26,6 +28,7 @@ import org.mozilla.focus.ext.hide
import org.mozilla.focus.ext.showAsFixed
import org.mozilla.focus.utils.Settings
+@Suppress("LongParameterList")
class FullScreenIntegration(
val activity: Activity,
val store: BrowserStore,
@@ -35,6 +38,7 @@ class FullScreenIntegration(
private val toolbarView: BrowserToolbar,
private val statusBar: View,
private val engineView: EngineView,
+ private val parentFragmentManager: FragmentManager,
) : LifecycleAwareFeature, UserInteractionHandler {
@VisibleForTesting
internal var feature = FullScreenFeature(
@@ -54,14 +58,16 @@ class FullScreenIntegration(
}
@VisibleForTesting
- internal fun fullScreenChanged(enabled: Boolean) {
+ internal fun fullScreenChanged(
+ enabled: Boolean,
+ fullScreenNotification: FullScreenNotification =
+ FullScreenNotificationDialog(R.layout.dialog_full_screen_notification),
+ ) {
if (enabled) {
enterBrowserFullscreen()
statusBar.isVisible = false
- Toast
- .makeText(activity, R.string.full_screen_notification, Toast.LENGTH_SHORT)
- .show()
+ fullScreenNotification.show(parentFragmentManager)
switchToImmersiveMode()
} else {
=====================================
focus-android/app/src/main/java/org/mozilla/focus/fragment/BrowserFragment.kt
=====================================
@@ -272,6 +272,7 @@ class BrowserFragment :
binding.browserToolbar,
binding.statusBarBackground,
binding.engineView,
+ parentFragmentManager,
),
this,
view,
=====================================
focus-android/app/src/main/res/layout/dialog_full_screen_notification.xml
=====================================
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/full_screen_notification_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="8dp"
+ android:background="@drawable/focus_snackbar_background"
+ android:elevation="4dp"
+ android:minHeight="48dp"
+ android:orientation="horizontal"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp">
+
+ <TextView
+ android:id="@+id/full_screen_notification_text"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:letterSpacing="0.05"
+ android:maxLines="2"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:text="@string/full_screen_notification"
+ android:textAlignment="textStart"
+ android:textColor="@color/snackbarTextColor"
+ android:textSize="14sp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:text="@string/full_screen_notification" />
+</androidx.constraintlayout.widget.ConstraintLayout>
=====================================
focus-android/app/src/test/java/org/mozilla/focus/browser/integration/FullScreenIntegrationTest.kt
=====================================
@@ -12,11 +12,11 @@ import android.view.WindowManager
import androidx.core.view.isVisible
import mozilla.components.browser.engine.gecko.GeckoEngineView
import mozilla.components.browser.toolbar.BrowserToolbar
+import mozilla.components.feature.prompts.dialog.FullScreenNotification
import mozilla.components.feature.session.FullScreenFeature
import mozilla.components.support.test.any
import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.testContext
-import org.junit.Assert.assertNotNull
import org.junit.Test
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.runner.RunWith
@@ -26,7 +26,6 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
-import org.mozilla.focus.R
import org.mozilla.focus.ext.disableDynamicBehavior
import org.mozilla.focus.ext.enableDynamicBehavior
import org.mozilla.focus.ext.hide
@@ -34,7 +33,6 @@ import org.mozilla.focus.ext.showAsFixed
import org.mozilla.focus.utils.Settings
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
-import org.robolectric.shadows.ShadowToast
@RunWith(RobolectricTestRunner::class)
internal class FullScreenIntegrationTest {
@@ -50,6 +48,7 @@ internal class FullScreenIntegrationTest {
mock(),
mock(),
mock(),
+ mock(),
).apply {
this.feature = feature
}
@@ -71,6 +70,7 @@ internal class FullScreenIntegrationTest {
mock(),
mock(),
mock(),
+ mock(),
).apply {
this.feature = feature
}
@@ -92,6 +92,7 @@ internal class FullScreenIntegrationTest {
mock(),
mock(),
mock(),
+ mock(),
).apply {
this.feature = feature
}
@@ -117,6 +118,7 @@ internal class FullScreenIntegrationTest {
mock(),
mock(),
mock(),
+ mock(),
)
integration.viewportFitChanged(33)
@@ -141,6 +143,7 @@ internal class FullScreenIntegrationTest {
mock(),
mock(),
mock(),
+ mock(),
)
integration.switchToImmersiveMode()
@@ -169,6 +172,7 @@ internal class FullScreenIntegrationTest {
mock(),
mock(),
mock(),
+ mock(),
)
integration.exitImmersiveMode()
@@ -195,6 +199,7 @@ internal class FullScreenIntegrationTest {
toolbar,
mock(),
engineView,
+ mock(),
)
integration.enterBrowserFullscreen()
@@ -220,6 +225,7 @@ internal class FullScreenIntegrationTest {
toolbar,
mock(),
engineView,
+ mock(),
)
integration.enterBrowserFullscreen()
@@ -250,6 +256,7 @@ internal class FullScreenIntegrationTest {
toolbar,
mock(),
engineView,
+ mock(),
)
integration.exitBrowserFullscreen()
@@ -278,6 +285,7 @@ internal class FullScreenIntegrationTest {
toolbar,
mock(),
engineView,
+ mock(),
)
integration.exitBrowserFullscreen()
@@ -308,21 +316,17 @@ internal class FullScreenIntegrationTest {
toolbar,
statusBar,
engineView,
+ mock(),
),
)
- integration.fullScreenChanged(true)
+ val fullScreenNotification = mock<FullScreenNotification>()
+ integration.fullScreenChanged(true, fullScreenNotification)
verify(integration).enterBrowserFullscreen()
- verify(integration).switchToImmersiveMode()
verify(statusBar).isVisible = false
-
- val toast = ShadowToast.getTextOfLatestToast()
- assertNotNull(toast)
- assertEquals(
- testContext.getString(R.string.full_screen_notification),
- toast,
- )
+ verify(fullScreenNotification).show(any())
+ verify(integration).switchToImmersiveMode()
}
@Test
@@ -352,6 +356,7 @@ internal class FullScreenIntegrationTest {
toolbar,
statusBar,
engineView,
+ mock(),
),
)
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/compare/06…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/compare/06…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/firefox-android][firefox-android-115.2.1-13.0-1] 2 commits: Bug 1823316 - Use 'Snackbar' themed Dialog to notify on making app full-screen
by richard (@richard) 14 Dec '23
by richard (@richard) 14 Dec '23
14 Dec '23
richard pushed to branch firefox-android-115.2.1-13.0-1 at The Tor Project / Applications / firefox-android
Commits:
a0805d02 by t-p-white at 2023-12-14T15:36:13+01:00
Bug 1823316 - Use 'Snackbar' themed Dialog to notify on making app full-screen
- - - - -
8ff2dd1b by Tarik Eshaq at 2023-12-14T15:36:22+01:00
Bug 1865488: Adds server parameter to push subscription
(cherry picked from commit f66bc9d4981d9bba7091389d9f0a6864291d38fe)
- - - - -
9 changed files:
- + android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationDialog.kt
- android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFeature.kt
- fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
- fenix/app/src/main/java/org/mozilla/fenix/push/WebPushEngineIntegration.kt
- + fenix/app/src/main/res/layout/full_screen_notification_dialog.xml
- focus-android/app/src/main/java/org/mozilla/focus/browser/integration/FullScreenIntegration.kt
- focus-android/app/src/main/java/org/mozilla/focus/fragment/BrowserFragment.kt
- + focus-android/app/src/main/res/layout/dialog_full_screen_notification.xml
- focus-android/app/src/test/java/org/mozilla/focus/browser/integration/FullScreenIntegrationTest.kt
Changes:
=====================================
android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationDialog.kt
=====================================
@@ -0,0 +1,69 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.prompts.dialog
+
+import android.app.Dialog
+import android.os.Bundle
+import android.view.Gravity
+import android.view.WindowManager
+import androidx.annotation.LayoutRes
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.DialogFragment
+import androidx.fragment.app.FragmentManager
+import androidx.lifecycle.lifecycleScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+private const val TAG = "mozac_feature_prompts_full_screen_notification_dialog"
+private const val SNACKBAR_DURATION_LONG_MS = 3000L
+
+/**
+ * UI to show a 'full screen mode' notification.
+ */
+interface FullScreenNotification {
+ /**
+ * Show the notification.
+ *
+ * @param fragmentManager the [FragmentManager] to add this notification to.
+ */
+ fun show(fragmentManager: FragmentManager)
+}
+
+/**
+ * [DialogFragment] that is configured to match the style and behaviour of a Snackbar.
+ *
+ * @property layout the layout to use for the dialog.
+ */
+class FullScreenNotificationDialog(@LayoutRes val layout: Int) :
+ DialogFragment(), FullScreenNotification {
+ override fun show(fragmentManager: FragmentManager) = super.show(fragmentManager, TAG)
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = requireActivity().let {
+ val view = layoutInflater.inflate(layout, null)
+ AlertDialog.Builder(it).setView(view).create()
+ }
+
+ override fun onStart() {
+ super.onStart()
+
+ dialog?.let { dialog ->
+ dialog.window?.let { window ->
+ // Prevent any user input from key or other button events to it.
+ window.setFlags(
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ )
+
+ window.setGravity(Gravity.BOTTOM)
+ window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
+ }
+
+ lifecycleScope.launch {
+ delay(SNACKBAR_DURATION_LONG_MS)
+ dismiss()
+ }
+ }
+ }
+}
=====================================
android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFeature.kt
=====================================
@@ -70,7 +70,9 @@ import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import java.security.InvalidParameterException
import mozilla.components.ui.icons.R as iconsR
-internal const val FRAGMENT_TAG = "mozac_feature_sitepermissions_prompt_dialog"
+internal const val PROMPT_FRAGMENT_TAG = "mozac_feature_sitepermissions_prompt_dialog"
+
+private const val FULL_SCREEN_NOTIFICATION_TAG = "mozac_feature_prompts_full_screen_notification_dialog"
@VisibleForTesting
internal const val STORAGE_ACCESS_DOCUMENTATION_URL =
@@ -124,7 +126,7 @@ class SitePermissionsFeature(
private var loadingScope: CoroutineScope? = null
override fun start() {
- fragmentManager.findFragmentByTag(FRAGMENT_TAG)?.let { fragment ->
+ fragmentManager.findFragmentByTag(PROMPT_FRAGMENT_TAG)?.let { fragment ->
// There's still a [SitePermissionsDialogFragment] visible from the last time. Re-attach
// this feature so that the fragment can invoke the callback on this feature once the user
// makes a selection. This can happen when the app was in the background and on resume
@@ -439,8 +441,16 @@ class SitePermissionsFeature(
} else {
handleNoRuledFlow(permissionFromStorage, permissionRequest, origin)
}
- prompt?.show(fragmentManager, FRAGMENT_TAG)
- return prompt
+
+ val fullScreenNotificationDisplayed =
+ fragmentManager.fragments.any { fragment -> fragment.tag == FULL_SCREEN_NOTIFICATION_TAG }
+
+ return if (fullScreenNotificationDisplayed || prompt == null) {
+ null
+ } else {
+ prompt.show(fragmentManager, PROMPT_FRAGMENT_TAG)
+ prompt
+ }
}
@VisibleForTesting
=====================================
fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
=====================================
@@ -17,7 +17,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.accessibility.AccessibilityManager
-import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.CallSuper
import androidx.annotation.VisibleForTesting
@@ -74,6 +73,7 @@ import mozilla.components.feature.prompts.PromptFeature
import mozilla.components.feature.prompts.PromptFeature.Companion.PIN_REQUEST
import mozilla.components.feature.prompts.address.AddressDelegate
import mozilla.components.feature.prompts.creditcard.CreditCardDelegate
+import mozilla.components.feature.prompts.dialog.FullScreenNotificationDialog
import mozilla.components.feature.prompts.login.LoginDelegate
import mozilla.components.feature.prompts.share.ShareDelegate
import mozilla.components.feature.readerview.ReaderViewFeature
@@ -1465,10 +1465,11 @@ abstract class BaseBrowserFragment :
if (inFullScreen) {
// Close find in page bar if opened
findInPageIntegration.onBackPressed()
- Toast
- .makeText(requireContext(), R.string.full_screen_notification, Toast.LENGTH_SHORT)
- .show()
- activity?.enterToImmersiveMode()
+
+ FullScreenNotificationDialog(R.layout.full_screen_notification_dialog).show(
+ parentFragmentManager,
+ )
+
(view as? SwipeGestureLayout)?.isSwipeEnabled = false
browserToolbarView.collapse()
browserToolbarView.view.isVisible = false
=====================================
fenix/app/src/main/java/org/mozilla/fenix/push/WebPushEngineIntegration.kt
=====================================
@@ -58,8 +58,6 @@ internal class WebPushEngineDelegate(
private val logger = Logger("WebPushEngineDelegate")
override fun onGetSubscription(scope: String, onSubscription: (WebPushSubscription?) -> Unit) {
- // We don't have the appServerKey unless an app is creating a new subscription so we
- // allow the key to be null since it won't be overridden from a previous subscription.
pushFeature.getSubscription(scope) {
onSubscription(it?.toEnginePushSubscription())
}
@@ -72,9 +70,7 @@ internal class WebPushEngineDelegate(
) {
pushFeature.subscribe(
scope = scope,
- // See the full note at the implementation of `toEnginePushSubscription`.
- // Issue: https://github.com/mozilla/application-services/issues/2698
- appServerKey = null,
+ appServerKey = serverKey?.toEncodedBase64String(),
onSubscribeError = {
logger.error("Error on push onSubscribe.")
onSubscribe(null)
@@ -104,13 +100,12 @@ internal fun AutoPushSubscription.toEnginePushSubscription() = WebPushSubscripti
publicKey = this.publicKey.toDecodedByteArray(),
endpoint = this.endpoint,
authSecret = this.authKey.toDecodedByteArray(),
- // We don't send the `serverKey` because the code path from that will query
- // the push database for this key, which leads to an exception thrown.
- // Our workaround for now is to not put the server key in to begin with (which
- // will probably break a lot of sites).
- // See: https://github.com/mozilla/application-services/issues/2698
+ // We don't have the appServerKey unless an app is creating a new subscription so we
+ // allow the key to be null since it won't be overridden from a previous subscription.
appServerKey = null,
)
private fun String.toDecodedByteArray() =
Base64.decode(this.toByteArray(), Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP)
+private fun ByteArray.toEncodedBase64String() =
+ Base64.encodeToString(this, Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP)
=====================================
fenix/app/src/main/res/layout/full_screen_notification_dialog.xml
=====================================
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/full_screen_notification"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dp"
+ android:background="@drawable/fenix_snackbar_background"
+ android:elevation="4dp"
+ android:minHeight="48dp"
+ android:orientation="horizontal"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp">
+
+ <TextView
+ android:id="@+id/full_screen_notification_text"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:letterSpacing="0.05"
+ android:maxLines="2"
+ android:minHeight="46dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:text="@string/full_screen_notification"
+ android:textAlignment="textStart"
+ android:textColor="@color/photonWhite"
+ android:textSize="18sp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:text="@string/full_screen_notification" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
=====================================
focus-android/app/src/main/java/org/mozilla/focus/browser/integration/FullScreenIntegration.kt
=====================================
@@ -7,12 +7,14 @@ package org.mozilla.focus.browser.integration
import android.app.Activity
import android.os.Build
import android.view.View
-import android.widget.Toast
import androidx.annotation.VisibleForTesting
import androidx.core.view.isVisible
+import androidx.fragment.app.FragmentManager
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.concept.engine.EngineView
+import mozilla.components.feature.prompts.dialog.FullScreenNotification
+import mozilla.components.feature.prompts.dialog.FullScreenNotificationDialog
import mozilla.components.feature.session.FullScreenFeature
import mozilla.components.feature.session.SessionUseCases
import mozilla.components.support.base.feature.LifecycleAwareFeature
@@ -26,6 +28,7 @@ import org.mozilla.focus.ext.hide
import org.mozilla.focus.ext.showAsFixed
import org.mozilla.focus.utils.Settings
+@Suppress("LongParameterList")
class FullScreenIntegration(
val activity: Activity,
val store: BrowserStore,
@@ -35,6 +38,7 @@ class FullScreenIntegration(
private val toolbarView: BrowserToolbar,
private val statusBar: View,
private val engineView: EngineView,
+ private val parentFragmentManager: FragmentManager,
) : LifecycleAwareFeature, UserInteractionHandler {
@VisibleForTesting
internal var feature = FullScreenFeature(
@@ -54,14 +58,16 @@ class FullScreenIntegration(
}
@VisibleForTesting
- internal fun fullScreenChanged(enabled: Boolean) {
+ internal fun fullScreenChanged(
+ enabled: Boolean,
+ fullScreenNotification: FullScreenNotification =
+ FullScreenNotificationDialog(R.layout.dialog_full_screen_notification),
+ ) {
if (enabled) {
enterBrowserFullscreen()
statusBar.isVisible = false
- Toast
- .makeText(activity, R.string.full_screen_notification, Toast.LENGTH_SHORT)
- .show()
+ fullScreenNotification.show(parentFragmentManager)
switchToImmersiveMode()
} else {
=====================================
focus-android/app/src/main/java/org/mozilla/focus/fragment/BrowserFragment.kt
=====================================
@@ -272,6 +272,7 @@ class BrowserFragment :
binding.browserToolbar,
binding.statusBarBackground,
binding.engineView,
+ parentFragmentManager,
),
this,
view,
=====================================
focus-android/app/src/main/res/layout/dialog_full_screen_notification.xml
=====================================
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/full_screen_notification_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="8dp"
+ android:background="@drawable/focus_snackbar_background"
+ android:elevation="4dp"
+ android:minHeight="48dp"
+ android:orientation="horizontal"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp">
+
+ <TextView
+ android:id="@+id/full_screen_notification_text"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:letterSpacing="0.05"
+ android:maxLines="2"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:text="@string/full_screen_notification"
+ android:textAlignment="textStart"
+ android:textColor="@color/snackbarTextColor"
+ android:textSize="14sp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:text="@string/full_screen_notification" />
+</androidx.constraintlayout.widget.ConstraintLayout>
=====================================
focus-android/app/src/test/java/org/mozilla/focus/browser/integration/FullScreenIntegrationTest.kt
=====================================
@@ -12,11 +12,11 @@ import android.view.WindowManager
import androidx.core.view.isVisible
import mozilla.components.browser.engine.gecko.GeckoEngineView
import mozilla.components.browser.toolbar.BrowserToolbar
+import mozilla.components.feature.prompts.dialog.FullScreenNotification
import mozilla.components.feature.session.FullScreenFeature
import mozilla.components.support.test.any
import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.testContext
-import org.junit.Assert.assertNotNull
import org.junit.Test
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.runner.RunWith
@@ -26,7 +26,6 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
-import org.mozilla.focus.R
import org.mozilla.focus.ext.disableDynamicBehavior
import org.mozilla.focus.ext.enableDynamicBehavior
import org.mozilla.focus.ext.hide
@@ -34,7 +33,6 @@ import org.mozilla.focus.ext.showAsFixed
import org.mozilla.focus.utils.Settings
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
-import org.robolectric.shadows.ShadowToast
@RunWith(RobolectricTestRunner::class)
internal class FullScreenIntegrationTest {
@@ -50,6 +48,7 @@ internal class FullScreenIntegrationTest {
mock(),
mock(),
mock(),
+ mock(),
).apply {
this.feature = feature
}
@@ -71,6 +70,7 @@ internal class FullScreenIntegrationTest {
mock(),
mock(),
mock(),
+ mock(),
).apply {
this.feature = feature
}
@@ -92,6 +92,7 @@ internal class FullScreenIntegrationTest {
mock(),
mock(),
mock(),
+ mock(),
).apply {
this.feature = feature
}
@@ -117,6 +118,7 @@ internal class FullScreenIntegrationTest {
mock(),
mock(),
mock(),
+ mock(),
)
integration.viewportFitChanged(33)
@@ -141,6 +143,7 @@ internal class FullScreenIntegrationTest {
mock(),
mock(),
mock(),
+ mock(),
)
integration.switchToImmersiveMode()
@@ -169,6 +172,7 @@ internal class FullScreenIntegrationTest {
mock(),
mock(),
mock(),
+ mock(),
)
integration.exitImmersiveMode()
@@ -195,6 +199,7 @@ internal class FullScreenIntegrationTest {
toolbar,
mock(),
engineView,
+ mock(),
)
integration.enterBrowserFullscreen()
@@ -220,6 +225,7 @@ internal class FullScreenIntegrationTest {
toolbar,
mock(),
engineView,
+ mock(),
)
integration.enterBrowserFullscreen()
@@ -250,6 +256,7 @@ internal class FullScreenIntegrationTest {
toolbar,
mock(),
engineView,
+ mock(),
)
integration.exitBrowserFullscreen()
@@ -278,6 +285,7 @@ internal class FullScreenIntegrationTest {
toolbar,
mock(),
engineView,
+ mock(),
)
integration.exitBrowserFullscreen()
@@ -308,21 +316,17 @@ internal class FullScreenIntegrationTest {
toolbar,
statusBar,
engineView,
+ mock(),
),
)
- integration.fullScreenChanged(true)
+ val fullScreenNotification = mock<FullScreenNotification>()
+ integration.fullScreenChanged(true, fullScreenNotification)
verify(integration).enterBrowserFullscreen()
- verify(integration).switchToImmersiveMode()
verify(statusBar).isVisible = false
-
- val toast = ShadowToast.getTextOfLatestToast()
- assertNotNull(toast)
- assertEquals(
- testContext.getString(R.string.full_screen_notification),
- toast,
- )
+ verify(fullScreenNotification).show(any())
+ verify(integration).switchToImmersiveMode()
}
@Test
@@ -352,6 +356,7 @@ internal class FullScreenIntegrationTest {
toolbar,
statusBar,
engineView,
+ mock(),
),
)
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/compare/33…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/compare/33…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/mullvad-browser][mullvad-browser-115.6.0esr-13.0-1] squash! MB 79: Add Mullvad Browser MAR signing keys
by boklm (@boklm) 14 Dec '23
by boklm (@boklm) 14 Dec '23
14 Dec '23
boklm pushed to branch mullvad-browser-115.6.0esr-13.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
65b3f1db by Nicolas Vigier at 2023-12-14T16:46:37+01:00
squash! MB 79: Add Mullvad Browser MAR signing keys
MB 256: Add mullvad-browser nightly mar signing key
- - - - -
2 changed files:
- toolkit/mozapps/update/updater/nightly_aurora_level3_primary.der
- toolkit/mozapps/update/updater/nightly_aurora_level3_secondary.der
Changes:
=====================================
toolkit/mozapps/update/updater/nightly_aurora_level3_primary.der
=====================================
Binary files a/toolkit/mozapps/update/updater/nightly_aurora_level3_primary.der and b/toolkit/mozapps/update/updater/nightly_aurora_level3_primary.der differ
=====================================
toolkit/mozapps/update/updater/nightly_aurora_level3_secondary.der
=====================================
Binary files a/toolkit/mozapps/update/updater/nightly_aurora_level3_secondary.der and b/toolkit/mozapps/update/updater/nightly_aurora_level3_secondary.der differ
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/65b…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/65b…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser-build][main] Bug 41043: Create script to push build requests to Mullvad build servers
by richard (@richard) 14 Dec '23
by richard (@richard) 14 Dec '23
14 Dec '23
richard pushed to branch main at The Tor Project / Applications / tor-browser-build
Commits:
338d8950 by Richard Pospesel at 2023-12-14T16:11:19+00:00
Bug 41043: Create script to push build requests to Mullvad build servers
- - - - -
4 changed files:
- Makefile
- projects/release/config
- + projects/release/kick_devmole_build
- rbm.local.conf.example
Changes:
=====================================
Makefile
=====================================
@@ -685,6 +685,10 @@ torbrowser-signtag-release: submodule-update
torbrowser-signtag-alpha: submodule-update
$(rbm) build release --step signtag --target alpha --target torbrowser
+# requires var/devmole_auth_token to be set in rbm.local.conf
+torbrowser-kick-devmole-build: submodule-update
+ $(rbm) build release --step kick_devmole_build --target torbrowser
+
# requires tpo_user variable be set in rbm.local.conf
mullvadbrowser-upload-sha256sums-release: submodule-update
$(rbm) build release --step upload_sha256sums --target release --target mullvadbrowser
@@ -699,6 +703,10 @@ mullvadbrowser-signtag-release: submodule-update
mullvadbrowser-signtag-alpha: submodule-update
$(rbm) build release --step signtag --target alpha --target mullvadbrowser
+# requires var/devmole_auth_token to be set in rbm.local.conf
+mullvadbrowser-kick-devmole-build: submodule-update
+ $(rbm) build release --step kick_devmole_build --target mullvadbrowser
+
fetch: submodule-update
$(rbm) fetch
=====================================
projects/release/config
=====================================
@@ -279,3 +279,8 @@ steps:
name: mar-tools
pkg_type: fetch_martools
compare_mar_signed_unsigned: '[% INCLUDE compare_mar_signed_unsigned %]'
+ kick_devmole_build:
+ build_log: '-'
+ debug: 0
+ input_files: []
+ kick_devmole_build: '[% INCLUDE kick_devmole_build %]'
=====================================
projects/release/kick_devmole_build
=====================================
@@ -0,0 +1,42 @@
+#!/usr/bin/bash
+
+# This script triggers a build of Tor or Mullvad Browser on Mullvad Infrastructure
+# Hashes are saved here: https://cdn.stagemole.eu/hashes/
+# A Mullvad build server auth token (var/devmole_auth_token) is required to build
+# For now you have to be connecting from Sweden (ie via Malmö or Gothenburg exits using MullvadVPN) for your request to succeed
+
+set -e
+
+# get our build tag
+TAG=[% c("var/git_tag_prefix") %]-[% c("var/torbrowser_version") %]-[% c("var/torbrowser_build") %]
+
+# check for tag existence
+if ! git rev-parse ${TAG} > /dev/null 2>&1; then
+ echo "Error: build tag '${TAG}' does not exist"
+ exit 1
+fi
+
+# determine whether alpha or release based on the build tag
+RELEASE=
+if [[ "${TAG}" =~ ^(mb|tbb)-[1-9][0-9]\.[05]a[1-9][0-9]*-build[1-9]$ ]]; then
+ RELEASE="alpha"
+elif [[ "${TAG}" =~ ^(mb|tbb)-[1-9][0-9]\.[05](\.[1-9][0-9]*)?-build[1-9]$ ]]; then
+ RELEASE="release"
+else
+ echo "Error: malformed build tag '${TAG}'"
+ exit 1
+fi
+
+# get auth token for submission to devmole build server
+AUTH_TOKEN=[% c("buildconf/devmole_auth_token") %]
+if [[ "${AUTH_TOKEN}" = "" ]]; then
+ echo "AUTH_TOKEN: ${AUTH_TOKEN}"
+ echo "Error: buildconf/devmole_auth_token missing from rbm.local.conf"
+ exit 1
+fi
+
+# make request
+curl -X POST "https://drone-server.devmole.eu/api/repos/mullvad/browser-build/builds?bran…" -H "Authorization: Bearer ${AUTH_TOKEN}" -H "Accept: application/json"
+
+echo
+echo Hashes will appear here: https://cdn.stagemole.eu/hashes/[% c("var/projectname") %]/[% c("var/torbrowser_version") %]-[% c("var/torbrowser_build") %]
=====================================
rbm.local.conf.example
=====================================
@@ -42,6 +42,11 @@ buildconf:
### signing the tag.
#git_signtag_opt: '-u keyid'
+ ### The buildconf/devmole_auth_token option is used for starting remote builds on
+ ### Mullvad's devmole server using the kick_devmole_build step in the release
+ ### project. Such a token can be acquired from the Mullvad sysadmins.
+ #devmole_auth_token: abcdefghijklmnopqrstuvwxyz012345
+
var:
local_conf: 1
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/3…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/3…
You're receiving this email because of your account on gitlab.torproject.org.
1
0