Bug 1886792 - Handle install_search_widget deeplink r=android-reviewers,amejiamarmol

Differential Revision: https://phabricator.services.mozilla.com/D205477
fenix/125.0
t-p-white 2 months ago committed by Ryan VanderMeulen
parent a960879c37
commit d2757cf67e

@ -4,6 +4,7 @@
package org.mozilla.fenix.home.intent package org.mozilla.fenix.home.intent
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
@ -20,12 +21,14 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.ext.alreadyOnDestination import org.mozilla.fenix.ext.alreadyOnDestination
import org.mozilla.fenix.ext.openSetDefaultBrowserOption import org.mozilla.fenix.ext.openSetDefaultBrowserOption
import org.mozilla.fenix.utils.showAddSearchWidgetPrompt
/** /**
* Deep links in the form of `fenix://host` open different parts of the app. * Deep links in the form of `fenix://host` open different parts of the app.
*/ */
class HomeDeepLinkIntentProcessor( class HomeDeepLinkIntentProcessor(
private val activity: HomeActivity, private val activity: HomeActivity,
private val showAddSearchWidgetPrompt: (Activity) -> Unit = ::showAddSearchWidgetPrompt,
) : HomeIntentProcessor { ) : HomeIntentProcessor {
private val logger = Logger("DeepLinkIntentProcessor") private val logger = Logger("DeepLinkIntentProcessor")
@ -102,6 +105,10 @@ class HomeDeepLinkIntentProcessor(
val intent = notificationSettings(activity) val intent = notificationSettings(activity)
activity.startActivity(intent) activity.startActivity(intent)
} }
"install_search_widget" -> {
showAddSearchWidgetPrompt(activity)
return
}
} }
} }

