* Adds `checkForPdfViewer` to determine if page is a PDF Viewer page or not
* Adjusts save_to_pdf_failure to have extras of pdf, non-pdf, or unknown
* Adjusts save_to_pdf_failure to have extras of failure reason
* Adjusts save_to_pdf_tapped to have extras of pdf, non-pdf, or unknown
* Adds save_to_pdf_completed with extras of pdf, non-pdf, or unknown
* Bug 1820211 - Adds `tabKilled` event to track when a tab was killed with form data.
- Also includes if the tab was the active tab and whether the app was in the foreground.
* Bug 1820211 - Adds tests for TelemetryMiddleware and StoreLifecycleObserver
* Bug 1820211 - Renames CheckFormDataAction to UpdateHasFormData
- Removes @property hasFormData comment from sessionState
- Moves checking formdata from TabContentMiddleware to SessionPrioritizationMiddleware
---------
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Upgrade kotlin to 1.7.20, coroutines to 1.6.4 and compose compiler to 1.3.2.
Replace deprecated Xopt-in with op-in.
Replace deprecated Xjvm-default=enable with Xjvm-default=all.
Remove useIR property that is now default true.
Adds support for Save to PDF from the GeckoSession by plugging the
API into `onExternalResponse` to provide the same flow as a typical
file download experience would be.
Co-authored-by: Olivia Hall <ohall@mozilla.com>
Used `runTestOnMain` where `MainCoroutineRule` was used or needed to be used,
`runTest` elsewhere.
Extra effort for removing all `runBlocking` occurrences in unit tests.
`kotlinx.coroutines.test.runTest` is a test specific API that seems like a more
appropriate way for running tests in a coroutine than the general
`kotlinx.coroutines.runBlocking` api.
- Refactor out all usages of TestCoroutineDispatcher and TestCoroutineScope
- Refactor MainCoroutineRule to now use UnconfinedTestDispatcher by default.
This dispatcher will eagerly enter all launch or async blocks being more suited
to our codebase.
This also required updating room to >= 2.4.0.
This new version adds a deprecation of the `MigrationTestHelper` api used in
`LoginExceptionStorageTest` that is to be later fixed in https://github.com/mozilla-mobile/android-components/issues/11765.
`activity_compose` was also update to the latest stable version to ensure a
better match with the latest stable version for compose.
Used 1.6.10 for Kotlin although 1.6.20 is available to prevent any issues with
Compose 1.1.1 reported as an error at compile time:
"e: This version (1.1.1) of the Compose Compiler requires Kotlin version 1.6.10
but you appear to be using Kotlin version 1.6.20 which is not known to be
compatible. Please fix your configuration (or
`suppressKotlinVersionCompatibilityCheck` but don't say I didn't warn you!)."
This also required updating room to >= 2.4.0.
This new version adds a deprecation of the `MigrationTestHelper` api used in
`LoginExceptionStorageTest` that is to be later fixed in https://github.com/mozilla-mobile/android-components/issues/11765.
activity_compose was also update to the latest stable version to ensure a
better match with the latest stable version for compose.
This change splits out tab-specific data from RecoverableTab data class
into a separate TabState (so, it doesn't have the EngineSessionState).
Then, once we have the simplified TabState, everything that touches RecentlyClosedTabs
is converted to use that instead of its more expensive sibling.
This way we avoid having to eagerly process EngineSessionState simply to populate BrowserState.closedTabs.
This saves us from having to hit disk (where the EngineSessionState is persisted) on initializing BrowserState (so, startup in most cases).
It also saves us from having to parse/rehydrate that persisted state.
At the point we actually need the EngineSessionState for a tab we'd like to restore, we can read/process it.
* Add MoveTabsAction and tests for it
* Add MoveTabsUseCase and a test
* Add getFilter to TabsFeature
* ktlint/detekt formating pass
* Changelog entry
* Fix cut off comment
* Remove action reference comment
* Remove unneeded setting of selectedTabId in copy
* Replace filter getter with just making the variable public
It's simpler and I can't see why it shouldn't be modifiable.
* API change from position+filter to target+placeAfter.
Also added a "tab not found" check.
* Add another test, clean up changelog
* Animate moving tabs via movement rather than add+delete.
* Put Private modifier back, improve documentation.
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
* Refactored the tab restoration flow to support restoring tabs at their original index.
* Lint check fixes
* Refactored the index class variable name and made it non-null
* Refactored RestoreAction to take an ENUM for a restoration location.
* Cleaned up tests and lint errors
* Fixed broken test after restore tab refactor
* Refactored the location of RestoreLocation and revised instances of "removalIndex"
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
* For https://github.com/mozilla-mobile/android-components/issues/10560: Fixed bug causing external links to open tabs irrespective of the session's private status
* Updated findTabByUrl function names and comments for better clarity
* Fixed import detekt issue
* Refactored selectors test for better clarity
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
We wanted to introduce this action for testing purposes in client apps
that want to "turn back time" for a certain tab.
The difficulty is in ensuring clients do not misuse these actions, and
we thought of a few strategies:
- Option 1: Make a separate grouping called `DebugAction` and document
that these are special actions.
- Option 2: Using a middleware, we only allow changes to the store
depending on some dynmamic logic in the client app. This is a bit
complicated and requries the user to restart the app to add this
special middleware.
- Option 3: Add an annotation that requires the client to opt into using
the action.
In this patch, I decided to go with a combination of options 1 and 3
which gave us the right about of warning and flexibility.
With option 2, we were still required to add new actions to the store
and the middleware would not have prevented misuse in those cases.
Mainly, does two things:
- refactors SessionState.Source into a richer form (splitting sources
into Internal and External, where External ones track information
about originating package)
- adds persistence of External sources into tab session state; we don't
want to persist Internal sources as that was explicitly removed before
for causing various issues (e.g. UI behaving incorrectly after
restoring tabs with various internal sources set)
This new property helps with separating the current responsibilities of
lastMediaAccess such that after this:
- lastMediaAccess is only updated when media starts playing allowing clients to
order media tabs and find the first / last tab with in progress media.
- lastHadMediaSessionActive indicates whether a MediaSession should be active
for this tab and serves as a backup for lastMediaUrl for the situations where a
website might allow media to continue playing even when the users accesses
another page (with another URL) in that same HTML document.
Renamed "BrowserState.updateTabState" to a more appropriate
"BrowserState.updateTabOrCustomTabState" signaling that it can be used to
update any tab or custom tab.
Created two new "BrowserState.updateTabState" and
"BrowserState.updateCustomTabState" extension methods to allow updating the
state of either tabs or custom tabs depending on the properties needing update.
By this we are forcing the clients to choose what type of SessionState they
want updated and in so limiting the situations in which the old API would try
to update any SessionState and could throw a ClassCastException if in the
"update" lambda parameter callers would try to update a property not existing
in one SessionState implementation but available in other.
LastMediaAccessState contains both
- lastMediaAccess - timestamp for the last time media started playing
(which is reset to 0 when GV deactivates the MediaSession)
- lastMediaUrl - tab url when media started playing
By combining this two properties we'll know that a tab has in progress media
even when:
- the user navigates to another page in the same document
but media continues to play, MediaSession exists, lastMediaAccess is not reset,
- media starts playing in another tab
but the previous media tab has the same url as lastMediaUrl.
After media starting to play in a tab only if
- user navigated to another website and
- MediaSession is deactivated (happens when navigating to another website or
when media starts playing in another tab)
will we consider that this tab doesn't anymore have in progress media.