v26.16.1.178666 #7
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
open-grind/grindr.rs#7
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
New third-party fingerprinting SDK: SafetyKit
com.safetykit.androidpackage (absent in 26.15.1), plus an obfuscateda/package holding a "FingerprintFramework".POST https://ingest.sk-diagnostics.com/v1/mobile-events(errors →/v1/mobile-events/errors)Authorization: Bearer <hardcoded API key>,Content-Type: application/json; charset=utf-8{ uuid, data: {<device fingerprint>}, event_name, params: { user_id } }uuid= random UUID persisted in SharedPreferencescom.safetykit, keyuuidevent_name="login"or"user_registration";user_id= Grindr profile idSafetyKit.recordLoginEvent()/recordUserRegistrationEvent();SafetyKit.initialize()at startup. All three gated by flagsafety_kit_sdk_integration.qemu.*,ro.bootloader,init.svc.qemud,adb_enabled,development_settings_enabled,mock_location), sensors, cameras, requested permissions + app signatures, wifi/network/routes, battery, locale, fonts,android_id,boot_count,proc_meminfo,proc_version, ~150 Settings.* keys.safetykit_init_failure { reason }.New endpoints
POSTv1/popup-logicPOSTv1/popup-logic/ackGETv5/push-settingspush_settings_v5_migrationPUTv5/push-settingsDELETEv3/push-tokens/{token}requireRealDeviceInfo: true, no body, fired on sign-outChanged endpoint
POST web/v3/consent/grindr/get→POST web/v3/consent/grindr/get?includePurposeInfo=truePopup-logic orchestration (new package, NOT wired up)
Server-driven, session-scoped modal sequencing with per-step acks.
StepType=Mandatory | Optional(no wireName mapping present in the APK).PlanSource=Server | Default(client-only).Nothing calls
ModalPlanService— zero references outside its own file, and no DI module provides it. (Control: the 3 other new services each have 2 external refs.) Don't implement yet; expect it to go live in a later release. The existingpopup/data/datasource/api/service/PopupModalServicegate is untouched.New / changed JSON fields
POST web/v3/consent/grindr/getgainspurposeInfo, a required non-nullMap<string, { allowed: string, allowsOptOut: bool, isRecorded: bool, requiresOptIn: bool, legalBasis: string, source: string, collectedAt: int64, issuedAt: int64 }>. A missingpurposeInfothrowsJsonDataException.requiresOptInnow decides whether the Ketch consent WebView is loaded at all (with flagketch-webview-on-demand). Six previously-discarded top-level fields now reach the domain model (jurisdictionCode,hasUnrecordedOptInConsent,setConsentRequired,interactive,collectedAt,vendorConsents) — onlyjurisdictionCodeandpurposeInfohave readers.POST v2/age-verification/verifyresponse gainsfailureReason: string.BannedTermsResponse(profile text moderation) gainscode: int?.GET /v1/store-and-profile→upgrade_cardgainsctaTextTrial,ctaTextTrialId,ctaPriceRoles: string[],productType.GET v3/legal-agreementserror body is now parsed:{ code: int?, message: string? }(onlycodeis consumed) →LegalAgreementFetchFailure(httpStatus, serverErrorCode, cause).GET/PUT v5/push-settings:{ tapPushNotification: bool|null, favoritePushNotification: bool|null }. The client only ever writesfavoritePushNotificationand reads only that back; the tap value is parsed and discarded. Failed GET leaves the previous state (no blanking).New enum values
banSubReason(412 ban responses): +DRUG_SEEKING,DRUG_FACILITATION,NON_CONSENSUAL_INTIMATE_IMAGERY,SEXTORTION(29 → 33). None removed.GET v2/warningswarning type: +DRUG_SEEKING,DRUG_FACILITATION,NON_CONSENSUAL_INTIMATE_IMAGERY(9 → 12). NoSEXTORTIONhere.AgeVerificationFailureReason:LIVENESS_CHECK_FAILED,DOCUMENT_EXPIRED,DOCUMENT_VERIFICATION_FAILED,AGE_NOT_DETECTED,UNDERAGE_DETECTED.ReferrerType+favorite_online_notification(24 → 25).source(POST /v1/store/attribution/tokens): +profile_tab-edge|xtra|unlimited|my_subscription|current_sku, −intro_offer_account_creation.New cascade item type
Server-driven config
Added (17) —
atc-fullscreen-ad-gate,atc-fullscreen-iam-gate,push_settings_v5_migration,safety_kit_sdk_integration,edge-paywall-embedded-in-store,premium-tier-price-test-sep26,half-sheet-upsell-v2,health-center-woodwork-perk-at-subscription-purchase,rewarded-ads-free-session-v3,rewarded-ads-viewed-me-v3,right-now-text-status-enabled,ketch-webview-on-demand,boost-somewhere-else-v3,ads-disable-front-fill,braze-ad-clicked-analytics,disable-async-webview-startup,disable-maps-gl-warmupRemoved (5) —
ad-backfill,ads-ketch-consent-api-enabled,ads-new-applovin-privacy-flags-enabled,community_events,disable-defer-maps-warmupNew experiment payload (
GET /v3/assignment):health-center-woodwork-perk-at-subscription-purchase→payload: { payload: { introSheetPostPurchase: string?, woodWorkTreatment: string? } }Other changes
PushNotificationActionTypeare unchanged (package move only).POST v3/gcm-push-tokensmovedLoginRestService→PushTokenRestService; body{ vendorProvidedIdentifier, token }andrequireRealDeviceInfo: trueunchanged. It now also fires on FCM token rotation and on successful session refresh.v5/push-settings.favoritePushNotification; push opensgrindr://favorite-profile.grindr://favorite-profile?profileID=<id>(also accepts?profileId=) — the only deeplink host added. Server sends it in the "favorite came online" push."No Ads for %1$d min", "Watch a quick video and be done").atc_block_reaped,atc_block_released,atc_ad_suppressed); enforcement gated byatc-fullscreen-ad-gate/atc-fullscreen-iam-gate.edge-paywall-embedded-in-storeANDpremium-tier-price-test-sep26AND the pre-existingedge-paywall-v2.DRUG_PROMOTIONre-tiered from warning to temporary suspensionGenerated by Claude Opus 5 on September 11, 2026.