@ -5,8 +5,6 @@
package org.mozilla.fenix.onboarding package org.mozilla.fenix.onboarding
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.IntentFilter import android.content.IntentFilter
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
@ -43,7 +41,8 @@ import org.mozilla.fenix.onboarding.view.telemetrySequenceId
import org.mozilla.fenix.onboarding.view.toPageUiData import org.mozilla.fenix.onboarding.view.toPageUiData
import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.theme.FirefoxTheme import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.gecko.search.SearchWidgetProvider import org.mozilla.fenix.utils.canShowAddSearchWidgetPrompt
import org.mozilla.fenix.utils.showAddSearchWidgetPrompt
/** /**
* Fragment displaying the onboarding flow. * Fragment displaying the onboarding flow.
@ -54,7 +53,7 @@ class OnboardingFragment : Fragment() {
pagesToDisplay( pagesToDisplay(
isNotDefaultBrowser(requireContext()), isNotDefaultBrowser(requireContext()),
canShowNotificationPage(requireContext()), canShowNotificationPage(requireContext()),
canShowAddWidgetCard(), canShowAddSearchWidgetPrompt(),
) )
} }
private val telemetryRecorder by lazy { OnboardingTelemetryRecorder() } private val telemetryRecorder by lazy { OnboardingTelemetryRecorder() }
@ -162,7 +161,7 @@ class OnboardingFragment : Fragment() {
pagesToDisplay.telemetrySequenceId(), pagesToDisplay.telemetrySequenceId(),
pagesToDisplay.sequencePosition(OnboardingPageUiData.Type.ADD_SEARCH_WIDGET), pagesToDisplay.sequencePosition(OnboardingPageUiData.Type.ADD_SEARCH_WIDGET),
) )
showAddSearchWidgetDialog() showAddSearchWidgetPrompt(requireActivity())
}, },
onSkipFirefoxWidgetClick = { onSkipFirefoxWidgetClick = {
telemetryRecorder.onSkipAddWidgetClick( telemetryRecorder.onSkipAddWidgetClick(
@ -183,19 +182,6 @@ class OnboardingFragment : Fragment() {
) )
} }
private fun showAddSearchWidgetDialog() {
// Requesting to pin app widget is only available for Android 8.0 and above
if (canShowAddWidgetCard()) {
val appWidgetManager = AppWidgetManager.getInstance(activity)
val searchWidgetProvider =
ComponentName(requireActivity(), SearchWidgetProvider::class.java)
if (appWidgetManager.isRequestPinAppWidgetSupported) {
val successCallback = WidgetPinnedReceiver.getPendingIntent(requireContext())
appWidgetManager.requestPinAppWidget(searchWidgetProvider, null, successCallback)
}
}
}
private fun onFinish(onboardingPageUiData: OnboardingPageUiData?) { private fun onFinish(onboardingPageUiData: OnboardingPageUiData?) {
/* onboarding page UI data can be null if there was no pages to display */ /* onboarding page UI data can be null if there was no pages to display */
if (onboardingPageUiData != null) { if (onboardingPageUiData != null) {
@ -222,8 +208,6 @@ class OnboardingFragment : Fragment() {
!NotificationManagerCompat.from(context.applicationContext) !NotificationManagerCompat.from(context.applicationContext)
.areNotificationsEnabledSafe() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU .areNotificationsEnabledSafe() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
private fun canShowAddWidgetCard() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
private fun isNotATablet() = !resources.getBoolean(R.bool.tablet) private fun isNotATablet() = !resources.getBoolean(R.bool.tablet)
private fun pagesToDisplay( private fun pagesToDisplay(

@ -0,0 +1,35 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.utils
import android.app.Activity
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.os.Build
import org.mozilla.fenix.onboarding.WidgetPinnedReceiver
import org.mozilla.gecko.search.SearchWidgetProvider
/**
* Displays the "add search widget" prompt for capable devices.
*
* @param activity the parent [Activity].
*/
fun showAddSearchWidgetPrompt(activity: Activity) {
// Requesting to pin app widget is only available for Android 8.0 and above
if (canShowAddSearchWidgetPrompt()) {
val appWidgetManager = AppWidgetManager.getInstance(activity)
val searchWidgetProvider =
ComponentName(activity, SearchWidgetProvider::class.java)
if (appWidgetManager.isRequestPinAppWidgetSupported) {
val successCallback = WidgetPinnedReceiver.getPendingIntent(activity)
appWidgetManager.requestPinAppWidget(searchWidgetProvider, null, successCallback)
}
}
}
/**
* Checks whether the device is capable of displaying the "add search widget" prompt.
*/
fun canShowAddSearchWidgetPrompt() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O

@ -4,6 +4,7 @@
package org.mozilla.fenix.home.intent package org.mozilla.fenix.home.intent
import android.app.Activity
import android.content.Intent import android.content.Intent
import android.content.pm.PackageInfo import android.content.pm.PackageInfo
import android.content.pm.PackageManager import android.content.pm.PackageManager
@ -43,7 +44,7 @@ class HomeDeepLinkIntentProcessorTest {
activity = mockk(relaxed = true) activity = mockk(relaxed = true)
navController = mockk(relaxed = true) navController = mockk(relaxed = true)
out = mockk() out = mockk()
processorHome = HomeDeepLinkIntentProcessor(activity) processorHome = HomeDeepLinkIntentProcessor(activity, ::showAddSearchWidgetPrompt)
} }
@Test @Test
@ -257,9 +258,10 @@ class HomeDeepLinkIntentProcessorTest {
assertTrue(processorHome.process(testIntent("make_default_browser"), navController, out)) assertTrue(processorHome.process(testIntent("make_default_browser"), navController, out))
val searchTermOrURL = SupportUtils.getGenericSumoURLForTopic( val searchTermOrURL =
topic = SupportUtils.SumoTopic.SET_AS_DEFAULT_BROWSER, SupportUtils.getGenericSumoURLForTopic(
) topic = SupportUtils.SumoTopic.SET_AS_DEFAULT_BROWSER,
)
verify { verify {
activity.openToBrowserAndLoad( activity.openToBrowserAndLoad(
@ -291,5 +293,18 @@ class HomeDeepLinkIntentProcessorTest {
verify { out wasNot Called } verify { out wasNot Called }
} }
@Test
fun `process install_search_widget deep link`() {
assertTrue(processorHome.process(testIntent("install_search_widget"), navController, out))
verify { showAddSearchWidgetPrompt(activity) }
verify { navController wasNot Called }
verify { out wasNot Called }
}
private fun testIntent(uri: String) = Intent("", "$DEEP_LINK_SCHEME://$uri".toUri()) private fun testIntent(uri: String) = Intent("", "$DEEP_LINK_SCHEME://$uri".toUri())
private fun showAddSearchWidgetPrompt(activity: Activity) {
println("$activity add search widget prompt was shown ")
}
} }

Loading…
Cancel
Save