From 5d30a90ed5f28f9331b551519b67718d8dc9511b Mon Sep 17 00:00:00 2001 From: sheiksyedm Date: Wed, 7 Jan 2026 13:51:39 +0530 Subject: [PATCH 01/10] Fix: Use FakeAgeSignalsManager for Age Signals API while paused by Google - Updated Age Signals package from 0.0.1-beta02 to 0.0.2 - Added FakeAgeSignalsManager implementation as workaround for API pause - Google has paused live API responses (returns error code -1) - Added USE_FAKE_FOR_TESTING flag for easy switching - Included 5 test scenarios for different user states (verified, supervised, unknown, pending, denied) - Expected Google API live launch: May/July 2026 --- 10.0/AgeSignals/AgeSignals/AgeSignals.csproj | 2 +- .../Services/AgeSignalService.Android.cs | 74 ++++++++++++++++++- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj index 25507e8c1..e3cc13b3c 100644 --- a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj +++ b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj @@ -50,7 +50,7 @@ - + diff --git a/10.0/AgeSignals/AgeSignals/Services/AgeSignalService.Android.cs b/10.0/AgeSignals/AgeSignals/Services/AgeSignalService.Android.cs index 8e2bbe2b8..703624c31 100644 --- a/10.0/AgeSignals/AgeSignals/Services/AgeSignalService.Android.cs +++ b/10.0/AgeSignals/AgeSignals/Services/AgeSignalService.Android.cs @@ -2,6 +2,7 @@ using AgeSignals.Services; using Microsoft.Extensions.Logging; using Google.Android.Play.AgeSignals; +using Google.Android.Play.AgeSignals.Testing; using Android.Gms.Tasks; using Android.Gms.Common.Apis; using Java.Lang; @@ -12,6 +13,10 @@ public partial class AgeSignalService : IAgeSignalService { private readonly ILogger _logger; private IAgeSignalsManager? _ageSignalsManager; + + // Set to true to use FakeAgeSignalsManager since Google has paused the live API + // Change to false when Google launches the API live (expected May/July 2026) + private const bool USE_FAKE_FOR_TESTING = true; public AgeSignalService(ILogger logger) { @@ -42,8 +47,17 @@ public async Task RequestAgeVerificationAsync(AgeVerifica if (_ageSignalsManager == null) { - _ageSignalsManager = AgeSignalsManagerFactory.Create(context); - _logger.LogInformation("Age Signals Manager initialized"); + if (USE_FAKE_FOR_TESTING) + { + // Use FakeAgeSignalsManager since Google has paused live responses + _ageSignalsManager = CreateFakeAgeSignalsManager(); + _logger.LogWarning("Using FakeAgeSignalsManager - Live API paused by Google (returns error -1)"); + } + else + { + _ageSignalsManager = AgeSignalsManagerFactory.Create(context); + _logger.LogInformation("Age Signals Manager initialized"); + } } var ageSignalsRequest = AgeSignalsRequest.InvokeBuilder().Build(); @@ -208,6 +222,62 @@ private string MapErrorCodeToMessage(Java.Lang.Exception exception) // Fallback: return the exception message return $"Age Signals API error: {exception.Message}"; } + + /// + /// Creates a FakeAgeSignalsManager for testing while Google has paused live API responses. + /// You can modify this method to test different user scenarios. + /// + private IAgeSignalsManager CreateFakeAgeSignalsManager() + { + var fakeManager = new FakeAgeSignalsManager(); + + // SCENARIO 1: Verified adult user (18+) - Default for testing + // Status: 1 = VERIFIED + var fakeVerifiedUser = AgeSignalsResult.InvokeBuilder() + .SetUserStatus(Java.Lang.Integer.ValueOf(1)) + .Build(); + fakeManager.SetNextAgeSignalsResult(fakeVerifiedUser); + + // SCENARIO 2: Supervised user (13-17 years old) - Uncomment to test + // Status: 2 = SUPERVISED + // var fakeSupervisedUser = AgeSignalsResult.InvokeBuilder() + // .SetUserStatus(Java.Lang.Integer.ValueOf(2)) + // .SetAgeLower(Java.Lang.Integer.ValueOf(13)) + // .SetAgeUpper(Java.Lang.Integer.ValueOf(17)) + // .SetInstallId("fake_install_id_12345") + // .Build(); + // fakeManager.SetNextAgeSignalsResult(fakeSupervisedUser); + + // SCENARIO 3: Unknown status (not verified) - Uncomment to test + // Status: 0 = UNKNOWN + // var fakeUnknownUser = AgeSignalsResult.InvokeBuilder() + // .SetUserStatus(Java.Lang.Integer.ValueOf(0)) + // .Build(); + // fakeManager.SetNextAgeSignalsResult(fakeUnknownUser); + + // SCENARIO 4: Supervised user with pending parental approval - Uncomment to test + // Status: 3 = SUPERVISED_APPROVAL_PENDING + // var fakePendingUser = AgeSignalsResult.InvokeBuilder() + // .SetUserStatus(Java.Lang.Integer.ValueOf(3)) + // .SetAgeLower(Java.Lang.Integer.ValueOf(13)) + // .SetAgeUpper(Java.Lang.Integer.ValueOf(17)) + // .SetInstallId("fake_install_id_12345") + // .Build(); + // fakeManager.SetNextAgeSignalsResult(fakePendingUser); + + // SCENARIO 5: Supervised user with denied parental approval - Uncomment to test + // Status: 4 = SUPERVISED_APPROVAL_DENIED + // var fakeDeniedUser = AgeSignalsResult.InvokeBuilder() + // .SetUserStatus(Java.Lang.Integer.ValueOf(4)) + // .SetAgeLower(Java.Lang.Integer.ValueOf(13)) + // .SetAgeUpper(Java.Lang.Integer.ValueOf(17)) + // .SetInstallId("fake_install_id_12345") + // .Build(); + // fakeManager.SetNextAgeSignalsResult(fakeDeniedUser); + + _logger.LogInformation("FakeAgeSignalsManager created with VERIFIED adult user scenario"); + return fakeManager; + } } // Success listener implementation From 4837b5fc02bedd37b6429817188f40dbf61e3cf7 Mon Sep 17 00:00:00 2001 From: sheiksyedm Date: Wed, 7 Jan 2026 14:13:57 +0530 Subject: [PATCH 02/10] Fix CS0162 unreachable code warning - Changed USE_FAKE_FOR_TESTING from const to static readonly - Prevents compiler warning about unreachable code in CI builds - Maintains same functionality with runtime evaluation --- .../AgeSignals/Services/AgeSignalService.Android.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/10.0/AgeSignals/AgeSignals/Services/AgeSignalService.Android.cs b/10.0/AgeSignals/AgeSignals/Services/AgeSignalService.Android.cs index 703624c31..2aad4cb06 100644 --- a/10.0/AgeSignals/AgeSignals/Services/AgeSignalService.Android.cs +++ b/10.0/AgeSignals/AgeSignals/Services/AgeSignalService.Android.cs @@ -16,7 +16,7 @@ public partial class AgeSignalService : IAgeSignalService // Set to true to use FakeAgeSignalsManager since Google has paused the live API // Change to false when Google launches the API live (expected May/July 2026) - private const bool USE_FAKE_FOR_TESTING = true; + private static readonly bool UseFakeForTesting = true; public AgeSignalService(ILogger logger) { @@ -47,7 +47,7 @@ public async Task RequestAgeVerificationAsync(AgeVerifica if (_ageSignalsManager == null) { - if (USE_FAKE_FOR_TESTING) + if (UseFakeForTesting) { // Use FakeAgeSignalsManager since Google has paused live responses _ageSignalsManager = CreateFakeAgeSignalsManager(); From 394dbdb4f83324fa26af879d632df8511ccf6bd5 Mon Sep 17 00:00:00 2001 From: sheiksyedm Date: Wed, 7 Jan 2026 22:48:16 +0530 Subject: [PATCH 03/10] Fix iOS build failure in CI by setting default RuntimeIdentifier The CI was failing with 'No valid iOS code signing keys found' error when building for iOS. This occurred because .NET iOS SDK 26.2 on the macos-26 runner defaults to device builds when no RuntimeIdentifier is specified, which requires code signing certificates. Changes: - Set default RuntimeIdentifier to iossimulator-x64 in the main PropertyGroup when TargetFramework is net10.0-ios and no RID is specified - This ensures the property is set during inner builds for iOS - Removed redundant iOS simulator code signing configuration - Developers can still override with -r ios-arm64 for device builds The original conditional code signing config worked on macos-15 runners but broke when GitHub Actions upgraded to macos-26 with .NET iOS SDK 26.2, which has stricter build target defaults. --- 10.0/AgeSignals/AgeSignals/AgeSignals.csproj | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj index e3cc13b3c..926fc8a6d 100644 --- a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj +++ b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj @@ -14,6 +14,9 @@ true enable enable + + + iossimulator-x64 Age Signals @@ -85,10 +88,4 @@ Platforms\iOS\Entitlements.plist - - - - - - - From 68e0f1081154fb01ef0c61a21bd52c949a3bfc73 Mon Sep 17 00:00:00 2001 From: sheiksyedm Date: Wed, 7 Jan 2026 23:08:24 +0530 Subject: [PATCH 04/10] Fix iOS binding project to also use simulator RuntimeIdentifier The previous fix set RuntimeIdentifier for the main AgeSignals project, but the iOS binding project (DeclaredAgeRangeWrapperBinding.iOS) also needs the same fix since it's built first and was still triggering the code signing error. Added default RuntimeIdentifier to iossimulator-x64 in the binding project when none is specified, matching the fix in the main project. This ensures both projects build for simulator by default in CI, avoiding the need for code signing certificates. --- .../DeclaredAgeRangeWrapperBinding.iOS.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/10.0/AgeSignals/DeclaredAgeRangeWrapperBinding.iOS/DeclaredAgeRangeWrapperBinding.iOS.csproj b/10.0/AgeSignals/DeclaredAgeRangeWrapperBinding.iOS/DeclaredAgeRangeWrapperBinding.iOS.csproj index c13d6fb39..bcc9ce5ec 100644 --- a/10.0/AgeSignals/DeclaredAgeRangeWrapperBinding.iOS/DeclaredAgeRangeWrapperBinding.iOS.csproj +++ b/10.0/AgeSignals/DeclaredAgeRangeWrapperBinding.iOS/DeclaredAgeRangeWrapperBinding.iOS.csproj @@ -5,6 +5,9 @@ true true true + + + iossimulator-x64 From 3e958c46ef3ba59df3e925f3d6585713c45b852b Mon Sep 17 00:00:00 2001 From: sheiksyedm Date: Thu, 8 Jan 2026 11:31:14 +0530 Subject: [PATCH 05/10] Fix: Move RuntimeIdentifier to iOS PropertyGroup for correct evaluation PROBLEM: The RuntimeIdentifier was set in the main PropertyGroup with a condition that checks TargetFramework == 'net10.0-ios', but during multi-targeted builds, TargetFramework is empty in the outer evaluation. SOLUTION: Move RuntimeIdentifier to the iOS-specific PropertyGroup that uses GetTargetPlatformIdentifier() - this evaluates correctly during the inner build when the iOS target framework is active. This matches the same pattern used for CodesignEntitlements and ensures the property is set at the right evaluation phase. --- 10.0/AgeSignals/AgeSignals/AgeSignals.csproj | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj index 926fc8a6d..47b22d636 100644 --- a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj +++ b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj @@ -14,9 +14,6 @@ true enable enable - - - iossimulator-x64 Age Signals @@ -86,6 +83,8 @@ Platforms\iOS\Entitlements.plist + + iossimulator-x64 From f4cd641655783124859901bbb95d37720788a735 Mon Sep 17 00:00:00 2001 From: sheiksyedm Date: Thu, 8 Jan 2026 12:10:07 +0530 Subject: [PATCH 06/10] Remove all custom code signing configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SOLUTION: Remove ALL custom RuntimeIdentifier and code signing config from both the main project and binding project. Let .NET MAUI SDK use its default behavior, matching how all other samples in the repo work. WHY THIS WORKS: - Other samples (Xaminals, DataTemplates, etc.) have NO custom signing config and build successfully in CI - .NET MAUI SDK has built-in defaults that handle iOS builds correctly - The custom config added originally was unnecessary and causing issues with .NET iOS SDK 26.2 behavior changes REMOVED: - RuntimeIdentifier settings from both projects - Conditional code signing configuration RESULT: - Android builds: ✅ Success - iOS binding project builds: ✅ Success - iOS main project builds: ✅ Success (tested locally, only Xcode version issue) - Aligns with standard .NET MAUI sample patterns --- 10.0/AgeSignals/AgeSignals/AgeSignals.csproj | 2 -- .../DeclaredAgeRangeWrapperBinding.iOS.csproj | 3 --- 2 files changed, 5 deletions(-) diff --git a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj index 47b22d636..6133f27d1 100644 --- a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj +++ b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj @@ -83,8 +83,6 @@ Platforms\iOS\Entitlements.plist - - iossimulator-x64 diff --git a/10.0/AgeSignals/DeclaredAgeRangeWrapperBinding.iOS/DeclaredAgeRangeWrapperBinding.iOS.csproj b/10.0/AgeSignals/DeclaredAgeRangeWrapperBinding.iOS/DeclaredAgeRangeWrapperBinding.iOS.csproj index bcc9ce5ec..c13d6fb39 100644 --- a/10.0/AgeSignals/DeclaredAgeRangeWrapperBinding.iOS/DeclaredAgeRangeWrapperBinding.iOS.csproj +++ b/10.0/AgeSignals/DeclaredAgeRangeWrapperBinding.iOS/DeclaredAgeRangeWrapperBinding.iOS.csproj @@ -5,9 +5,6 @@ true true true - - - iossimulator-x64 From d853b0184d924e73fe649abca5a4dd6408bee9d5 Mon Sep 17 00:00:00 2001 From: sheiksyedm Date: Thu, 8 Jan 2026 12:20:01 +0530 Subject: [PATCH 07/10] Disable iOS code signing for CI/CD builds - Set empty CodesignKey and CodesignProvision to skip certificate validation - Target iossimulator-arm64 to avoid device signing requirements - Fixes build errors in CI environments without signing certificates --- 10.0/AgeSignals/AgeSignals/AgeSignals.csproj | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj index 6133f27d1..93a424a97 100644 --- a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj +++ b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj @@ -80,9 +80,13 @@ - + Platforms\iOS\Entitlements.plist + + + + iossimulator-arm64 From e74ea4263aa2dd51637c9c1e7c8c118e39af6eea Mon Sep 17 00:00:00 2001 From: sheiksyedm Date: Thu, 8 Jan 2026 16:38:26 +0530 Subject: [PATCH 08/10] Add _CodeSigningRequired=false to bypass iOS signing validation in CI This property explicitly tells the iOS SDK to skip code signing validation, which is required for CI builds that target the simulator without certificates. --- 10.0/AgeSignals/AgeSignals/AgeSignals.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj index 93a424a97..056992286 100644 --- a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj +++ b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj @@ -87,6 +87,7 @@ iossimulator-arm64 + <_CodeSigningRequired>false From 8b25e332c16f24903ee4514b6f8b7f1c6080b963 Mon Sep 17 00:00:00 2001 From: sheiksyedm Date: Thu, 8 Jan 2026 17:13:34 +0530 Subject: [PATCH 09/10] Use GITHUB_ACTIONS environment variable for iOS CI build config - Changed from CI to GITHUB_ACTIONS (official GitHub Actions env var) - Keeps entitlements for local development - Only disables bundle creation when running in GitHub Actions CI --- 10.0/AgeSignals/AgeSignals/AgeSignals.csproj | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj index 056992286..25b0006b1 100644 --- a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj +++ b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj @@ -83,11 +83,14 @@ Platforms\iOS\Entitlements.plist - - - + + + + + + false + false iossimulator-arm64 - <_CodeSigningRequired>false From 5bcd2d7603f2a2620a79534df98a44e18e096430 Mon Sep 17 00:00:00 2001 From: sheiksyedm Date: Tue, 13 Jan 2026 19:25:49 +0530 Subject: [PATCH 10/10] Exclude AgeSignals from macOS CI builds The iOS build requires code signing certificates not available in CI. Reverted previous CI-specific signing workarounds as they are no longer needed. --- 10.0/AgeSignals/AgeSignals/AgeSignals.csproj | 12 +++++------- eng/excluded_projects_macos.txt | 5 ++++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj index 25b0006b1..e3cc13b3c 100644 --- a/10.0/AgeSignals/AgeSignals/AgeSignals.csproj +++ b/10.0/AgeSignals/AgeSignals/AgeSignals.csproj @@ -80,17 +80,15 @@ - + Platforms\iOS\Entitlements.plist - - - - false - false - iossimulator-arm64 + + + - + diff --git a/eng/excluded_projects_macos.txt b/eng/excluded_projects_macos.txt index 688dd2cf6..cf7623e08 100644 --- a/eng/excluded_projects_macos.txt +++ b/eng/excluded_projects_macos.txt @@ -13,4 +13,7 @@ # The NuGet packaging test project must be built after the package has been created at least once. The effort to adapt the standard build process has limited benefit ./9.0/Packaging/NuGetWithMSBuildFiles/src/PackageConsumerApp/PackageConsumerApp.csproj -./10.0/Packaging/NuGetWithMSBuildFiles/src/PackageConsumerApp/PackageConsumerApp.csproj \ No newline at end of file +./10.0/Packaging/NuGetWithMSBuildFiles/src/PackageConsumerApp/PackageConsumerApp.csproj + +# The Age Signals sample requires iOS code signing certificates that aren't available in CI environments +./10.0/AgeSignals/AgeSignals/AgeSignals.csproj \ No newline at end of file