Commit 2ed8028a authored by Tiger Oakes's avatar Tiger Oakes
Browse files

Add externalAppType field

parent cd5c0ce3
......@@ -27,6 +27,7 @@ import java.util.UUID
* @property navigationBarColor Background color for the navigation bar.
* @property titleVisible Whether the title should be shown in the custom tab.
* @property sessionToken The token associated with the custom tab.
* @property externalAppType How this custom tab is being displayed.
*/
data class CustomTabConfig(
val id: String = UUID.randomUUID().toString(),
......@@ -40,7 +41,8 @@ data class CustomTabConfig(
val exitAnimations: Bundle? = null,
@ColorInt val navigationBarColor: Int? = null,
val titleVisible: Boolean = false,
val sessionToken: CustomTabsSessionToken? = null
val sessionToken: CustomTabsSessionToken? = null,
val externalAppType: ExternalAppType = ExternalAppType.CUSTOM_TAB
) {
companion object {
......@@ -49,6 +51,24 @@ data class CustomTabConfig(
}
}
/**
* Represents different contexts that a custom tab session can be displayed in.
*/
enum class ExternalAppType {
/**
* Custom tab is displayed as a normal custom tab with toolbar.
*/
CUSTOM_TAB,
/**
* Custom tab toolbar is hidden inside a Progressive Web App created by the browser.
*/
PROGRESSIVE_WEB_APP,
/**
* Custom tab is displayed fullscreen inside a Trusted Web Activity from an external app.
*/
TRUSTED_WEB_ACTIVITY
}
data class CustomTabActionButtonConfig(
val description: String,
val icon: Bitmap,
......
......@@ -35,6 +35,7 @@ import mozilla.components.browser.state.state.CustomTabActionButtonConfig
import mozilla.components.browser.state.state.CustomTabConfig
import mozilla.components.browser.state.state.CustomTabConfig.Companion.EXTRA_NAVIGATION_BAR_COLOR
import mozilla.components.browser.state.state.CustomTabMenuItem
import mozilla.components.browser.state.state.ExternalAppType
import mozilla.components.support.utils.SafeIntent
import mozilla.components.support.utils.toSafeBundle
import mozilla.components.support.utils.toSafeIntent
......@@ -101,7 +102,8 @@ fun createCustomTabConfigFromIntent(
CustomTabsSessionToken.getSessionTokenFromIntent(intent)
} else {
null
}
},
externalAppType = ExternalAppType.CUSTOM_TAB
)
}
......
......@@ -12,6 +12,7 @@ import android.os.Build
import android.os.Build.VERSION.SDK_INT
import androidx.core.net.toUri
import mozilla.components.browser.state.state.CustomTabConfig
import mozilla.components.browser.state.state.ExternalAppType
import mozilla.components.concept.engine.manifest.WebAppManifest
import mozilla.components.support.utils.ColorUtils.isDark
......@@ -42,7 +43,8 @@ fun WebAppManifest.toCustomTabConfig(): CustomTabConfig {
actionButtonConfig = null,
showCloseButton = false,
showShareMenuItem = true,
menuItems = emptyList()
menuItems = emptyList(),
externalAppType = ExternalAppType.PROGRESSIVE_WEB_APP
)
}
......
......@@ -18,6 +18,7 @@ import kotlinx.coroutines.launch
import mozilla.components.browser.session.Session
import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.state.state.CustomTabConfig.Companion.EXTRA_ADDITIONAL_TRUSTED_ORIGINS
import mozilla.components.browser.state.state.ExternalAppType
import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.fetch.Client
import mozilla.components.feature.customtabs.createCustomTabConfigFromIntent
......@@ -58,7 +59,7 @@ class TrustedWebActivityIntentProcessor(
return if (!url.isNullOrEmpty() && matches(intent)) {
val session = Session(url, private = false, source = Session.Source.HOME_SCREEN)
val customTabConfig = createCustomTabConfigFromIntent(intent, null)
session.customTabConfig = customTabConfig
session.customTabConfig = customTabConfig.copy(externalAppType = ExternalAppType.TRUSTED_WEB_ACTIVITY)
sessionManager.add(session)
loadUrlUseCase(url, session, EngineSession.LoadUrlFlags.external())
......
......@@ -13,6 +13,9 @@ import androidx.core.net.toUri
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest
import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.state.state.ExternalAppType
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.EngineSession
import mozilla.components.feature.customtabs.store.CustomTabsServiceStore
import mozilla.components.feature.pwa.intent.WebAppIntentProcessor.Companion.ACTION_VIEW_PWA
......@@ -20,12 +23,14 @@ import mozilla.components.feature.session.SessionUseCases
import mozilla.components.support.test.any
import mozilla.components.support.test.eq
import mozilla.components.support.test.mock
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
@RunWith(AndroidJUnit4::class)
......@@ -33,6 +38,14 @@ import org.mockito.Mockito.verify
class TrustedWebActivityIntentProcessorTest {
private val apiKey = "XXXXXXXXX"
private lateinit var store: BrowserStore
private lateinit var sessionManager: SessionManager
@Before
fun setup() {
store = BrowserStore()
sessionManager = SessionManager(mock(), store)
}
@Test
fun `matches checks if intent is a trusted web activity intent`() {
......@@ -94,13 +107,16 @@ class TrustedWebActivityIntentProcessorTest {
}
val loadUrlUseCase: SessionUseCases.DefaultLoadUrlUseCase = mock()
val store: CustomTabsServiceStore = mock()
val customTabsStore: CustomTabsServiceStore = mock()
val processor = spy(TrustedWebActivityIntentProcessor(mock(), loadUrlUseCase, mock(), mock(), apiKey, store))
val processor = TrustedWebActivityIntentProcessor(sessionManager, loadUrlUseCase, mock(), mock(), apiKey, customTabsStore)
assertTrue(processor.process(intent))
val sessionState = store.state.customTabs.first()
assertNotNull(sessionState.config)
assertEquals(ExternalAppType.TRUSTED_WEB_ACTIVITY, sessionState.config.externalAppType)
verify(loadUrlUseCase).invoke(eq("https://example.com"), any(), eq(EngineSession.LoadUrlFlags.external()))
verify(store, never()).state
verify(customTabsStore, never()).state
}
}
......@@ -10,6 +10,9 @@ import androidx.core.net.toUri
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest
import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.state.state.ExternalAppType
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.manifest.WebAppManifest
import mozilla.components.feature.intent.ext.getSessionId
import mozilla.components.feature.pwa.ManifestStorage
......@@ -71,4 +74,26 @@ class WebAppIntentProcessorTest {
assertNotNull(intent.getSessionId())
assertEquals(manifest, intent.getWebAppManifest())
}
@Test
fun `process adds custom tab config`() = runBlockingTest {
val intent = Intent(ACTION_VIEW_PWA, "https://mozilla.com".toUri())
val storage: ManifestStorage = mock()
val store = BrowserStore()
val sessionManager = SessionManager(mock(), store)
val manifest = WebAppManifest(
name = "Test Manifest",
startUrl = "https://mozilla.com"
)
`when`(storage.loadManifest("https://mozilla.com")).thenReturn(manifest)
val processor = WebAppIntentProcessor(sessionManager, mock(), storage)
assertTrue(processor.process(intent))
val sessionState = store.state.customTabs.first()
assertNotNull(sessionState.config)
assertEquals(ExternalAppType.PROGRESSIVE_WEB_APP, sessionState.config.externalAppType)
}
}
......@@ -15,6 +15,9 @@ permalink: /changelog/
* **browser-toolbar**
* ⚠️ **This is a breaking change**: Refactored the internals to use `ConstraintLayout`. As part of this change the public API was simplified and unused methods/properties have been removed.
* **browser-state**
* Added `externalAppType` to `CustomTabConfig` to indicate how the session is being used.
# 18.0.0
* [Commits](https://github.com/mozilla-mobile/android-components/compare/v17.0.0...v18.0.0)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment