001package com.intentsoftware.addapptr;
002
003import android.app.Activity;
004import android.app.Application;
005import android.content.Context;
006import android.content.pm.PackageManager;
007import android.graphics.Bitmap;
008import android.util.Log;
009import android.util.Pair;
010import android.view.Gravity;
011import android.view.View;
012import android.view.ViewGroup;
013
014import com.intentsoftware.addapptr.ad.NativeAd;
015import com.intentsoftware.addapptr.ad.NativeAdData;
016import com.intentsoftware.addapptr.ad.VASTAdData;
017import com.intentsoftware.addapptr.module.Logger;
018import com.intentsoftware.addapptr.module.ServerLogger;
019import com.intentsoftware.addapptr.module.Utils;
020
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024
025import androidx.annotation.Nullable;
026
027@SuppressWarnings({"unused", "WeakerAccess"})
028public class AATKit {
029
030    // Used only in Javadoc.
031    public static final int BANNER_DEFAULT_RELOAD_INTERVAL_IN_SECONDS = (int) (BannerReloader.AUTORELOAD_INTERVAL_DEFAULT / 1000);
032    public static final int BANNER_MIN_RELOAD_INTERVAL_IN_SECONDS = (int) (BannerReloader.AUTORELOAD_INTERVAL_MIN / 1000);
033    public static final int BANNER_MAX_RELOAD_INTERVAL_IN_SECONDS = (int) (BannerReloader.AUTORELOAD_INTERVAL_MAX / 1000);
034
035    /**
036     * Used for passing of detailed GDPR consent. Possible implementations: {@link ManagedConsent}, {@link SimpleConsent}, {@link VendorConsent}.
037     */
038    public interface Consent {
039        /**
040         * Sets to set the networks that will not be requested if they do not have the TCF2 consent. Only works if TCF2 compliant CMP is used.
041         *
042         * @param stopSet Set of networks not to be requested without TCF2 consent.
043         */
044        void setNoConsentNetworkStopSet(Set<AdNetwork> stopSet);
045    }
046
047    /**
048     * Notifies about AATKit events.
049     */
050    public interface Delegate {
051        /**
052         * Notifies that placement has finished loading an ad successfully.
053         *
054         * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
055         */
056        void aatkitHaveAd(int placementId);
057
058        /**
059         * Notifies that placement has failed to load an ad.
060         *
061         * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
062         */
063        void aatkitNoAd(int placementId);
064
065        /**
066         * Notifies that ad went fullscreen and that application should pause.
067         *
068         * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
069         */
070        void aatkitPauseForAd(int placementId);
071
072        /**
073         * Notifies that ad came back from fullscreen and that application should resume.
074         *
075         * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
076         */
077        void aatkitResumeAfterAd(int placementId);
078
079        /**
080         * Notifies that placement has loaded an Empty ad.
081         *
082         * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
083         */
084        void aatkitShowingEmpty(int placementId);
085
086        /**
087         * Notifies that placement has earned incentive (by rewarded ads).
088         * <p>
089         * Note: This callback might also be invoked for regular fullscreen
090         * placements, not just the ones configured for rewarded videos. Please
091         * make sure placementId is your rewarded video placement before rewarding
092         * the user.
093         *
094         * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
095         * @param aatKitReward Incentive object. Can be null for networks not supporting reward information.
096         */
097        void aatkitUserEarnedIncentive(int placementId, @Nullable AATKitReward aatKitReward);
098
099        /**
100         * Notifies that the AATKit has obtained ad rules.
101         *
102         * @param fromTheServer Indicates if the rules came from the server. It will return false if the currently used rules come from the {@link #setInitialRules(String)} method or the cached rules are used.
103         */
104        void aatkitObtainedAdRules(boolean fromTheServer);
105
106        /**
107         * Notifies that application's bundle ID was not recognized by the AddApptr server.
108         */
109        void aatkitUnknownBundleId();
110
111        /**
112         * Notifies that AATKit has new banner view ready for placement. Used only for MultiSizeBanner.
113         *
114         * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
115         * @param bannerView  Loaded banner view
116         */
117        void aatkitHaveAdForPlacementWithBannerView(int placementId, BannerPlacementLayout bannerView);
118
119        /**
120         * Notifies that placement has finished loading an VAST ad successfully. Used only for VAST.
121         *
122         * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
123         * @param data        Loaded VAST ad data.
124         */
125        void aatkitHaveVASTAd(int placementId, VASTAdData data);
126    }
127
128    private static AdController adController;
129
130    /**
131     * @return AATKit version.
132     */
133    public static String getVersion() {
134        logAATKitCall("CMD: getVersion()");
135        return Version.NAME;
136    }
137
138    /**
139     * @return AATKit detailed build version.
140     */
141    public static String getFullVersion() {
142        logAATKitCall("CMD: getFullVersion()");
143        return Version.FULL_NAME;
144    }
145
146    /**
147     * Initializes the AATKit library. Should be called once during application initialization before any other calls to AATKit.
148     *
149     * @param configuration Configuration for AATKit.
150     * @see AATKitConfiguration
151     */
152    public static void init(AATKitConfiguration configuration) {
153        logAATKitCall("CMD: init(" + configuration + ")");
154
155        if (configuration == null) {
156            if (Logger.isLoggable(Log.ERROR)) {
157                Logger.e(AATKit.class, "Configuration cannot be null");
158            }
159            return;
160        }
161        if (adController != null) {
162            if (Logger.isLoggable(Log.ERROR)) {
163                Logger.e(AATKit.class, "AdController is already initialized");
164            }
165            return;
166        }
167
168        String version = "?";
169        String packageName = configuration.getApplication().getApplicationContext().getPackageName();
170        try {
171            version = configuration.getApplication().getPackageManager().getPackageInfo(packageName, 0).versionName;
172        } catch (PackageManager.NameNotFoundException e) {
173            if (Logger.isLoggable(Log.WARN)) {
174                Logger.w(AATKit.class, "Failed to check version of application", e);
175            }
176        }
177
178        Logger.d("Init", Version.FULL_NAME
179                + ", application: " + packageName
180                + " (version: " + version + ")"
181                + ", configuration: " + configuration);
182        adController = new AdController(configuration);
183    }
184
185    /**
186     * Initializes the AATKit library. Should be called once during application initialization before any other calls to AATKit.
187     *
188     * @param application Reference to {@link Application}.
189     * @param delegate    Optional delegate allowing to listen for AATKit events.
190     * @see AATKit.Delegate
191     * @deprecated use {@link #init(AATKitConfiguration)} instead.
192     */
193    @Deprecated
194    public static void init(Application application, Delegate delegate) {
195        logAATKitCall("CMD: init(" + application + "," + delegate + ")");
196        if (adController != null) {
197            if (Logger.isLoggable(Log.ERROR)) {
198                Logger.e(AATKit.class, "AdController is already initialized");
199            }
200            return;
201        }
202        Logger.d("Init", Version.FULL_NAME + ", live mode, shake debug on, rule caching on");
203        AATKitConfiguration config = new AATKitConfiguration(application);
204        config.setDelegate(delegate);
205        adController = new AdController(config);
206
207    }
208
209    /**
210     * Initializes the AATKit library. Should be called once during application initialization before any other calls to AATKit.
211     *
212     * @param application       Reference to {@link Application}.
213     * @param delegate          Optional delegate allowing to listen for AATKit events.
214     * @param enableRuleCaching Sets if AATKit should preserve last downloaded ad rules when the application is closed.
215     * @param initialRules      Optional parameter (can be null). Allows to set initial rules that will be used before real config is downloaded from the server.
216     * @see AATKit.Delegate
217     * @deprecated use {@link #init(AATKitConfiguration)} instead.
218     */
219    @Deprecated
220    public static void init(Application application, Delegate delegate, boolean enableRuleCaching, String initialRules) {
221        logAATKitCall("CMD: init(" + application + "," + delegate + "," + enableRuleCaching + "," + initialRules + ")");
222        if (adController != null) {
223            if (Logger.isLoggable(Log.ERROR)) {
224                Logger.e(AATKit.class, "AdController is already initialized");
225            }
226            return;
227        }
228        Logger.d("Init", Version.FULL_NAME + ", live mode, shake debug on, rule caching: " + enableRuleCaching + ", initial rules: " + initialRules);
229
230        AATKitConfiguration config = new AATKitConfiguration(application);
231        config.setDelegate(delegate);
232        config.setShouldCacheRules(enableRuleCaching);
233        config.setInitialRules(initialRules);
234
235        adController = new AdController(config);
236    }
237
238
239    /**
240     * Initializes the AATKit library. Should be called once during application initialization before any other calls to AATKit.
241     * It also enables the test ads, and should only be used during development.
242     *
243     * @param application Reference to {@link Application}.
244     * @param delegate    Optional delegate allowing to listen for AATKit events.
245     * @param testId      Test application id obtained from addapptr.com account.
246     * @deprecated use {@link #init(AATKitConfiguration)} instead.
247     */
248    @Deprecated
249    public static void init(Application application, Delegate delegate, int testId) {
250        logAATKitCall("CMD: init(" + application + "," + delegate + "," + testId + ")");
251        if (adController != null) {
252            if (Logger.isLoggable(Log.ERROR)) {
253                Logger.e(AATKit.class, "AdController is already initialized");
254            }
255            return;
256        }
257        Logger.d("Init", Version.FULL_NAME + ", test mode with ID: " + testId + ", shake debug on, rule caching on");
258
259        AATKitConfiguration config = new AATKitConfiguration(application);
260        config.setDelegate(delegate);
261        config.setTestModeAccountId(testId);
262
263        adController = new AdController(config);
264    }
265
266
267    /**
268     * Initializes the AATKit library without debug screen appearing after shaking the device (it is enabled by default). It is advised to use the {@link #init(Application, Delegate)} method instead. Should be called once during application initialization before any other calls
269     * to AATKit.
270     *
271     * @param application Reference to {@link Application}.
272     * @param delegate    Optional delegate allowing to listen for AATKit events.
273     * @see AATKit.Delegate
274     * @deprecated use {@link #init(AATKitConfiguration)} instead.
275     */
276    @Deprecated
277    public static void initWithoutDebugScreen(Application application, Delegate delegate) {
278        logAATKitCall("CMD: initWithoutDebugScreen(" + application + "," + delegate + ")");
279        if (adController != null) {
280            if (Logger.isLoggable(Log.ERROR)) {
281                Logger.e(AATKit.class, "AdController is already initialized");
282            }
283            return;
284        }
285        Logger.d("Init", Version.FULL_NAME + ", live mode, shake debug off, rule caching on");
286        AATKitConfiguration config = new AATKitConfiguration(application);
287        config.setDelegate(delegate);
288        config.setUseDebugShake(false);
289
290        adController = new AdController(config);
291    }
292
293    /**
294     * Enables AATKit test ads that should be for testing only during development.
295     *
296     * @param testAppId Test application id obtained from addapptr.com account.
297     * @deprecated use {@link #init(AATKitConfiguration)} with setting the test mode in configuration object instead.
298     */
299    @Deprecated
300    public static void enableTestMode(int testAppId) {
301        logAATKitCall("CMD: enableTestMode(" + testAppId + ")");
302        adController.setTestAppId(testAppId);
303    }
304
305    /**
306     * Enables debug screen that will show after shaking the device. It is already enabled by default.
307     */
308    public static void enableDebugScreen() {
309        logAATKitCall("CMD: enableDebugScreen()");
310        adController.enableDebugScreen();
311    }
312
313    /**
314     * Disables the debug screen appearing after shaking the device. It is enabled by default.
315     */
316    public static void disableDebugScreen() {
317        logAATKitCall("CMD: disableDebugScreen()");
318        adController.disableDebugScreen();
319    }
320
321    /**
322     * Used for obtaining debug information (the same that would be presented in dialog after shaking the device if debug screen is enabled)
323     *
324     * @return String with debug information
325     */
326    public static String getDebugInfo() {
327        logAATKitCall("CMD: getDebugInfo()");
328        return adController.getDebugInfo();
329    }
330
331    /**
332     * Allows to reconfigure the options for GDPR consent.
333     *
334     * @param configuration New configuration.
335     */
336    public static void reconfigure(AATKitRuntimeConfiguration configuration) {
337        logAATKitCall("CMD: reconfigure(" + configuration + ")");
338        adController.reconfigure(configuration);
339    }
340
341    /**
342     * Checks if AATKit recognizes given device as tablet.
343     *
344     * @param context The {@link Context} of your application.
345     * @return True if device is recognized as tablet, false otherwise.
346     */
347    public static boolean isTablet(Context context) {
348        logAATKitCall("CMD: isTablet(" + context + ")");
349        return Utils.isTablet(context);
350    }
351
352    /**
353     * Returns the {@link PlacementSize} with maximum width that will fit on a given device in portrait screen orientation.
354     *
355     * @param context The {@link Context} of your application.
356     * @return {@link PlacementSize} best fitting current device
357     */
358    public static PlacementSize maximumBannerSizePortrait(Context context) {
359        logAATKitCall("CMD: maximumBannerSizePortrait(" + context + ")");
360        return Utils.maxPlacementSize(Utils.screenWidthPortrait(context));
361    }
362
363    /**
364     * Returns the {@link PlacementSize} with maximum width that will fit on a given device in landscape screen orientation.
365     *
366     * @param context The {@link Context} of your application.
367     * @return {@link PlacementSize} best fitting current device
368     */
369    public static PlacementSize maximumBannerSizeLandscape(Context context) {
370        logAATKitCall("CMD: maximumBannerSizeLandscape(" + context + ")");
371        return Utils.maxPlacementSize(Utils.screenWidthLandscape(context));
372    }
373
374    /**
375     * Returns the set of {@link BannerSize} that will fit on a given device in portrait screen orientation.
376     *
377     * @param context The {@link Context} of your application.
378     * @return Set of {@link BannerSize} fitting current device
379     */
380    public static Set<BannerSize> fittingBannerSizesPortrait(Context context) {
381        logAATKitCall("CMD: fittingBannerSizesPortrait(" + context + ")");
382        return Utils.fittingBannerSizes(Utils.screenWidthPortrait(context));
383    }
384
385    /**
386     * Returns the set of {@link BannerSize} that will fit on a given device in landscape screen orientation.
387     *
388     * @param context The {@link Context} of your application.
389     * @return Set of {@link BannerSize} fitting current device
390     */
391    public static Set<BannerSize> fittingBannerSizesLandscape(Context context) {
392        logAATKitCall("CMD: fittingBannerSizesLandscape(" + context + ")");
393        return Utils.fittingBannerSizes(Utils.screenWidthLandscape(context));
394    }
395
396    /**
397     * Notifies AATKit about activity resume. Invoke this method in every activity that uses AATKit.
398     *
399     * @param activity Reference to {@link Activity}.
400     */
401    public static void onActivityResume(Activity activity) {
402        logAATKitCall("CMD: onActivityResume(" + activity + ")");
403        adController.onActivityResume(activity);
404    }
405
406    /**
407     * Notifies AATKit about activity pause. Invoke this method in every activity that uses AATKit.
408     *
409     * @param activity Reference to {@link Activity}.
410     */
411    public static void onActivityPause(Activity activity) {
412        logAATKitCall("CMD: onActivityPause(" + activity + ")");
413        adController.onActivityPause();
414    }
415
416    /**
417     * Creates placement with given name and size. If the placement of given name and size already exists, it will be returned.
418     *
419     * @param name Unique name of placement. The same name will be used in addapptr.com account.
420     * @param size Size of placement. Use {@link PlacementSize#Fullscreen} for interstitials, {@link PlacementSize#Native} for native ads and other sizes for banner ads.
421     * @return Placement identifier, or -1 if placement cannot be created.
422     */
423    public static int createPlacement(String name, PlacementSize size) {
424        logAATKitCall("CMD: createPlacement(" + name + "," + size + ")");
425        return adController.createPlacement(name, size);
426    }
427
428    /**
429     * Creates a new native ad placement. If the native ad placement of given name already exists, it will be returned.
430     *
431     * @param name              Unique name of placement. The same name will be used in addapptr.com account.
432     * @param supportsMainImage True if the native ads returned should have main image asset. Keep in mind that if main image is used, it has to be displayed.
433     * @return Placement identifier, or -1 if placement cannot be created.
434     */
435    public static int createNativeAdPlacement(String name, boolean supportsMainImage) {
436        logAATKitCall("CMD: createNativeAdPlacement(" + name + "," + supportsMainImage + ")");
437        return adController.createNativeAdPlacement(name, supportsMainImage);
438    }
439
440    /**
441     * Creates a new banner placement. If the banner placement of given name already exists, it will be returned.
442     * <p>
443     * <b>The placement will create a copy of the
444     * configuration.</b> Any changes made to the configuration after placement is created will be ignored.
445     *
446     * @param name          Unique name of placement. The same name will be used in addapptr.com account.
447     * @param configuration The configuration for this placement. The placement will ignore any changes made to configuration after it was created.
448     * @return Banner placement instance, or null if the placement cannot be created.
449     */
450    public static BannerPlacement createBannerPlacement(String name, BannerConfiguration configuration) {
451        logAATKitCall("CMD: createInFeedBannerPlacement(" + name + "," + configuration + ")");
452        return adController.createBannerPlacement(name, configuration);
453    }
454
455    /**
456     * Creates a new rewarded video placement. If the rewarded video ad placement of given name already exists, it will be returned.
457     * <b>Only one Rewarded Video placement can be used within the app.</b>
458     *
459     * @param name Unique name of placement. The same name will be used in addapptr.com account.
460     * @return Placement identifier, or -1 if placement cannot be created.
461     */
462    public static int createRewardedVideoPlacement(String name) {
463        logAATKitCall("CMD: createRewardedVideoPlacement(" + name + ")");
464        return adController.createRewardedVideoPlacement(name);
465    }
466
467    /**
468     * Enables automatic reloading of placement. Autoreloader will use reload time configured on addapptr.com account or fallback to default {@value #BANNER_DEFAULT_RELOAD_INTERVAL_IN_SECONDS} seconds.
469     *
470     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
471     */
472    public static void startPlacementAutoReload(int placementId) {
473        logAATKitCall("CMD: startPlacementAutoReload(" + placementId + ")");
474        adController.startPlacementAutoReload(placementId);
475    }
476
477    /**
478     * Enables automatic reloading of placement and sets custom reload time. This reload time will be used instead of time configured on addapptr.com account.
479     *
480     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
481     * @param seconds     Interval between ad reloads. Should be a value from {@value #BANNER_MIN_RELOAD_INTERVAL_IN_SECONDS} to {@value #BANNER_MAX_RELOAD_INTERVAL_IN_SECONDS} seconds.
482     */
483    public static void startPlacementAutoReload(int placementId, int seconds) {
484        logAATKitCall("CMD: startPlacementAutoReload(" + placementId + "," + seconds + ")");
485        adController.startPlacementAutoReload(placementId, seconds);
486    }
487
488    /**
489     * Disables automatic reloading of placement.
490     *
491     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
492     */
493    public static void stopPlacementAutoReload(int placementId) {
494        logAATKitCall("CMD: stopPlacementAutoReload(" + placementId + ")");
495        adController.stopPlacementAutoReload(placementId);
496    }
497
498    /**
499     * Sets reload time that will be used instead of time configured on addapptr.com account.
500     *
501     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
502     * @param seconds     Interval between ad reloads. Should be a value from {@value #BANNER_MIN_RELOAD_INTERVAL_IN_SECONDS} to {@value #BANNER_MAX_RELOAD_INTERVAL_IN_SECONDS} seconds.
503     */
504    public static void setPlacementAutoreloadInterval(int placementId, int seconds) {
505        logAATKitCall("CMD: setPlacementAutoreloadInterval(" + placementId + "," + seconds + ")");
506        adController.setPlacementAutoreloadInterval(placementId, seconds);
507    }
508
509    /**
510     * Requests placement reload. Works only if automatic reloading is disabled. For native ads, it might return false if current limit for native ads loading in parallel is reached.
511     * <p>
512     * For banners it will not cause new banner to show more often than set banner refresh interval (default: 30s) - instead, it will set a timer to reload and show next ad when the refresh interval passes. To force ad reload and display before this delay, use the method {@link #reloadPlacement(int, boolean)} instead.
513     *
514     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
515     * @return True if call ends in causing a placement to reload, false otherwise.
516     * @see #reloadPlacement(int, boolean)
517     */
518    public static boolean reloadPlacement(int placementId) {
519        logAATKitCall("CMD: reloadPlacement(" + placementId + ")");
520        return adController.reloadPlacement(placementId, false);
521    }
522
523    /**
524     * Requests placement reload. Works only if automatic reloading is disabled. For native ads, it might return false if current limit for native ads loading in parallel is reached.
525     *
526     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
527     * @param forceLoad   True if you want to be able to reload and show new banner before set banner reload interval (default: 30s) between reloads, false otherwise.
528     * @return True if call ends in causing a placement to reload, false otherwise.
529     * @see #reloadPlacement(int)
530     */
531    public static boolean reloadPlacement(int placementId, boolean forceLoad) {
532        logAATKitCall("CMD: reloadPlacement(" + placementId + "," + forceLoad + ")");
533        return adController.reloadPlacement(placementId, forceLoad);
534    }
535
536    /**
537     * Returns placement view. Works only for banner placements.
538     *
539     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
540     * @return Placement view or null if {@code placementId} is not valid.
541     */
542    public static View getPlacementView(int placementId) {
543        logAATKitCall("CMD: getPlacementView(" + placementId + ")");
544        return adController.getPlacementView(placementId);
545    }
546
547
548    /**
549     * Binds the native ad instance with given ViewGroup. Needed for click handling and tracking. Please note that this method will not work correctly with Facebook Audience Network ads.
550     *
551     * @param nativeAd Native ad instance.
552     * @param layout   ViewGroup used to render the native ad.
553     * @deprecated This method is deprecated and will be removed in the future. Please use {@link #attachNativeAdToLayout(NativeAdData, ViewGroup, View, View, View)} instead.
554     */
555    @Deprecated
556    public static void attachNativeAdToLayout(NativeAdData nativeAd, ViewGroup layout) {
557        logAATKitCall("CMD: attachNativeAdToLayout(" + nativeAd + ", " + layout.getClass().getSimpleName() + ")");
558        if (Logger.isLoggable(Log.WARN)) {
559            Logger.w(AATKit.class, "");
560        }
561        adController.attachNativeAdToLayout(nativeAd, layout, null, null, null);
562    }
563
564    /**
565     * Binds the native ad instance with given ViewGroup. Needed for click handling and tracking.
566     *
567     * @param nativeAd      Native ad instance.
568     * @param layout        ViewGroup used to render the native ad.
569     * @param mainImageView View used to show the main image of the ad. Can be null.
570     * @param iconView      View used to show the icon of the native ad.
571     * @deprecated This method is deprecated and will be removed in the future. Please use {@link #attachNativeAdToLayout(NativeAdData, ViewGroup, View, View, View)} instead.
572     */
573    @Deprecated
574    public static void attachNativeAdToLayout(NativeAdData nativeAd, ViewGroup layout, View mainImageView, View iconView) {
575        String mainImageClass = mainImageView == null ? "null" : mainImageView.getClass().getSimpleName();
576        String iconViewClass = iconView == null ? "null" : iconView.getClass().getSimpleName();
577        logAATKitCall("CMD: attachNativeAdToLayout(" + nativeAd + ", " + layout.getClass().getSimpleName() + ", " + mainImageClass + ", " + iconViewClass + ")");
578        adController.attachNativeAdToLayout(nativeAd, layout, mainImageView, iconView, null);
579    }
580
581    /**
582     * Binds the native ad instance with given ViewGroup. Needed for click handling and tracking.
583     *
584     * @param nativeAd      Native ad instance.
585     * @param layout        ViewGroup used to render the native ad.
586     * @param mainImageView View used to show the main image of the ad. Can be null.
587     * @param iconView      View used to show the icon of the native ad.
588     * @param CTAView       View used to show the Call To Action of the native ad. Can be null.
589     */
590    public static void attachNativeAdToLayout(NativeAdData nativeAd, ViewGroup layout, View mainImageView, View iconView, View CTAView) {
591        String mainImageClass = mainImageView == null ? "null" : mainImageView.getClass().getSimpleName();
592        String iconViewClass = iconView == null ? "null" : iconView.getClass().getSimpleName();
593        String ctaViewClass = CTAView == null ? "null" : CTAView.getClass().getSimpleName();
594        logAATKitCall("CMD: attachNativeAdToLayout(" + nativeAd + ", " + layout.getClass().getSimpleName() + ", " + mainImageClass + ", " + iconViewClass + ", " + ctaViewClass + ")");
595        adController.attachNativeAdToLayout(nativeAd, layout, mainImageView, iconView, CTAView);
596    }
597
598    /**
599     * Removes the binding between native ad and ViewGroup. Should be called when the native ad will no longer be presented and should be destroyed.
600     *
601     * @param nativeAd Native ad instance.
602     */
603    public static void detachNativeAdFromLayout(NativeAdData nativeAd) {
604        logAATKitCall("CMD: detachNativeAdFromLayout(" + nativeAd + ")");
605        adController.detachNativeAdFromLayout(nativeAd);
606    }
607
608    /**
609     * Returns the title of native ad.
610     *
611     * @param nativeAd Native ad instance.
612     * @return String with title asset of the ad, or null if it is not available.
613     */
614    public static String getNativeAdTitle(NativeAdData nativeAd) {
615        logAATKitCall("CMD: getNativeAdTitle(" + nativeAd + ")");
616        return adController.getNativeAdTitle(nativeAd);
617    }
618
619    /**
620     * Returns the description of native ad.
621     *
622     * @param nativeAd Native ad instance.
623     * @return String with description asset of the ad, or null if it is not available.
624     */
625    public static String getNativeAdDescription(NativeAdData nativeAd) {
626        logAATKitCall("CMD: getNativeAdDescription(" + nativeAd + ")");
627        return adController.getNativeAdDescription(nativeAd);
628    }
629
630    /**
631     * Returns the call to action of native ad.
632     *
633     * @param nativeAd Native ad instance.
634     * @return String with call to action asset of the ad, or null if it is not available.
635     */
636    public static String getNativeAdCallToAction(NativeAdData nativeAd) {
637        logAATKitCall("CMD: getNativeAdCallToAction(" + nativeAd + ")");
638        return adController.getNativeAdCallToAction(nativeAd);
639    }
640
641    /**
642     * Returns the URL of the image asset of native ad.
643     *
644     * @param nativeAd Native ad instance.
645     * @return String with URL of the image asset of the ad, or null if it is not available.
646     */
647    public static String getNativeAdImageUrl(NativeAdData nativeAd) {
648        logAATKitCall("CMD: getNativeAdImageUrl(" + nativeAd + ")");
649        return adController.getNativeAdImageUrl(nativeAd);
650    }
651
652    /**
653     * Returns the URL of the icon asset of native ad.
654     *
655     * @param nativeAd Native ad instance.
656     * @return String with URL of the icon asset of the ad, or null if it is not available.
657     */
658    public static String getNativeAdIconUrl(NativeAdData nativeAd) {
659        logAATKitCall("CMD: getNativeAdIconUrl(" + nativeAd + ")");
660        return adController.getNativeAdIconUrl(nativeAd);
661    }
662
663    /**
664     * Returns the rating asset of native ad.
665     *
666     * @param nativeAd Native ad instance.
667     * @return NativeAdRating instance containing both value and scale of rating, or null if it is not available.
668     */
669    public static NativeAd.NativeAdRating getNativeAdRating(NativeAdData nativeAd) {
670        logAATKitCall("CMD: getNativeAdRating(" + nativeAd + ")");
671        return adController.getNativeAdRating(nativeAd);
672    }
673
674    /**
675     * Returns the view with branding logo or ad information related to the ad network providing the native ad. Some networks like Facebook Audience Network require this special view to be visible on native ads.
676     *
677     * @param nativeAd Native ad insance.
678     * @return View that should be added to native ad layout, or null if it is not available.
679     */
680    public static View getNativeAdBrandingLogo(NativeAdData nativeAd) {
681        logAATKitCall("CMD: getNativeAdBrandingLogo(" + nativeAd + ")");
682        return adController.getNativeAdBrandingLogo(nativeAd);
683    }
684
685    /**
686     * Returns the advertiser asset of native ad (not the same as ad network providing it).
687     *
688     * @param nativeAd Native ad instance.
689     * @return String with advertiser asset of the ad, or null if it is not available.
690     */
691    public static String getNativeAdAdvertiser(NativeAdData nativeAd) {
692        logAATKitCall("CMD: getNativeAdAdvertiser(" + nativeAd + ")");
693        return adController.getNativeAdAdvertiser(nativeAd);
694    }
695
696    /**
697     * Returns the type of native ad. Only some networks support this, default value is {@link com.intentsoftware.addapptr.ad.NativeAd.Type#UNKNOWN}
698     *
699     * @param nativeAd Native ad instance.
700     * @return Enum value representing the type of given native ad.
701     * @deprecated For Google Native Ads, it is now recommended to use the Unified ad type. See our documentation on native ads integration to learn more.
702     */
703    @Deprecated
704    public static NativeAd.Type getNativeAdType(NativeAdData nativeAd) {
705        logAATKitCall("CMD: getNativeAdType(" + nativeAd + ")");
706        return adController.getNativeAdType(nativeAd);
707    }
708
709    /**
710     * Returns the ad network providing given native ad
711     *
712     * @param nativeAd Native ad instance.
713     * @return Enum value representing the ad network providing the ad.
714     */
715    public static AdNetwork getNativeAdNetwork(NativeAdData nativeAd) {
716        logAATKitCall("CMD: getNativeAdNetwork(" + nativeAd + ")");
717        return adController.getNativeAdNetwork(nativeAd);
718    }
719
720    /**
721     * Returns if the native ad has expired and shall no longer be used.
722     *
723     * @param nativeAd Native ad instance.
724     * @return True if native ad has expired, false otherwise.
725     */
726    public static boolean isNativeAdExpired(NativeAdData nativeAd) {
727        logAATKitCall("CMD: isNativeAdExpired(" + nativeAd + ")");
728        return adController.isNativeAdExpired(nativeAd);
729    }
730
731    /**
732     * Returns if the native ad is ready to be displayed.
733     *
734     * @param nativeAd Native ad instance.
735     * @return True if native ad is ready, false otherwise.
736     */
737    public static boolean isNativeAdReady(NativeAdData nativeAd) {
738        logAATKitCall("CMD: isNativeAdReady(" + nativeAd + ")");
739        return adController.isNativeAdReady(nativeAd);
740    }
741
742    /**
743     * Indicates that the application wants to display a native ad for given native ad placement. Used in reporting.
744     *
745     * @param placementId Placement identifier obtained from
746     *                    {@link #createPlacement(String, PlacementSize)}.
747     * @deprecated Please use {@link #reportAdSpaceForPlacement(int)} instead.
748     */
749    @Deprecated
750    public static void reportAdSpaceForNativePlacement(int placementId) {
751        logAATKitCall("CMD: reportAdSpaceForNativePlacement(" + placementId + ")");
752        adController.reportAdSpaceForPlacement(placementId);
753    }
754
755    /**
756     * Indicates that the application wants to display a native or VAST ad for given placement. Used in reporting.
757     *
758     * @param placementId Placement identifier obtained from
759     *                    {@link #createPlacement(String, PlacementSize)}.
760     */
761    public static void reportAdSpaceForPlacement(int placementId) {
762        logAATKitCall("CMD: reportAdSpaceForPlacement(" + placementId + ")");
763        adController.reportAdSpaceForPlacement(placementId);
764    }
765
766    /**
767     * Returns how many ads are currently loading for given native ad placement.
768     *
769     * @param placementId Placement identifier obtained from
770     *                    {@link #createPlacement(String, PlacementSize)}.
771     * @return Number of ads that are currently loading for given placement.
772     */
773    public static int currentlyLoadingNativeAdsOnPlacement(int placementId) {
774        logAATKitCall("CMD: currentlyLoadingNativeAdsOnPlacement(" + placementId + ")");
775        return adController.currentlyLoadingNativeAdsOnPlacement(placementId);
776    }
777
778    /**
779     * Checks if desired impression cap (set on AddApptr Dashboard) is reached for given native ad placement.
780     *
781     * @param placementId Placement identifier obtained from
782     *                    {@link #createPlacement(String, PlacementSize)}.
783     * @return True if impression cap is reached for this placement, false otherwise.
784     * @deprecated This method is deprecated and will be removed in the future. Please use {@link #isFrequencyCapReachedForPlacement(int)} method instead.
785     */
786    @Deprecated
787    public static boolean isFrequencyCapReachedForNativePlacement(int placementId) {
788        logAATKitCall("CMD: isFrequencyCapReachedForNativePlacement(" + placementId + ")");
789        return adController.isFrequencyCapReachedForPlacement(placementId);
790    }
791
792    /**
793     * Checks if desired impression cap (set on AddApptr Dashboard) is reached for given native ad, fullscreen, rewarded video or VAST placement.
794     * Note: this method will ALWAYS return "false" for other placement types.
795     *
796     * @param placementId Placement identifier obtained from
797     *                    {@link #createPlacement(String, PlacementSize)}.
798     * @return True if impression cap is reached for given placement, false otherwise.
799     */
800    public static boolean isFrequencyCapReachedForPlacement(int placementId) {
801        logAATKitCall("CMD: isFrequencyCapReachedForPlacement(" + placementId + ")");
802        return adController.isFrequencyCapReachedForPlacement(placementId);
803    }
804
805    /**
806     * Returns the instance of native ad for given native ad placement.
807     *
808     * @param placementId Placement identifier obtained from
809     *                    {@link #createPlacement(String, PlacementSize)}.
810     * @return Native ad instance if it is loaded for given placement, null otherwise.
811     */
812    public static NativeAdData getNativeAd(int placementId) {
813        logAATKitCall("CMD: getNativeAd(" + placementId + ")");
814        return adController.getNativeAd(placementId);
815    }
816
817    /**
818     * Returns identifier of placement with given name, or -1 if placement with given name does not exist.
819     *
820     * @param placementName Placent name, used when creating placement with {@link #createPlacement(String, PlacementSize)} method.
821     * @return Placement identifier, or -1 if placement does not exist.
822     * @deprecated This method is deprecated and will be removed in the future. Please use {@link #getPlacementIdForName(String)} method instead.
823     */
824    @Deprecated
825    public static int getPlacmentIdForName(String placementName) {
826        logAATKitCall("CMD: getPlacmentIdForName(" + placementName + ")");
827        return adController.findPlacementIdByRealName(placementName);
828    }
829
830    /**
831     * Returns identifier of placement with given name, or -1 if placement with given name does not exist.
832     *
833     * @param placementName Placent name, used when creating placement with {@link #createPlacement(String, PlacementSize)} method.
834     * @return Placement identifier, or -1 if placement does not exist.
835     */
836    public static int getPlacementIdForName(String placementName) {
837        logAATKitCall("CMD: getPlacementIdForName(" + placementName + ")");
838        return adController.findPlacementIdByRealName(placementName);
839    }
840
841    /**
842     * Returns true if there is an ad loaded for given placementId.
843     *
844     * @param placementId Placement identifier obtained from
845     *                    {@link #createPlacement(String, PlacementSize)}.
846     * @return True if there is an ad loaded for given placementId.
847     */
848    public static boolean hasAdForPlacement(int placementId) {
849        logAATKitCall("CMD: hasAdForPlacement(" + placementId + ")");
850        return adController.hasAdForPlacement(placementId);
851    }
852
853    /**
854     * Shows interstitial ad if ad is ready.
855     *
856     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
857     * @return True if showing interstitial was successful, false otherwise.
858     */
859    public static boolean showPlacement(int placementId) {
860        logAATKitCall("CMD: showPlacement(" + placementId + ")");
861        return adController.showPlacement(placementId);
862    }
863
864    /**
865     * Allows to enable or disable selected ad networks. By default all networks are enabled.
866     *
867     * @param network Ad network.
868     * @param enabled True to enable, false to disable.
869     */
870    public static void setNetworkEnabled(AdNetwork network, boolean enabled) {
871        logAATKitCall("CMD: setNetworkEnabled(" + network + "," + enabled + ")");
872        SupportedNetworks.setNetworkEnabled(network, enabled);
873    }
874
875    /**
876     * Returns true if ad network is enabled, false otherwise.
877     *
878     * @param network Ad network.
879     * @return True if ad network is enabled, false otherwise.
880     */
881    public static boolean isNetworkEnabled(AdNetwork network) {
882        logAATKitCall("CMD: isNetworkEnabled(" + network + ")");
883        return SupportedNetworks.isNetworkEnabled(network);
884    }
885
886    /**
887     * Sets placement default image. This image will be shown in placement when no ad is available.
888     *
889     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
890     * @param image       The bitmap to set.
891     */
892    public static void setPlacementDefaultImageBitmap(int placementId, Bitmap image) {
893        logAATKitCall("CMD: setPlacementDefaultImageBitmap(" + placementId + "," + image + ")");
894        adController.setPlacementDefaultImage(placementId, image);
895    }
896
897    /**
898     * Sets placement default image. This image will be shown in placement when no ad is available.
899     *
900     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
901     * @param resId       The identifier of the resource.
902     */
903    public static void setPlacementDefaultImageResource(int placementId, int resId) {
904        logAATKitCall("CMD: setPlacementDefaultImageResource(" + placementId + "," + resId + ")");
905        adController.setPlacementDefaultImageResource(placementId, resId);
906    }
907
908    /**
909     * Get option from AATKit. Options can be obtained from the server or set using the {@link #setOption(String, String)} method.
910     *
911     * @param optionName The name of the option to be checked.
912     * @return Value of the option or null if it is not set.
913     */
914    public static String getOption(String optionName) {
915        logAATKitCall("CMD: getOption(" + optionName + ")");
916        return AdController.getOption(optionName);
917    }
918
919    /**
920     * Convenience method for checking if option is enabled in AATKit. Options can be obtained from the server or set using the {@link #setOption(String, String)} method.
921     *
922     * @param optionName The name of the option to be checked.
923     * @return True if option value is "Yes", false otherwise.
924     */
925    public static boolean isOptionEnabled(String optionName) {
926        logAATKitCall("CMD: isOptionEnabled(" + optionName + ")");
927        return AdController.isOptionEnabled(optionName);
928    }
929
930    /**
931     * Set option in AATKit. Options can also be obtained from the server.
932     *
933     * @param optionName  The name of the option to be set.
934     * @param optionValue The value of the option to be set.
935     */
936    public static void setOption(String optionName, String optionValue) {
937        logAATKitCall("CMD: setOption(" + optionName + "," + optionName + ")");
938        adController.setOption(optionName, optionValue);
939    }
940
941    /**
942     * Sets the targeting information for the application. This information will be used only if no placement-specific targeting is available.
943     *
944     * @param info Map with targeting information
945     * @see #setTargetingInfo(int, Map)
946     */
947    public static void setTargetingInfo(Map<String, List<String>> info) {
948        logAATKitCall("CMD: setTargetingInfo(" + info + ")");
949        adController.setTargetingInfo(null, info);
950    }
951
952    /**
953     * Sets the targeting information for the given placement. Information provided for placement overrides targeting information for application set by the {@link #setTargetingInfo(Map)}.
954     *
955     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
956     * @param info        Map with targeting information
957     */
958    public static void setTargetingInfo(int placementId, Map<String, List<String>> info) {
959        logAATKitCall("CMD: setTargetingInfo(" + placementId + ", " + info + ")");
960        adController.setTargetingInfo(placementId, info);
961    }
962
963    /**
964     * Sets the content targeting url for the application. This information will be used only if no placement-specific targeting is available.
965     *
966     * @param targetingUrl The targeting url
967     * @see #setContentTargetingUrl(int, String)
968     */
969    public static void setContentTargetingUrl(String targetingUrl) {
970        logAATKitCall("CMD: setContentTargetingUrl(" + targetingUrl + ")");
971        adController.setContentTargetingUrl(null, targetingUrl);
972    }
973
974    /**
975     * Sets the content targeting url for the given placement. Information provided for placement overrides targeting information for application set by the {@link #setContentTargetingUrl(String)}.
976     *
977     * @param placementId  Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
978     * @param targetingUrl The targeting url
979     */
980    public static void setContentTargetingUrl(int placementId, String targetingUrl) {
981        logAATKitCall("CMD: setContentTargetingUrl(" + placementId + ", " + targetingUrl + ")");
982        adController.setContentTargetingUrl(placementId, targetingUrl);
983    }
984
985    /**
986     * Adds an ad network to the list of ad networks that receive targeting keywords (if any set).
987     * If no ad networks are added, any set keywords will be delivered to all ad networks supporting keyword targeting.
988     *
989     * @param network Chosen ad network.
990     */
991    public static void addAdNetworkForKeywordTargeting(AdNetwork network) {
992        logAATKitCall("CMD: addAdNetworkForKeywordTargeting(" + network + ")");
993        adController.addAdNetworkForKeywordTargeting(network);
994    }
995
996    /**
997     * Removes an ad network from the list of ad networks that receive targeting keywords (if any set).
998     * If no ad networks are added to the list, any set keywords will be delivered to all ad networks supporting keyword targeting.
999     *
1000     * @param network Chosen ad network.
1001     */
1002    public static void removeAdNetworkForKeywordTargeting(AdNetwork network) {
1003        logAATKitCall("CMD: removeAdNetworkForKeywordTargeting(" + network + ")");
1004        adController.removeAdNetworkForKeywordTargeting(network);
1005    }
1006
1007    /**
1008     * Sets gravity for ads that don't fill entire placement area. Works only for banner placements.
1009     *
1010     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
1011     * @param gravity     The {@link Gravity} to set.
1012     */
1013    public static void setPlacementContentGravity(int placementId, int gravity) {
1014        logAATKitCall("CMD: setPlacementContentGravity(" + placementId + "," + gravity + ")");
1015        adController.setPlacementContentGravity(placementId, gravity);
1016    }
1017
1018    /**
1019     * Allows setting of ad rules that will be used before real rules from the server are downloaded.
1020     *
1021     * @param rules String containing the rules to be used.
1022     */
1023    public static void setInitialRules(String rules) {
1024        logAATKitCall("CMD: setInitialRules(" + rules + ")");
1025        adController.setInitialRules(rules);
1026    }
1027
1028    /**
1029     * Allows the AATKit to preserve last downloaded ad rules when the application is closed. Such rules will be re-used next time the application is started, before new ones get downloaded.
1030     *
1031     * @param enabled True to enable, false to disable.
1032     */
1033    public static void setRuleCachingEnabled(boolean enabled) {
1034        logAATKitCall("CMD: setRuleCachingEnabled(" + enabled + ")");
1035        adController.setRuleCachingEnabled(enabled);
1036    }
1037
1038    /**
1039     * Allows to set log level from code.
1040     *
1041     * @param logLevel Desired log level, as in {@link android.util.Log} class.
1042     */
1043    public static void setLogLevel(int logLevel) {
1044        ServerLogger.log("CMD: setLogLevel(" + logLevel + ")");
1045        adController.setLogLevel(logLevel);
1046    }
1047
1048    /**
1049     * Reports the VAST ad impression.
1050     *
1051     * @param data The data for a VAST ad which has been impressed.
1052     */
1053    public static void reportVASTImpression(VASTAdData data) {
1054        logAATKitCall("CMD: reportVASTImpression(" + data + ")");
1055        adController.reportVASTImpression(data);
1056    }
1057
1058    /**
1059     * Reports the VAST ad viewable impression.
1060     *
1061     * @param data The VAST ad data for which the viewable impression should be counted.
1062     */
1063    public static void reportVASTViewableImpression(VASTAdData data) {
1064        logAATKitCall("CMD: reportVASTViewableImpression(" + data + ")");
1065        adController.reportVASTViewableImpression(data);
1066    }
1067
1068    /**
1069     * Reports the VAST ad click.
1070     *
1071     * @param data The data for a VAST ad which has been clicked.
1072     */
1073    public static void reportVASTClick(VASTAdData data) {
1074        logAATKitCall("CMD: reportVASTClick(" + data + ")");
1075        adController.reportVASTClick(data);
1076    }
1077
1078    /**
1079     * Sets VAST ad request parameters.
1080     *
1081     * @param placementId Placement identifier obtained from {@link #createPlacement(String, PlacementSize)}.
1082     * @param parameters  Parameters to set for a given placement identifier.
1083     */
1084    public static void setVASTRequestParameters(int placementId, VASTRequestParameters parameters) {
1085        logAATKitCall("CMD: setVASTRequestParameters(" + placementId + ", " + parameters + ")");
1086        adController.setVASTRequestParameters(placementId, parameters);
1087    }
1088
1089    //region non-public methods
1090
1091    private static void logAATKitCall(String call) {
1092        if (adController != null && adController.shouldLogAATKitCalls()) {
1093            ServerLogger.log(call);
1094        }
1095        if (Logger.isLoggable(Log.VERBOSE)) {
1096            String command = call.replaceFirst("^CMD:\\s*", "");
1097            Logger.v(AATKit.class, command);
1098        }
1099    }
1100
1101    static Pair<BannerPlacement, Boolean> createBannerPlacementForCache(String placementName, BannerConfiguration configuration, BannerCache cache) {
1102        return adController.createBannerPlacementForCache(placementName, configuration, cache);
1103    }
1104
1105    static void destroyBannerCache(BannerCache cache) {
1106        adController.destroyBannerCache(cache);
1107    }
1108
1109    // methods below are intended only for use by the plugins.
1110
1111    static void destroy() {
1112        adController.destroy();
1113        adController = null;
1114    }
1115
1116    static boolean isInitialized() {
1117        return adController != null;
1118    }
1119
1120    /**
1121     * Shows AATKit debug screen.
1122     */
1123    static void showDebugDialog() {
1124        logAATKitCall("CMD: showDebugDialog()");
1125        adController.showDebugDialog();
1126    }
1127
1128    //endregion
1129
1130}