Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public void onCreate() {

OneSignal.unsubscribeWhenNotificationsAreDisabled(true);
OneSignal.pauseInAppMessages(true);
OneSignal.setLocationShared(false);

Log.d(Tag.DEBUG, Text.ONESIGNAL_SDK_INIT);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ public void onClick(View v) {
locationSharedSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO remove element, was replaced by remote params
OneSignal.setLocationShared(isChecked);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,17 @@ public void onOSSubscriptionChanged(OSSubscriptionStateChanges stateChanges) {
}

private void setupOneSignalSDK() {
boolean privacyConsent = true;
OneSignal.setRequiresUserPrivacyConsent(privacyConsent);

boolean isLocationShared = OneSignalPrefs.getCachedLocationSharedStatus(context);
OneSignal.setLocationShared(isLocationShared);

boolean isInAppMessagingPaused = OneSignalPrefs.getCachedInAppMessagingPausedStatus(context);
OneSignal.pauseInAppMessages(isInAppMessagingPaused);

Log.d(Tag.DEBUG, Text.PRIVACY_CONSENT_REQUIRED_SET + ": " + privacyConsent);

boolean isEmailCached = attemptSignIn(new EmailUpdateCallback() {
@Override
public void onSuccess() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,6 @@ void saveRemoteParams(OneSignalRemoteParams.Params remoteParams,
OneSignalPrefs.PREFS_OS_RECEIVE_RECEIPTS_ENABLED,
remoteParams.receiveReceiptEnabled
);
OneSignalPrefs.saveBool(
OneSignalPrefs.PREFS_ONESIGNAL,
OneSignalPrefs.PREFS_OS_UNSUBSCRIBE_WHEN_NOTIFICATIONS_DISABLED,
remoteParams.unsubscribeWhenNotificationsDisabled
);
OneSignalPrefs.saveBool(
OneSignalPrefs.PREFS_ONESIGNAL,
OneSignalPrefs.PREFS_OS_DISABLE_GMS_MISSING_PROMPT,
remoteParams.disableGMSMissingPrompt
);
OneSignalPrefs.saveBool(
OneSignalPrefs.PREFS_ONESIGNAL,
preferences.getOutcomesV2KeyName(),
Expand All @@ -57,9 +47,13 @@ void saveRemoteParams(OneSignalRemoteParams.Params remoteParams,
logger.debug("OneSignal saveInfluenceParams: " + remoteParams.influenceParams.toString());
trackerFactory.saveInfluenceParams(remoteParams.influenceParams);

saveLocationShared(remoteParams.locationShared);
OneSignal.setSharedLocation(remoteParams.locationShared);
savePrivacyConsentRequired(remoteParams.requiresUserPrivacyConsent);
saveGMSMissingPromptDisable(remoteParams.disableGMSMissingPrompt);
if (remoteParams.unsubscribeWhenNotificationsDisabled != null)
saveUnsubscribeWhenNotificationsAreDisabled(remoteParams.unsubscribeWhenNotificationsDisabled);
if (remoteParams.locationShared != null)
saveLocationShared(remoteParams.locationShared);
if (remoteParams.requiresUserPrivacyConsent != null)
savePrivacyConsentRequired(remoteParams.requiresUserPrivacyConsent);
}

boolean isRemoteParamsCallDone() {
Expand All @@ -70,6 +64,18 @@ OneSignalRemoteParams.Params getRemoteParams() {
return remoteParams;
}

boolean hasLocationKey() {
return remoteParams != null && remoteParams.locationShared != null;
}

boolean hasPrivacyConsentKey() {
return remoteParams != null && remoteParams.requiresUserPrivacyConsent != null;
}

boolean hasUnsubscribeNotificationKey() {
return remoteParams != null && remoteParams.unsubscribeWhenNotificationsDisabled != null;
}

void clearRemoteParams() {
remoteParams = null;
}
Expand All @@ -95,13 +101,29 @@ boolean unsubscribeWhenNotificationsAreDisabled() {
true);
}

void saveUnsubscribeWhenNotificationsAreDisabled(boolean unsubscribe) {
OneSignalPrefs.saveBool(
OneSignalPrefs.PREFS_ONESIGNAL,
OneSignalPrefs.PREFS_OS_UNSUBSCRIBE_WHEN_NOTIFICATIONS_DISABLED,
unsubscribe
);
}

boolean isGMSMissingPromptDisable() {
return OneSignalPrefs.getBool(
OneSignalPrefs.PREFS_ONESIGNAL,
OneSignalPrefs.PREFS_OS_DISABLE_GMS_MISSING_PROMPT,
false);
}

void saveGMSMissingPromptDisable(boolean promptDisable) {
OneSignalPrefs.saveBool(
OneSignalPrefs.PREFS_ONESIGNAL,
OneSignalPrefs.PREFS_OS_DISABLE_GMS_MISSING_PROMPT,
promptDisable
);
}

boolean isLocationShared() {
return OneSignalPrefs.getBool(
OneSignalPrefs.PREFS_ONESIGNAL,
Expand All @@ -120,10 +142,9 @@ boolean isPrivacyConsentRequired() {
return OneSignalPrefs.getBool(
OneSignalPrefs.PREFS_ONESIGNAL,
OneSignalPrefs.PREFS_OS_REQUIRES_USER_PRIVACY_CONSENT,
true);
false);
}


void savePrivacyConsentRequired(boolean required) {
OneSignalPrefs.saveBool(
OneSignalPrefs.PREFS_ONESIGNAL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class OSTaskController {
static final String IDS_AVAILABLE = "idsAvailable()";
static final String SEND_TAG = "sendTag()";
static final String SEND_TAGS = "sendTags()";
static final String SET_LOCATION_SHARED = "setLocationShared()";
static final String SET_REQUIRES_USER_PRIVACY_CONSENT = "setRequiresUserPrivacyConsent()";
static final String UNSUBSCRIBE_WHEN_NOTIFICATION_ARE_DISABLED = "unsubscribeWhenNotificationsAreDisabled()";
static final String HANDLE_NOTIFICATION_OPEN = "handleNotificationOpen()";
static final String CANCEL_GROUPED_NOTIFICATIONS = "cancelGroupedNotifications()";
static final HashSet<String> METHODS_AVAILABLE_FOR_DELAY = new HashSet<>(Arrays.asList(
Expand All @@ -37,6 +40,9 @@ class OSTaskController {
IDS_AVAILABLE,
SEND_TAG,
SEND_TAGS,
SET_LOCATION_SHARED,
SET_REQUIRES_USER_PRIVACY_CONSENT,
UNSUBSCRIBE_WHEN_NOTIFICATION_ARE_DISABLED,
HANDLE_NOTIFICATION_OPEN,
SET_EMAIL));

Expand Down
106 changes: 97 additions & 9 deletions OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
Expand Down Expand Up @@ -93,8 +94,7 @@ public enum LOG_LEVEL {
/**
* A display type enum for notifications when the app receives and tries shows them.
* <br/><br/>
* Used with the {@link OneSignal#setNotificationDisplayOption(OSNotificationDisplay)} and
* {@link OSNotificationGenerationJob#setNotificationDisplayOption(OSNotificationDisplay)}
* Used with the {@link OSNotificationGenerationJob#setNotificationDisplayOption(OSNotificationDisplay)}
* Determines how the notification will show to the user when inside of the
* {@link ExtNotificationWillShowInForegroundHandler#notificationWillShowInForeground(ExtNotificationGenerationJob)}
* {@link AppNotificationWillShowInForegroundHandler#notificationWillShowInForeground(AppNotificationGenerationJob)}
Expand Down Expand Up @@ -134,9 +134,9 @@ boolean isNotification() {
* The enum also helps decide the type of session the user is in an is tracked in {@link OneSignal#sessionManager}
* from the {@link OSSessionManager}.
* <br/><br/>
* {@link AppEntryAction#NOTIFICATION_CLICK} will always lead a overridden {@link com.onesignal.OSSessionManager.Session#DIRECT}.
* {@link AppEntryAction#NOTIFICATION_CLICK} will always lead a overridden {@link com.onesignal.influence.domain.OSInfluenceType#DIRECT}.
* {@link AppEntryAction#APP_OPEN} on a new session notifications within the attribution window
* parameter, this will lead to a {@link com.onesignal.OSSessionManager.Session#INDIRECT}.
* parameter, this will lead to a {@link com.onesignal.influence.domain.OSInfluenceType#DIRECT}.
* <br/><br/>
* @see OneSignal#onAppFocus
* @see OneSignal#onAppLostFocus
Expand Down Expand Up @@ -366,7 +366,6 @@ public interface PostNotificationResponseHandler {
static InAppMessageClickHandler inAppMessageClickHandler;

static boolean mAutoPromptLocation;
static boolean mUnsubscribeWhenNotificationsAreDisabled = true;
// TODO: End of old mInitBuilder params

// Is the init() of OneSignal SDK finished yet
Expand Down Expand Up @@ -589,8 +588,25 @@ public static void autoPromptLocation(boolean enable) {
* the default is {@code false}
* @return the builder you called this method on
*/
public static void unsubscribeWhenNotificationsAreDisabled(boolean set) {
mUnsubscribeWhenNotificationsAreDisabled = set;
public static void unsubscribeWhenNotificationsAreDisabled(final boolean set) {
if (taskController.shouldQueueTaskForInit(OSTaskController.UNSUBSCRIBE_WHEN_NOTIFICATION_ARE_DISABLED)) {
logger.error("Waiting for remote params. " +
"Moving " + OSTaskController.UNSUBSCRIBE_WHEN_NOTIFICATION_ARE_DISABLED + " operation to a pending task queue.");
taskController.addTaskToQueue(new Runnable() {
@Override
public void run() {
logger.debug("Running " + OSTaskController.UNSUBSCRIBE_WHEN_NOTIFICATION_ARE_DISABLED + " operation from pending task queue.");
unsubscribeWhenNotificationsAreDisabled(set);
}
});
return;
}

// Already set by remote params
if (getRemoteParamController().hasUnsubscribeNotificationKey())
return;

getRemoteParamController().saveUnsubscribeWhenNotificationsAreDisabled(set);
}

/**
Expand Down Expand Up @@ -641,6 +657,7 @@ public static void setAppContext(@NonNull Context context) {
boolean wasAppContextNull = (appContext == null);
appContext = context.getApplicationContext();
setupActivityLifecycleListener(wasAppContextNull);
setupPrivacyConsent(appContext);

logger.verbose("setAppContext(context) finished, checking if appId has been set before proceeding...");
if (appId == null) {
Expand Down Expand Up @@ -778,6 +795,19 @@ private static void setupActivityLifecycleListener(boolean wasAppContextNull) {
}
}

private static void setupPrivacyConsent(Context context) {
try {
ApplicationInfo ai = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
Bundle bundle = ai.metaData;

// Read the current privacy consent setting from AndroidManifest.xml
String requireSetting = bundle.getString("com.onesignal.PrivacyConsent");
setRequiresUserPrivacyConsent("ENABLE".equalsIgnoreCase(requireSetting));
} catch (Throwable t) {
t.printStackTrace();
}
}

private static void handleAppIdChange() {
// Re-register user if the app id changed (might happen when a dev is testing)
String oldAppId = getSavedAppId();
Expand Down Expand Up @@ -1007,6 +1037,35 @@ public static boolean requiresUserPrivacyConsent() {
return appContext == null || isUserPrivacyConsentRequired() && !userProvidedPrivacyConsent();
}

/**
* This method will be replaced by remote params set
*/
public static void setRequiresUserPrivacyConsent(final boolean required) {
if (taskController.shouldQueueTaskForInit(OSTaskController.SET_REQUIRES_USER_PRIVACY_CONSENT)) {
logger.error("Waiting for remote params. " +
"Moving " + OSTaskController.SET_REQUIRES_USER_PRIVACY_CONSENT + " operation to a pending task queue.");
taskController.addTaskToQueue(new Runnable() {
@Override
public void run() {
logger.debug("Running " + OSTaskController.SET_REQUIRES_USER_PRIVACY_CONSENT + " operation from pending task queue.");
setRequiresUserPrivacyConsent(required);
}
});
return;
}

// Already set by remote params
if (getRemoteParamController().hasPrivacyConsentKey())
return;

if (requiresUserPrivacyConsent() && !required) {
OneSignal.Log(LOG_LEVEL.ERROR, "Cannot change requiresUserPrivacyConsent() from TRUE to FALSE");
return;
}

getRemoteParamController().savePrivacyConsentRequired(required);
}

static boolean shouldLogUserPrivacyConsentErrorMessageForMethodName(String methodName) {
if (requiresUserPrivacyConsent()) {
if (methodName != null)
Expand Down Expand Up @@ -2442,12 +2501,41 @@ public void run() {
OneSignalStateSynchronizer.setSubscription(enable);
}

static void setSharedLocation(boolean enable) {
/**
* This method will be replaced by remote params set
*/
public static void setLocationShared(final boolean enable) {
if (taskController.shouldQueueTaskForInit(OSTaskController.SET_LOCATION_SHARED)) {
logger.error("Waiting for remote params. " +
"Moving " + OSTaskController.SET_LOCATION_SHARED + " operation to a pending task queue.");
taskController.addTaskToQueue(new Runnable() {
@Override
public void run() {
logger.debug("Running " + OSTaskController.SET_LOCATION_SHARED + " operation from pending task queue.");
setLocationShared(enable);
}
});
return;
}

// Already set by remote params
if (getRemoteParamController().hasLocationKey())
return;

getRemoteParamController().saveLocationShared(enable);
if (!enable)
OneSignalStateSynchronizer.clearLocation();
clearLocation();
logger.debug("OneSignal is shareLocation enabled: " + enable);
}

private static void clearLocation() {
// If applicable, check if the user provided privacy consent
if (shouldLogUserPrivacyConsentErrorMessageForMethodName(OSTaskController.SET_LOCATION_SHARED))
return;

OneSignalStateSynchronizer.clearLocation();
}

/**
* Use this method to manually prompt the user for location permissions.
* This allows for geotagging so you send notifications to users based on location.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ static class Params {
boolean restoreTTLFilter;
boolean clearGroupOnSummaryClick;
boolean receiveReceiptEnabled;
boolean unsubscribeWhenNotificationsDisabled;
boolean disableGMSMissingPrompt;
boolean locationShared;
boolean requiresUserPrivacyConsent;
Boolean unsubscribeWhenNotificationsDisabled;
Boolean locationShared;
Boolean requiresUserPrivacyConsent;
InfluenceParams influenceParams;
FCMParams fcmParams;
}
Expand Down Expand Up @@ -179,10 +179,12 @@ static private void processJson(String json, final @NonNull Callback callBack) {
clearGroupOnSummaryClick = responseJson.optBoolean("clear_group_on_summary_click", true);
receiveReceiptEnabled = responseJson.optBoolean("receive_receipts_enable", false);

unsubscribeWhenNotificationsDisabled = responseJson.optBoolean(UNSUBSCRIBE_ON_NOTIFICATION_DISABLE, true);
disableGMSMissingPrompt = responseJson.optBoolean(DISABLE_GMS_MISSING_PROMPT, false);
locationShared = responseJson.optBoolean(LOCATION_SHARED, true);
requiresUserPrivacyConsent = responseJson.optBoolean(REQUIRES_USER_PRIVACY_CONSENT, false);
// Null assignation to avoid remote param override user configuration until backend is done
// TODO remove has check when backend has new remote params and user sets inside OneSignal.java were removed
unsubscribeWhenNotificationsDisabled = !responseJson.has(UNSUBSCRIBE_ON_NOTIFICATION_DISABLE) ? null : responseJson.optBoolean(UNSUBSCRIBE_ON_NOTIFICATION_DISABLE, true);
locationShared = !responseJson.has(LOCATION_SHARED) ? null : responseJson.optBoolean(LOCATION_SHARED, true);
requiresUserPrivacyConsent = !responseJson.has(REQUIRES_USER_PRIVACY_CONSENT) ? null : responseJson.optBoolean(REQUIRES_USER_PRIVACY_CONSENT, false);

influenceParams = new InfluenceParams();
// Process outcomes params
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ public static ConcurrentLinkedQueue<Runnable> OneSignal_taskQueueWaitingForInit(
}

public static boolean OneSignal_requiresUserPrivacyConsent() {
return OneSignal.isUserPrivacyConsentRequired();
return OneSignal.requiresUserPrivacyConsent();
}

public static boolean OneSignal_locationShared() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,14 @@ public static void setRemoteParamsGetHtmlResponse(JSONObject params) throws JSON
remoteParamsGetHtmlResponse = remoteParams.toString();
}

public static void setAndRemoveKeyFromRemoteParams(String key) throws JSONException {
JSONObject remoteParams = new JSONObject(REMOTE_PARAMS);
if (remoteParams.has(key)) {
remoteParams.remove(key);
}
remoteParamsGetHtmlResponse = remoteParams.toString();
}

public static void setRemoteParamsGetHtmlResponse(String response) {
remoteParamsGetHtmlResponse = response;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2761,8 +2761,8 @@ public void onFailure(JSONObject response) {}
OneSignal.removeNotificationWillShowInForegroundHandler();
threadAndTaskWait();

// Permission subscription wont return until OneSignal init is done
assertNull(OneSignal.getPermissionSubscriptionState());
// TODO change to assertNull(OneSignal.getPermissionSubscriptionState()); when privacy consent public set is removed
assertFalse(OneSignal.getPermissionSubscriptionState().getSubscriptionStatus().getSubscribed());

OneSignal.setAppId(ONESIGNAL_APP_ID);
threadAndTaskWait();
Expand Down
Loading