costom tabs setting
This commit is contained in:
+28
-15
@@ -153,12 +153,14 @@ class IntentReceiverActivity : Activity() {
|
||||
// Flutter-side to handle (search, PDF display, etc.).
|
||||
if (intent.action == Intent.ACTION_SEND) {
|
||||
val shareUrl = extractShareUrl(intent)
|
||||
if (shareUrl != null) {
|
||||
if (shareUrl != null &&
|
||||
IntentGatekeeperPreferences.isCustomTabsEnabled(applicationContext)
|
||||
) {
|
||||
Log.d(TAG, "SHARE intent with URL, routing to custom tab: $shareUrl")
|
||||
handleShareUrlAsCustomTab(intent, shareUrl, privateBrowsingMode)
|
||||
return
|
||||
}
|
||||
Log.d(TAG, "SHARE intent without URL, routing to MainActivity")
|
||||
Log.d(TAG, "SHARE intent without URL (or custom tabs disabled), routing to MainActivity")
|
||||
handleRegularIntent(intent)
|
||||
return
|
||||
}
|
||||
@@ -193,19 +195,30 @@ class IntentReceiverActivity : Activity() {
|
||||
return
|
||||
}
|
||||
|
||||
val processors = listOf(
|
||||
"CustomTab" to CustomTabIntentProcessor(
|
||||
components.useCases.customTabsUseCases.add,
|
||||
resources,
|
||||
isPrivate = privateBrowsingMode,
|
||||
),
|
||||
"PWA" to WebAppIntentProcessor(
|
||||
components.core.store,
|
||||
components.useCases.customTabsUseCases.addWebApp,
|
||||
components.useCases.sessionUseCases.loadUrl,
|
||||
components.core.webAppManifestStorage,
|
||||
),
|
||||
)
|
||||
// When the user disables the Custom Tabs feature, external Custom Tab
|
||||
// intents are not handled here; they fall through to the main browser
|
||||
// via handleRegularIntent(). PWA processing is unaffected.
|
||||
val customTabsEnabled = IntentGatekeeperPreferences.isCustomTabsEnabled(applicationContext)
|
||||
|
||||
val processors = buildList {
|
||||
if (customTabsEnabled) {
|
||||
add(
|
||||
"CustomTab" to CustomTabIntentProcessor(
|
||||
components.useCases.customTabsUseCases.add,
|
||||
resources,
|
||||
isPrivate = privateBrowsingMode,
|
||||
),
|
||||
)
|
||||
}
|
||||
add(
|
||||
"PWA" to WebAppIntentProcessor(
|
||||
components.core.store,
|
||||
components.useCases.customTabsUseCases.addWebApp,
|
||||
components.useCases.sessionUseCases.loadUrl,
|
||||
components.core.webAppManifestStorage,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
for ((name, processor) in processors) {
|
||||
Log.d(TAG, "Trying $name processor...")
|
||||
|
||||
+10
@@ -21,6 +21,7 @@ import java.util.UUID
|
||||
object IntentGatekeeperPreferences {
|
||||
const val PREFS_NAME = "weblibre_intent_gatekeeper"
|
||||
const val KEY_ENABLED = "enabled"
|
||||
const val KEY_CUSTOM_TABS_ENABLED = "custom_tabs_enabled"
|
||||
const val KEY_BLOCKED_PACKAGES = "blocked_packages"
|
||||
const val KEY_PENDING_ALWAYS_ALLOW = "pending_always_allow"
|
||||
private const val KEY_NOTIFICATION_APPROVAL_TOKENS = "notification_approval_tokens"
|
||||
@@ -32,6 +33,15 @@ object IntentGatekeeperPreferences {
|
||||
fun isEnabled(context: Context): Boolean =
|
||||
get(context).getBoolean(KEY_ENABLED, false)
|
||||
|
||||
/**
|
||||
* Whether external Custom Tab (and share-with-URL) intents should be
|
||||
* handled as lightweight custom-tab activities. When false,
|
||||
* [IntentReceiverActivity] routes them to the main browser instead.
|
||||
* Defaults to true so the feature is active until the user opts out.
|
||||
*/
|
||||
fun isCustomTabsEnabled(context: Context): Boolean =
|
||||
get(context).getBoolean(KEY_CUSTOM_TABS_ENABLED, true)
|
||||
|
||||
fun isBlocked(context: Context, packageName: String): Boolean {
|
||||
val prefs = get(context)
|
||||
if (!prefs.getBoolean(KEY_ENABLED, false)) return false
|
||||
|
||||
+8
@@ -23,6 +23,7 @@ class IntentGatekeeperHostApiImpl(private val context: Context) : IntentGatekeep
|
||||
companion object {
|
||||
private const val PREFS_NAME = "weblibre_intent_gatekeeper"
|
||||
private const val KEY_ENABLED = "enabled"
|
||||
private const val KEY_CUSTOM_TABS_ENABLED = "custom_tabs_enabled"
|
||||
private const val KEY_BLOCKED_PACKAGES = "blocked_packages"
|
||||
private const val KEY_PENDING_ALWAYS_ALLOW = "pending_always_allow"
|
||||
}
|
||||
@@ -35,6 +36,13 @@ class IntentGatekeeperHostApiImpl(private val context: Context) : IntentGatekeep
|
||||
.apply()
|
||||
}
|
||||
|
||||
override fun setCustomTabsEnabled(enabled: Boolean) {
|
||||
val prefs = context.applicationContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
||||
prefs.edit()
|
||||
.putBoolean(KEY_CUSTOM_TABS_ENABLED, enabled)
|
||||
.apply()
|
||||
}
|
||||
|
||||
override fun resolvePackageLabel(packageName: String): String? {
|
||||
return try {
|
||||
val pm = context.applicationContext.packageManager
|
||||
|
||||
+25
@@ -340,6 +340,13 @@ interface IntentGatekeeperHostApi {
|
||||
* [IntentReceiverActivity] can reject intents without launching Flutter.
|
||||
*/
|
||||
fun setConfig(enabled: Boolean, blockedPackages: List<String>)
|
||||
/**
|
||||
* Replicates whether the Custom Tabs feature is enabled to the native side.
|
||||
* When disabled, [IntentReceiverActivity] routes external Custom Tab and
|
||||
* share-with-URL intents to the main browser instead of launching the
|
||||
* stripped-down custom-tab activity. Defaults to enabled on the native side.
|
||||
*/
|
||||
fun setCustomTabsEnabled(enabled: Boolean)
|
||||
/**
|
||||
* Resolves a package name to its user-visible application label via
|
||||
* [PackageManager]. Returns `null` if the package is not installed or the
|
||||
@@ -388,6 +395,24 @@ interface IntentGatekeeperHostApi {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.simple_intent_receiver.IntentGatekeeperHostApi.setCustomTabsEnabled$separatedMessageChannelSuffix", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val enabledArg = args[0] as Boolean
|
||||
val wrapped: List<Any?> = try {
|
||||
api.setCustomTabsEnabled(enabledArg)
|
||||
listOf(null)
|
||||
} catch (exception: Throwable) {
|
||||
IntentPigeonUtils.wrapError(exception)
|
||||
}
|
||||
reply.reply(wrapped)
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.simple_intent_receiver.IntentGatekeeperHostApi.resolvePackageLabel$separatedMessageChannelSuffix", codec)
|
||||
if (api != null) {
|
||||
|
||||
@@ -301,6 +301,28 @@ class IntentGatekeeperHostApi {
|
||||
;
|
||||
}
|
||||
|
||||
/// Replicates whether the Custom Tabs feature is enabled to the native side.
|
||||
/// When disabled, [IntentReceiverActivity] routes external Custom Tab and
|
||||
/// share-with-URL intents to the main browser instead of launching the
|
||||
/// stripped-down custom-tab activity. Defaults to enabled on the native side.
|
||||
Future<void> setCustomTabsEnabled(bool enabled) async {
|
||||
final pigeonVar_channelName = 'dev.flutter.pigeon.simple_intent_receiver.IntentGatekeeperHostApi.setCustomTabsEnabled$pigeonVar_messageChannelSuffix';
|
||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
pigeonVar_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: pigeonVar_binaryMessenger,
|
||||
);
|
||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[enabled]);
|
||||
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||
|
||||
_extractReplyValueOrThrow(
|
||||
pigeonVar_replyList,
|
||||
pigeonVar_channelName,
|
||||
isNullValid: true,
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
/// Resolves a package name to its user-visible application label via
|
||||
/// [PackageManager]. Returns `null` if the package is not installed or the
|
||||
/// label cannot be resolved.
|
||||
|
||||
@@ -69,6 +69,12 @@ abstract class IntentGatekeeperHostApi {
|
||||
/// [IntentReceiverActivity] can reject intents without launching Flutter.
|
||||
void setConfig(bool enabled, List<String> blockedPackages);
|
||||
|
||||
/// Replicates whether the Custom Tabs feature is enabled to the native side.
|
||||
/// When disabled, [IntentReceiverActivity] routes external Custom Tab and
|
||||
/// share-with-URL intents to the main browser instead of launching the
|
||||
/// stripped-down custom-tab activity. Defaults to enabled on the native side.
|
||||
void setCustomTabsEnabled(bool enabled);
|
||||
|
||||
/// Resolves a package name to its user-visible application label via
|
||||
/// [PackageManager]. Returns `null` if the package is not installed or the
|
||||
/// label cannot be resolved.
|
||||
|
||||
Reference in New Issue
Block a user