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.
This new property will be a timestamp of the last time media started playing in
the current page or be 0 if media hadn't started playing or another page loaded
in this tab so media was stopped.
To observe the media changes and update this property LastMediaAccessMiddleware
will have to be set on BrowserStore.
This makes sure observers see the crashed state of a tab update
before the engine session is set to null. This is important so
observers can react to crashes and won't immediately request a
new engine session.
Following crash reports it was seen that it is possible for multiple prompts to
be shown at the same time with an edgecase being that one prompt request comes
after the user interacted with a previous prompt but before the consume call
completing in AC / GV time at which this code will try to use the new prompt,
not the one the user interacted with.
Having support for multiple prompt requests in ContentState and tightly
coupling a PromptDialogFragment with it's PromptRequest ensures any action
consuming a PromptDialogFragment will always consume the PromptRequest for
which that dialog was shown irrespective of the number of prompts or which is
currently shown on top.
* Add locale to our browser state. Create an action for updating this state.
* Observe changes to locale in the service and dispatch changes in the locale manager
* Separate the building of the notification so it can be reused
* Create a use case for local updates to be used in the locale manager
Add channel id so that the existing notification can be accessed and updated
Send notification id instead of tag
Locale use cases test
Put locale action in sealed action class
Test locale scope
* Add refresh functionality to the service
Add locale actions and reducer for restoring state
Restore state for locale use case. Make getters for ids in notification service
Test locale use case notification in the locale manager
Test covering all locale use cases
* Add locale middleware to handle restore from disk
* Middleware tests for locale
* Locale action tests
* Locale state reducer tests
* Changelog
* Lint and cleanup
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
* Once we link an `EngineSession` to a `Session` we track the time.
* The separate `BrowserAction` allows us to write a Middleware for this event.
* I was unhappy with SystemClock requiring the Android stdlib and therefore making mocking a pain, or
requiring the slow Robolectric test runner. I ended up with this wrapper class, that seems to work
well in Fenix when writing unit tests.
The next step is to write a Middleware in Fenix that looks at those events and records metrics in Glean.
I will open a PR for that soon.
Prior to this when the user selected to share an image from the contextual menu
the apps would only share the URL, not the actual resource.
This patch adds a new `ShareDownloadFeature` that will listen for
`AddShareAction` and download, cache locally and then share the Internet
resource contained in Action's state.
Giving the time needed to actually download these resources this feature is
only used for image sharing, not for other types of potentially bigger
resource types.
This is a breaking change with clients expected to create and register a new
instance of the this new feature otherwise the "Share image" from the
browser contextual menu will do nothing.
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
* For `PurgeHistoryUseCase` I decided to not introduce a "tab ID" parameter and instead have
it purge the history of all tabs. It seems like this is what we need and individual tab
history removal is not needed for now.
* Some tabs may not have an `EngineSession` assigned. Creating one just to call purgeHistory()
seems excessive. Instead I am dropping an attached `EngineSessionState` which will cause
those tabs to just reload the URL with not back/forward history when they get restored.
Again, multiple things in this PR:
* Migrated WebAppIntentProcessor and TrustedWebActivityIntentProcessor to use TabsUseCases instead of
SessionManager directly.
* Migrated one LoadUrlUseCase to take a session ID instead of a `Session` instance as parameter
* Extended TabsUseCases to optionally accept a CustomTabConfig and/or WebAppManifest
I think with that we may even be able to remove WebAppManifest from `Session`. I'll look into this next.
Running ./gradlew ktlint locally reports a lot of stuff like:
/home/emilio/src/moz/android-components/components/support/migration/src/test/java/mozilla/components/support/migration/MigrationIntentProcessorTest.kt:1:1: File must end with a newline (\n)
This fixes it with:
for f in $(cat files | cut -d : -f 1); do echo "" >> $f; done
Making ./gradlew ktlint pass.