Skip to content

Commit

Permalink
Add FXIOS-10299 [Universal Links]Add AppLinks configuration for blog.…
Browse files Browse the repository at this point in the history
…mozilla.com and handle ULs (#23867)

* Add AppLinks configuration for blog.mozilla.com and handle ULs

* Add feature flagging for universal links

* update ff off logic to allow any activity type

* move isBrowsing activity to a function instead of an inline variable
  • Loading branch information
Cramsden authored Dec 19, 2024
1 parent 2a3b303 commit 15d1f4f
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 3 deletions.
4 changes: 4 additions & 0 deletions firefox-ios/Client.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,7 @@
61A164492CE7BE84001D6058 /* WallpaperStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A164452CE7BE1A001D6058 /* WallpaperStateTests.swift */; };
61A1644A2CE7BE8A001D6058 /* WallpaperMiddlewareTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A164472CE7BE3D001D6058 /* WallpaperMiddlewareTests.swift */; };
61E637852D03615D00E95B63 /* LabelButtonHeaderViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E637842D03615D00E95B63 /* LabelButtonHeaderViewTests.swift */; };
61F7A4332D136C3A00F7317B /* RouteBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F7A4322D136C3A00F7317B /* RouteBuilderTests.swift */; };
630FE1352C7FB42500D9D6B2 /* NativeErrorPageViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 630FE1322C7FB42500D9D6B2 /* NativeErrorPageViewControllerTests.swift */; };
631A369F2CC0A4FE0044DFEB /* NativeErrorPageMiddleware.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631A369E2CC0A4FE0044DFEB /* NativeErrorPageMiddleware.swift */; };
631A36A32CC0B2470044DFEB /* NativeErrorPageHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631A36A22CC0B2470044DFEB /* NativeErrorPageHelper.swift */; };
Expand Down Expand Up @@ -6936,6 +6937,7 @@
61B340508D4D86B6519A165C /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = "id.lproj/Default Browser.strings"; sourceTree = "<group>"; };
61DA4B5AB7DA505B9C992F95 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/ClearPrivateDataConfirm.strings; sourceTree = "<group>"; };
61E637842D03615D00E95B63 /* LabelButtonHeaderViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelButtonHeaderViewTests.swift; sourceTree = "<group>"; };
61F7A4322D136C3A00F7317B /* RouteBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouteBuilderTests.swift; sourceTree = "<group>"; };
623648C2A7D09ECA31155208 /* ka */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ka; path = ka.lproj/ErrorPages.strings; sourceTree = "<group>"; };
625D4575B4794C49451D6990 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/HistoryPanel.strings; sourceTree = "<group>"; };
627F483FB45E5DA53E1D5363 /* kab */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = kab; path = kab.lproj/ClearPrivateData.strings; sourceTree = "<group>"; };
Expand Down Expand Up @@ -11682,6 +11684,7 @@
21FA8FAC2AE8561C0013B815 /* TabTray */,
C8E531C929E5F7D300E03FEF /* URLScannerTests.swift */,
C81C66C329F00D1000F6422F /* UserActivityRouteTests.swift */,
61F7A4322D136C3A00F7317B /* RouteBuilderTests.swift */,
);
path = Coordinators;
sourceTree = "<group>";
Expand Down Expand Up @@ -17270,6 +17273,7 @@
C23889E32A50319A00429673 /* ShareSheetCoordinatorTests.swift in Sources */,
E1312FD129D237EE008DDA85 /* NotificationSurfaceManagerTests.swift in Sources */,
21371FA228A6C4A200BC3F37 /* OnboardingTelemetryUtilityTests.swift in Sources */,
61F7A4332D136C3A00F7317B /* RouteBuilderTests.swift in Sources */,
814B71FF2CBEDC3B001B134A /* MainMenuDetailsStateTests.swift in Sources */,
5AE371842A4DD6F50092A760 /* PasswordManagerListViewControllerSpy.swift in Sources */,
8A2825352760399B00395E66 /* KeyboardPressesHandlerTests.swift in Sources */,
Expand Down
14 changes: 12 additions & 2 deletions firefox-ios/Client/Coordinators/Router/RouteBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Foundation
import CoreSpotlight
import Shared

