-
Notifications
You must be signed in to change notification settings - Fork 0
Gate kit initialization behind hasConsent #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -97,6 +97,7 @@ public class KitManagerImpl implements KitManager, AttributionListener, UserAttr | |
|
|
||
| ConcurrentHashMap<Integer, KitIntegration> providers = new ConcurrentHashMap<Integer, KitIntegration>(); | ||
| private final Context mContext; | ||
| private volatile boolean hasConsent = false; | ||
|
|
||
| public KitManagerImpl(Context context, ReportingManager reportingManager, CoreCallbacks coreCallbacks, MParticleOptions options) { | ||
| mContext = context; | ||
|
|
@@ -105,6 +106,7 @@ public KitManagerImpl(Context context, ReportingManager reportingManager, CoreCa | |
| mKitIntegrationFactory = new KitIntegrationFactory(options); | ||
| if (options != null) { | ||
| mRoktOptions = options.getRoktOptions(); | ||
| hasConsent = options.hasConsent(); | ||
| } | ||
| MParticle instance = MParticle.getInstance(); | ||
| if (instance != null) { | ||
|
|
@@ -189,6 +191,25 @@ public void reloadKits() { | |
| configureKits(kitConfigurations); | ||
| } | ||
|
|
||
| @Override | ||
| public void setHasConsent(boolean hasConsent) { | ||
| this.hasConsent = hasConsent; | ||
| runOnMainThread(() -> { | ||
| reloadKits(); | ||
|
Comment on lines
+197
to
+198
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This posts kit reconfiguration to the main thread, so if Useful? React with 👍 / 👎. |
||
| // If consent is granted mid-session, best-effort signal current app state so kits | ||
| // don't have to wait for the next session boundary. | ||
| if (hasConsent && !isBackgrounded()) { | ||
| onApplicationForeground(); | ||
| onSessionStart(); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean hasConsent() { | ||
| return hasConsent; | ||
| } | ||
|
|
||
| @Override | ||
| public void updateDataplan(@Nullable MParticleOptions.DataplanOptions dataplanOptions) { | ||
| if (dataplanOptions != null) { | ||
|
|
@@ -230,6 +251,31 @@ protected synchronized void configureKits(@NonNull List<KitConfiguration> kitCon | |
| HashSet<Integer> activeIds = new HashSet<Integer>(); | ||
| HashMap<Integer, KitIntegration> previousKits = new HashMap<>(providers); | ||
|
|
||
| // Global gate: don't start any kits until the host app grants consent. | ||
| if (!hasConsent) { | ||
| // If any kits are already active, tear them down. | ||
| if (!providers.isEmpty()) { | ||
| for (Map.Entry<Integer, KitIntegration> entry : new HashMap<>(providers).entrySet()) { | ||
| Integer id = entry.getKey(); | ||
| KitIntegration integration = entry.getValue(); | ||
| if (integration != null) { | ||
| try { | ||
| Logger.debug("De-initializing kit (no consent): " + integration.getName()); | ||
| clearIntegrationAttributes(integration); | ||
| integration.onKitDestroy(); | ||
| integration.onKitCleanup(); | ||
| } catch (Exception ignored) { | ||
| } | ||
| } | ||
| providers.remove(id); | ||
| Intent intent = new Intent(MParticle.ServiceProviders.BROADCAST_DISABLED + id); | ||
| getContext().sendBroadcast(intent); | ||
| } | ||
| } | ||
| onKitsLoaded(new HashMap<>(providers), previousKits, new ArrayList<>(kitConfigurations)); | ||
| return; | ||
| } | ||
|
|
||
| if (kitConfigurations != null) { | ||
| for (KitConfiguration configuration : kitConfigurations) { | ||
| try { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When consent flips to true before the first config update, this branch starts a new loader thread while
UploadHandlercan simultaneously callloadKitLibrary()duringUPDATE_CONFIG; becauseloadKitLibrary()still uses an unsynchronizedif (!frameworkLoadAttempted)check, both threads can enter initialization and create/configure kits twice. That can double-initialize third-party SDKs and emit duplicate kit lifecycle side effects in production startup races.Useful? React with 👍 / 👎.