[BUG] [MicroG] DynamiteContextFactory bug breaks paid/verified app license checks
- /e/OS version(s):
3.4-a15-20260114569178-official-FP6
3.5-a15-20260211580868-official-FP6
- Device model(s): Fairphone 6
- Impacted Application:
- MicroG
- (example app, BusinessCalendar2)
- Affected application/URL:
- https://github.com/microg/GmsCore
- https://www.appgenix-software.com/
- microG: 0.3.11.250932-15
**Summary:**
Apps fail to verify Play Store licenses due to MicroG's incomplete emulation of `DynamiteContextFactory` API. E.g., Business Calendar 2 ("BC2" ; `com.appgenix.bizcal`) fails to see its valid license -- verified and purchased on the same Google account -- and incorrectly shows it's "pay to go pro" upgrade screen.
**Expected:**
Apps using the Play Billing Library should find existing purchases & unlock their pro features.
**Observed:**
BC2 launches & shows its `GoProActivity` screen, asking for a new purchase even though one's already been made.
**Analysis:**
Logcat shows the clear sequence pointing to an incompatibility with MicroG.
1. **OK Initial Billing comm:**
BC2 successfully connects to MicroG's billing service & confirms support for in-app purchases + subscriptions.
```
02-13 11:18:13.355 D Billing : isBillingSupported(...type=subs)=Bundle[{...RESPONSE_CODE=0}]
02-13 11:18:13.362 D Billing : isBillingSupported(...type=inapp)=Bundle[{...RESPONSE_CODE=0}]
```
2. **License Query init:**
App correctly queries for existing purchases for license verification
```
02-13 11:18:13.379 D Billing : getPurchasesExtraParams(...type=inapp,...)
02-13 11:18:13.392 D Billing : getPurchasesExtraParams(...type=subs,...)
```
3. **DynamiteContextFactory Emulation FAIL:**
The problem's here.
BC2 attempts to use `DynamiteContextFactory`, but fails with "Unsupported class loader" warnings.
This appears to be the core incompatibility in MicroG's GMS emulation.
```
02-13 11:18:13.124 D DynamiteContextFactory: Created and cached a new DynamiteContext for cacheKey: com.google.android.gms.measurement.dynamite-com.appgenix.bizcal
02-13 11:18:13.125 W appgenix.bizcal: Unsupported class loader
02-13 11:18:13.191 D DynamiteContextFactory: Created and cached a new DynamiteContext for cacheKey: com.google.android.gms.maps_dynamite-com.appgenix.bizcal
02-13 11:18:13.191 W appgenix.bizcal: Unsupported class loader
02-13 11:18:13.307 W appgenix.bizcal: Unsupported class loader
02-13 11:18:13.307 D DynamiteContextFactory: Created and cached a new ClassLoader for cacheKey: com.google.android.gms.measurement.dynamite-com.appgenix.bizcal ClassLoader: 70308833
02-13 11:18:13.377 W appgenix.bizcal: Unsupported class loader
02-13 11:18:13.377 D DynamiteContextFactory: Created and cached a new ClassLoader for cacheKey: com.google.android.gms.maps_dynamite-com.appgenix.bizcal ClassLoader: 207065700
```
4. **Logic continues with bad Data:**
Because the `DynamiteContextFactory` call FAILs, `getPurchasesExtraParams` call returns an empty list.
Looks like BC2's logic sees this empty list & determines -- correctly in this case -- there's no license.
5. **Incorrect App Behavior Triggered:**
BC2 then launches its `GoProActivity` licensing screen -- and there's the problem.
This isn't an app bug; it's just the correct response to the bad data it received from MicroG.
```
02-13 11:18:17.392 I ActivityTaskManager: START u0 {cmp=com.appgenix.bizcal/.ui.GoProActivity} ...
```
**Root Cause:**
The `DynamiteContextFactory` implementation in MicroG fails to provide a compatible `ClassLoader` for dynamically loaded GMS modules (e.g., `com.google.android.gms.measurement.dynamite`). When the Google Play Billing library (or one/more of its deps?) attempts to use this `ClassLoader`, it fails, logged as an "Unsupported class loader" warning. The silent fail prevents a `getPurchasesExtraParams` call from correctly querying Google's servers & parsing the response.
This results in an empty purchase list being returned to the application.
**Conclusion:**
This is a specific implementation defect in MicroG's `DynamiteContextFactory`.
A likely fix requires modifying it to return a `ClassLoader` that's' fully compatible with the GMS client libraries. The new `ClassLoader` should correctly resolve and load resources and classes from both the dynamically loaded module's APK and the host app's context. Once the "Unsupported class loader" failure is remedied, it should allow the license verification process to complete successfully.
issue