final class RouteBuilder {
final class RouteBuilder: FeatureFlaggable {
private var isPrivate = false
private var prefs: Prefs?

Expand Down Expand Up @@ -158,7 +158,8 @@ final class RouteBuilder {

// If the user activity has a webpageURL, it's a deep link or an old history item.
// Use the URL to create a new search tab.
if let url = userActivity.webpageURL {
if let url = userActivity.webpageURL,
isBrowsingActivity(userActivity) {
return .search(url: url, isPrivate: false)
}

Expand Down Expand Up @@ -206,6 +207,15 @@ final class RouteBuilder {
}
}

private func isBrowsingActivity(_ userActivity: NSUserActivity) -> Bool {
if featureFlags.isFeatureEnabled(.universalLinks, checking: .buildOnly) {
return userActivity.activityType == NSUserActivityTypeBrowsingWeb ||
userActivity.activityType == browsingActivityType
} else {
return true
}
}

// MARK: - Telemetry

private func recordTelemetry(input: DeeplinkInput.Host, isPrivate: Bool) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
<array>
<string>Default</string>
</array>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:blog.mozilla.org</string>
</array>
<key>com.apple.developer.authentication-services.autofill-credential-provider</key>
<true/>
<key>com.apple.developer.networking.multipath</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
<dict>
<key>aps-environment</key>
<string>production</string>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:blog.mozilla.org</string>
</array>
<key>com.apple.developer.authentication-services.autofill-credential-provider</key>
<true/>
<key>com.apple.developer.networking.multipath</key>
Expand Down
2 changes: 2 additions & 0 deletions firefox-ios/Client/FeatureFlags/NimbusFlaggableFeature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ enum NimbusFeatureFlagID: String, CaseIterable {
case splashScreen
case unifiedAds
case unifiedSearch
case universalLinks
case toolbarRefactor
case toolbarOneTapNewTab
case toolbarNavigationHint
Expand Down Expand Up @@ -133,6 +134,7 @@ struct NimbusFlaggableFeature: HasNimbusSearchBar {
.splashScreen,
.unifiedAds,
.unifiedSearch,
.universalLinks,
.toolbarRefactor,
.toolbarOneTapNewTab,
.toolbarNavigationHint,
Expand Down
2 changes: 1 addition & 1 deletion firefox-ios/Client/Helpers/UserActivityHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import WebKit
import SiteImageView
import Common

private let browsingActivityType: String = "org.mozilla.ios.firefox.browsing"
let browsingActivityType: String = "org.mozilla.ios.firefox.browsing"

private let searchableIndex = CSSearchableIndex.default()

Expand Down
8 changes: 8 additions & 0 deletions firefox-ios/Client/Nimbus/NimbusFeatureFlagLayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ final class NimbusFeatureFlagLayer {
case .unifiedSearch:
return checkUnifiedSearchFeature(from: nimbus)

case .universalLinks:
return checkUniversalLinkFeature(from: nimbus)

case .toolbarOneTapNewTab:
return checkToolbarOneTapNewTabFeature(from: nimbus)

Expand Down Expand Up @@ -225,6 +228,11 @@ final class NimbusFeatureFlagLayer {
return config.unifiedSearch
}

private func checkUniversalLinkFeature(from nimbus: FxNimbus) -> Bool {
let config = nimbus.features.universalLinks.value()
return config.enabled
}

private func checkToolbarOneTapNewTabFeature(from nimbus: FxNimbus) -> Bool {
let config = nimbus.features.toolbarRefactorFeature.value()
return config.oneTapNewTab
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// 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/

import XCTest
@testable import Client

class RouteBuilderTests: XCTestCase {
let testURL = URL(string: "https://example.com")
let handoffUserActivity = NSUserActivity(activityType: browsingActivityType)
let universalLinkUserActivity = NSUserActivity(activityType: NSUserActivityTypeBrowsingWeb)
let randomActivity = NSUserActivity(activityType: "random")

override func setUp() {
super.setUp()
LegacyFeatureFlagsManager.shared.initializeDeveloperFeatures(with: MockProfile())
handoffUserActivity.webpageURL = testURL
universalLinkUserActivity.webpageURL = testURL
randomActivity.webpageURL = testURL
}
func test_makeRoute_whenUniversalLinkIsDisabled_HandlesAnyACtivityType() {
setupNimbusUniversalLinksTesting(isEnabled: false)
let routeBuilder = createSubject()

let route = routeBuilder.makeRoute(
userActivity: handoffUserActivity
)

let universalLinkRoute = routeBuilder.makeRoute(
userActivity: universalLinkUserActivity
)

let randomRoute = routeBuilder.makeRoute(
userActivity: randomActivity
)

XCTAssertEqual(route, .search(url: testURL, isPrivate: false))
XCTAssertEqual(universalLinkRoute, .search(url: testURL, isPrivate: false))
XCTAssertEqual(randomRoute, .search(url: testURL, isPrivate: false))
}

func test_makeRoute_whenUniversalLinkIsEnabled_handlesWebpageURLForActivityTypeBrowsingActivityAndBrowsingWeb() {
setupNimbusUniversalLinksTesting(isEnabled: true)
let routeBuilder = createSubject()

let route = routeBuilder.makeRoute(
userActivity: handoffUserActivity
)

let universalLinkRoute = routeBuilder.makeRoute(
userActivity: universalLinkUserActivity
)

let randomRoute = routeBuilder.makeRoute(
userActivity: randomActivity
)

XCTAssertEqual(route, .search(url: testURL, isPrivate: false))
XCTAssertEqual(universalLinkRoute, .search(url: testURL, isPrivate: false))
XCTAssertNil(randomRoute)
}

private func createSubject() -> RouteBuilder {
let subject = RouteBuilder()
trackForMemoryLeaks(subject)
return subject
}

private func setupNimbusUniversalLinksTesting(isEnabled: Bool) {
FxNimbus.shared.features.universalLinks.with { _, _ in
return UniversalLinks(
enabled: isEnabled
)
}
}
}
18 changes: 18 additions & 0 deletions firefox-ios/nimbus-features/universalLinks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# The configuration for the universalLinks feature
features:
universal-links:
description: >
This feature is for managing the roll out of universal link support in the iOS App
variables:
enabled:
description: >
If true, enables the feature
type: Boolean
default: false
defaults:
- channel: beta
value:
enabled: false
- channel: developer
value:
enabled: true
1 change: 1 addition & 0 deletions firefox-ios/nimbus.fml.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ include:
- nimbus-features/tosFeature.yaml
- nimbus-features/trackingProtectionRefactor.yaml
- nimbus-features/unifiedAds.yaml
- nimbus-features/universalLinks.yaml
- nimbus-features/zoomFeature.yaml

0 comments on commit 15d1f4f

Please sign in to comment.