Create sub packages.

This commit is contained in:
Benoit Marty
2023-04-24 14:49:15 +02:00
committed by Benoit Marty
parent 4c9bed9d8a
commit d33fbaf89f
15 changed files with 58 additions and 32 deletions

View File

@@ -29,8 +29,9 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.login.impl.changeserver.ChangeServerNode
import io.element.android.features.login.impl.oidc.CustomTabHandler
import io.element.android.features.login.impl.oidc.OidcNode
import io.element.android.features.login.impl.oidc.CustomTabAvailabilityChecker
import io.element.android.features.login.impl.oidc.customtab.CustomTabHandler
import io.element.android.features.login.impl.oidc.webview.OidcNode
import io.element.android.features.login.impl.root.LoginRootNode
import io.element.android.libraries.architecture.BackstackNode
import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler
@@ -43,6 +44,7 @@ import kotlinx.parcelize.Parcelize
class LoginFlowNode @AssistedInject constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val customTabAvailabilityChecker: CustomTabAvailabilityChecker,
private val customTabHandler: CustomTabHandler,
) : BackstackNode<LoginFlowNode.NavTarget>(
backstack = BackStack(
@@ -72,7 +74,8 @@ class LoginFlowNode @AssistedInject constructor(
}
override fun onOidcDetails(oidcDetails: OidcDetails) {
if (customTabHandler.supportCustomTab()) {
if (customTabAvailabilityChecker.supportCustomTab()) {
// In this case open a Chrome Custom tab
customTabHandler.open(oidcDetails.url)
} else {
// Fallback to WebView mode

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.features.login.impl.oidc
import android.content.Context
import androidx.browser.customtabs.CustomTabsClient
import io.element.android.libraries.di.ApplicationContext
import javax.inject.Inject
class CustomTabAvailabilityChecker @Inject constructor(
@ApplicationContext private val context: Context,
) {
/**
* Return true if the device supports Custom tab, i.e. there is an third party app with
* CustomTab support (ex: Chrome, Firefox, etc.).
*/
fun supportCustomTab(): Boolean {
val packageName = CustomTabsClient.getPackageName(context, null)
return packageName != null
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.impl.oidc
package io.element.android.features.login.impl.oidc.customtab
import android.content.ComponentName
import android.content.Context
@@ -22,7 +22,6 @@ import android.net.Uri
import androidx.browser.customtabs.CustomTabsClient
import androidx.browser.customtabs.CustomTabsServiceConnection
import androidx.browser.customtabs.CustomTabsSession
import io.element.android.features.login.impl.oidc.web.openUrlInChromeCustomTab
import io.element.android.libraries.di.ApplicationContext
import javax.inject.Inject
@@ -33,15 +32,6 @@ class CustomTabHandler @Inject constructor(
private var customTabsClient: CustomTabsClient? = null
private var customTabsServiceConnection: CustomTabsServiceConnection? = null
/**
* Return true if the device supports Custom tab, i.e. there is an third party app with
* CustomTab support (ex: Chrome, Firefox, etc.).
*/
fun supportCustomTab(): Boolean {
val packageName = CustomTabsClient.getPackageName(context, null)
return packageName != null
}
fun prepareCustomTab(url: String) {
val packageName = CustomTabsClient.getPackageName(context, null)
@@ -82,6 +72,6 @@ class CustomTabHandler @Inject constructor(
}
fun open(url: String) {
openUrlInChromeCustomTab(context, customTabsSession, false, url)
context.openUrlInChromeCustomTab(customTabsSession, false, url)
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.impl.oidc.web
package io.element.android.features.login.impl.oidc.customtab
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.features.login.api.oidc.OidcAction

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.impl.oidc.web
package io.element.android.features.login.impl.oidc.customtab
import android.content.ActivityNotFoundException
import android.content.Context
@@ -29,8 +29,7 @@ import androidx.browser.customtabs.CustomTabsSession
* If several compatible browsers are installed, the user will be proposed to choose one.
* Ref: https://developer.chrome.com/multidevice/android/customtabs.
*/
fun openUrlInChromeCustomTab(
context: Context,
fun Context.openUrlInChromeCustomTab(
session: CustomTabsSession?,
darkTheme: Boolean,
url: String
@@ -58,7 +57,7 @@ fun openUrlInChromeCustomTab(
.apply {
intent.flags += Intent.FLAG_ACTIVITY_NEW_TASK
}
.launchUrl(context, Uri.parse(url))
.launchUrl(this, Uri.parse(url))
} catch (activityNotFoundException: ActivityNotFoundException) {
// TODO context.toast(R.string.error_no_external_application_found)
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.impl.oidc
package io.element.android.features.login.impl.oidc.webview
import io.element.android.features.login.api.oidc.OidcAction

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.impl.oidc
package io.element.android.features.login.impl.oidc.webview
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.impl.oidc
package io.element.android.features.login.impl.oidc.webview
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.impl.oidc
package io.element.android.features.login.impl.oidc.webview
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.matrix.api.auth.OidcDetails

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.impl.oidc
package io.element.android.features.login.impl.oidc.webview
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.architecture.Async

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.impl.oidc
package io.element.android.features.login.impl.oidc.webview
import android.webkit.WebView
import androidx.activity.compose.BackHandler
@@ -27,9 +27,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.viewinterop.AndroidView
import io.element.android.features.login.impl.oidc.OidcUrlParser
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.core.bool.orFalse
import io.element.android.libraries.core.bool.orTrue
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.impl.oidc
package io.element.android.features.login.impl.oidc.webview
import android.annotation.TargetApi
import android.os.Build
@@ -23,7 +23,6 @@ import android.webkit.WebView
import android.webkit.WebViewClient
import timber.log.Timber
// TODO Move to a dedicated module
class OidcWebViewClient(private val eventListener: WebViewEventListener) : WebViewClient() {
@TargetApi(Build.VERSION_CODES.N)
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.features.login.impl.oidc
package io.element.android.features.login.impl.oidc.webview
interface WebViewEventListener {
/**

View File

@@ -25,7 +25,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import io.element.android.features.login.api.oidc.OidcAction
import io.element.android.features.login.impl.oidc.web.DefaultOidcActionFlow
import io.element.android.features.login.impl.oidc.customtab.DefaultOidcActionFlow
import io.element.android.features.login.impl.util.LoginConstants
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.Presenter

View File

@@ -16,7 +16,7 @@
@file:OptIn(ExperimentalCoroutinesApi::class)
package io.element.android.features.login.impl.oidc
package io.element.android.features.login.impl.oidc.webview
import app.cash.molecule.RecompositionClock
import app.cash.molecule.moleculeFlow