001package com.intentsoftware.addapptr;
002
003import android.app.Activity;
004import android.content.Context;
005import android.util.Log;
006
007import com.intentsoftware.addapptr.consent.CMP;
008import com.intentsoftware.addapptr.consent.CMPDelegate;
009import com.intentsoftware.addapptr.module.Logger;
010
011import androidx.annotation.NonNull;
012
013/**
014 * Will present a dialog for the users to grant or withhold their consent.
015 */
016@SuppressWarnings({"unused", "WeakerAccess"})
017public class ManagedConsent extends ConsentImplementation implements CMPDelegate {
018
019    private CMPImplementation cmp;
020    private ManagedConsentDelegate delegate;
021    private Context applicationContext;
022
023    /**
024     * Creates the {@link ManagedConsent} instance.
025     *
026     * @param cmp      Instance of {@link CMP} to be used.
027     * @param context  The {@link Context} of your application.
028     * @param delegate The {@link ManagedConsentDelegate} instance. Must not be null.
029     */
030    public ManagedConsent(CMP cmp, Context context, @NonNull ManagedConsentDelegate delegate) {
031        if (cmp instanceof CMPImplementation) {
032            if (((CMPImplementation) cmp).isSuccessfullyInitialized()) {
033                this.cmp = (CMPImplementation) cmp;
034                this.cmp.setDelegate(this);
035                this.applicationContext = context.getApplicationContext();
036                this.delegate = delegate;
037                if (Logger.isLoggable(Log.VERBOSE)) {
038                        Logger.v(this, "initialized ManagedConsent: " + toString());
039                }
040            } else {
041                if (Logger.isLoggable(Log.ERROR)) {
042                        Logger.e(this, "Passed CMP was not successfully initialized. ManagedConsent will not work.");
043                }
044            }
045        } else {
046            if (Logger.isLoggable(Log.ERROR)) {
047                Logger.e(this, "Passed CMP is not an instance of allowed classes. ManagedConsent will not work.");
048            }
049        }
050    }
051
052    /**
053     * Presents the consent screen ONLY if it is required by the used CMP (i.e. no user consent has been set yet).
054     *
055     * @param activity The Activity from which the consent screen will be shown.
056     */
057    public void showIfNeeded(Activity activity) {
058        if (Logger.isLoggable(Log.VERBOSE)) {
059                Logger.v(this, "showIfNeeded called");
060        }
061        if (cmp != null && cmp.isSuccessfullyInitialized()) {
062            cmp.showIfNeeded(activity);
063        } else {
064            if (Logger.isLoggable(Log.ERROR)) {
065                Logger.e(this, "ManagedConsent was not initialized with a working CMP. Cannot show.");
066            }
067        }
068    }
069
070    /**
071     * Presents the consent screen, allowing the user to change consent settings.
072     *
073     * @param activity The Activity from which the consent screen will be shown.
074     */
075    public void editConsent(Activity activity) {
076        if (Logger.isLoggable(Log.VERBOSE)) {
077                Logger.v(this, "editConsent called");
078        }
079        if (cmp != null && cmp.isSuccessfullyInitialized()) {
080            cmp.editConsent(activity);
081        } else {
082            if (Logger.isLoggable(Log.ERROR)) {
083                Logger.e(this, "ManagedConsent was not initialized with a working CMP. Cannot edit.");
084            }
085        }
086    }
087
088    /**
089     * Tells the CMP to reload. You can call this method for example after receiving {@link ManagedConsentDelegate#managedConsentCMPFailedToLoad(ManagedConsent, String)} callback.
090     *
091     * @param activity The Activity instance.
092     */
093    public void reload(Activity activity) {
094        if (Logger.isLoggable(Log.VERBOSE)) {
095                Logger.v(this, "reload called");
096        }
097        if (cmp != null && cmp.isSuccessfullyInitialized()) {
098            cmp.reload(activity);
099        } else {
100            if (Logger.isLoggable(Log.ERROR)) {
101                Logger.e(this, "ManagedConsent was not initialized with a working CMP. Cannot reload.");
102            }
103        }
104    }
105
106    @Override
107    public void onConsentUpdated(ManagedConsentState state) {
108        readConsentStringFromSharedPreferences(applicationContext);
109        ConsentHelper.reconfigureNetworks(applicationContext);
110        delegate.managedConsentCMPFinished(state);
111    }
112
113    @Override
114    public void onCMPFailedToShow(String error) {
115        if (Logger.isLoggable(Log.WARN)) {
116            Logger.w(this, "Failed to show CMP: " + error);
117        }
118        delegate.managedConsentCMPFailedToShow(this, error);
119    }
120
121    @Override
122    public void onCMPFailedToLoad(String error) {
123        if (Logger.isLoggable(Log.WARN)) {
124            Logger.w(this, "Failed to load CMP: " + error);
125        }
126        delegate.managedConsentCMPFailedToLoad(this, error);
127    }
128
129    @Override
130    public void CMPNeedsUI() {
131        if (Logger.isLoggable(Log.VERBOSE)) {
132            Logger.v(this, "CMP needs UI");
133        }
134        delegate.managedConsentNeedsUserInterface(this);
135    }
136
137    @Override
138    NonIABConsent getConsentForNetwork(AdNetwork network) {
139        if (cmp != null && cmp.isSuccessfullyInitialized()) {
140            return cmp.getConsentForNetwork(network);
141        } else {
142            if (Logger.isLoggable(Log.ERROR)) {
143                Logger.e(this, "ManagedConsent was not initialized with a working CMP, cannot check consent for network");
144            }
145            return NonIABConsent.WITHHELD;
146        }
147    }
148
149    @Override
150    public String toString() {
151        return "ManagedConsent{" +
152                "cmp=" + cmp +
153                ", delegate=" + delegate +
154                "} " + super.toString();
155    }
156
157    /**
158     * Notifies about the need to show the consent dialog.
159     */
160    public interface ManagedConsentDelegate {
161        /**
162         * Notifies that {@link ManagedConsent} needs to show a consent dialog. After receiving this notification, you should pause your application and call the {@link #showIfNeeded(Activity)} method.
163         *
164         * @param managedConsent The {@link ManagedConsent} instance that requests UI.
165         */
166        void managedConsentNeedsUserInterface(ManagedConsent managedConsent);
167
168        /**
169         * Notifies that the used {@link CMP} has finished updating consent.
170         * @param state The {@link ManagedConsentState} informing about consent given by the user.
171         */
172        void managedConsentCMPFinished(ManagedConsentState state);
173
174        /**
175         * Notifies that the used {@link CMP} failed to load.
176         *
177         * @param managedConsent @param managedConsent The {@link ManagedConsent} instance.
178         * @param error          The description of what went wrong
179         */
180        void managedConsentCMPFailedToLoad(ManagedConsent managedConsent, String error);
181
182        /**
183         * Notifies that the used {@link CMP} failed to show.
184         *
185         * @param managedConsent @param managedConsent The {@link ManagedConsent} instance.
186         * @param error          The description of what went wrong
187         */
188        void managedConsentCMPFailedToShow(ManagedConsent managedConsent, String error);
189    }
190
191    /**
192     * Possible states of consent given by the user.
193     */
194    public enum ManagedConsentState {
195        /**
196         * No information about consent state.
197         */
198        UNKNOWN,
199
200        /**
201         * Consent has been declined by the user.
202         */
203        WITHHELD,
204
205        /**
206         * Partial consent has been granted by the user - at least some purposes and some vendors were given consent.
207         */
208        CUSTOM,
209
210        /**
211         * Full consent has been granted by the user.
212         */
213        OBTAINED
214    }
215
216}