Analytics extends AirshipComponent { @NonNull public AssociatedIdentifiers.Editor editAssociatedIdentifiers() { return new AssociatedIdentifiers.Editor() { @Override void onApply(boolean clear, @NonNull Map<String, String> idsToAdd, @NonNull List<String> idsToRemove) { synchronized (associatedIdentifiersLock) { if (!isDataCollectionEnabled()) { Logger.warn("Analytics - Unable to track associated identifiers when data collection is disabled."); return; } Map<String, String> ids = new HashMap<>(); AssociatedIdentifiers associatedIdentifiers = getAssociatedIdentifiers(); if (!clear) { Map<String, String> currentIds = associatedIdentifiers.getIds(); ids.putAll(currentIds); } ids.putAll(idsToAdd); for (String key : idsToRemove) { ids.remove(key); } AssociatedIdentifiers identifiers = new AssociatedIdentifiers(ids); AssociatedIdentifiers prev = associatedIdentifiers; if (prev.getIds().equals(identifiers.getIds())) { Logger.info("Skipping analytics event addition for duplicate associated identifiers."); return; } getDataStore().put(ASSOCIATED_IDENTIFIERS_KEY, identifiers); addEvent(new AssociateIdentifiersEvent(identifiers)); } } }; } Analytics(@NonNull Context context,
                     @NonNull PreferenceDataStore dataStore,
                     @NonNull AirshipRuntimeConfig runtimeConfig,
                     @NonNull AirshipChannel channel,
                     @NonNull LocaleManager localeManager); @VisibleForTesting  Analytics(@NonNull Context context,
              @NonNull PreferenceDataStore dataStore,
              @NonNull AirshipRuntimeConfig runtimeConfig,
              @NonNull AirshipChannel airshipChannel,
              @NonNull ActivityMonitor activityMonitor,
              @NonNull LocaleManager localeManager,
              @NonNull Executor executor,
              @NonNull EventManager eventManager); @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) void addHeaderDelegate(@NonNull AnalyticsHeaderDelegate headerDelegate); @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) void addEventListener(@NonNull EventListener eventListener); @Override @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) @AirshipComponentGroups.Group int getComponentGroup(); @Override @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) @JobInfo.JobResult int onPerformJob(@NonNull UAirship airship, @NonNull JobInfo jobInfo); boolean isAppInForeground(); void addEvent(@NonNull final Event event); @Nullable String getConversionSendId(); @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) void setConversionSendId(@Nullable String sendId); @Nullable @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) String getConversionMetadata(); void setConversionMetadata(@Nullable String metadata); @NonNull String getSessionId(); void setEnabled(boolean enabled); boolean isEnabled(); @NonNull AssociatedIdentifiers.Editor editAssociatedIdentifiers(); @NonNull AssociatedIdentifiers getAssociatedIdentifiers(); void trackScreen(@Nullable String screen); void uploadEvents(); void addAnalyticsListener(@NonNull AnalyticsListener analyticsListener); void removeAnalyticsListener(@NonNull AnalyticsListener analyticsListener); void registerSDKExtension(@ExtensionName @NonNull String extension, @NonNull String version); @NonNull
    static final String EXTENSION_CORDOVA; @NonNull
    static final String EXTENSION_FLUTTER; @NonNull
    static final String EXTENSION_REACT_NATIVE; @NonNull
    static final String EXTENSION_UNITY; @NonNull
    static final String EXTENSION_XAMARIN; @NonNull
    static final String EXTENSION_TITANIUM; }
@Test public void testEditAssociatedIdentifiers() { analytics.editAssociatedIdentifiers() .addIdentifier("customKey", "customValue") .apply(); verify(mockEventManager).addEvent(Mockito.any(AssociateIdentifiersEvent.class), Mockito.anyString()); AssociatedIdentifiers storedIds = analytics.getAssociatedIdentifiers(); assertEquals(storedIds.getIds().get("customKey"), "customValue"); assertEquals(storedIds.getIds().size(), 1); }