Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2022, Leanplum, Inc. All rights reserved.
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.leanplum.internal;
import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
import com.leanplum.ActionContext.ContextualValues;
import com.leanplum.Leanplum;
import com.leanplum.LocationManager;
import com.leanplum.actions.internal.Action;
import com.leanplum.actions.internal.ActionManagerExecutionKt;
import com.leanplum.actions.internal.ActionQueue;
import com.leanplum.actions.internal.ActionScheduler;
import com.leanplum.actions.internal.Definitions;
import com.leanplum.actions.MessageDisplayController;
import com.leanplum.actions.MessageDisplayListener;
import com.leanplum.internal.Constants.Defaults;
import com.leanplum.utils.SharedPreferencesUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Handles in-app and push messaging.
*
* @author Andrew First
*/
public class ActionManager {
private static final long HOUR_MILLIS = 60 * 60 * 1000;
private static final long DAY_MILLIS = 24 * HOUR_MILLIS;
private static final long WEEK_MILLIS = 7 * DAY_MILLIS;
private final Map> messageImpressionOccurrences = new HashMap<>();
private final Map messageTriggerOccurrences = new HashMap<>();
private final Map sessionOccurrences = new HashMap<>();
private MessageDisplayListener messageDisplayListener;
private MessageDisplayController messageDisplayController;
private ActionScheduler scheduler = new ActionScheduler();
private boolean enabled = true; // when manager is disabled it will stop adding actions in queue
private boolean paused = true; // variable used when fetching chained action, paused until Activity is presented
private final ActionQueue queue = new ActionQueue();
private final ActionQueue delayedQueue = new ActionQueue();
private final Definitions definitions = new Definitions();
private volatile Action currentAction;
private boolean dismissOnPushOpened = true;
private boolean continueOnActivityResumed = true;
private static ActionManager instance;
public static final String PUSH_NOTIFICATION_ACTION_NAME = "__Push Notification";
public static final String HELD_BACK_ACTION_NAME = "__held_back";
private static LocationManager locationManager;
private static boolean loggedLocationManagerFailure = false;
public static class MessageMatchResult {
public boolean matchedTrigger;
public boolean matchedUnlessTrigger;
public boolean matchedLimit;
public boolean matchedActivePeriod;
}
public static synchronized ActionManager getInstance() {
if (instance == null) {
instance = new ActionManager();
}
return instance;
}
public static synchronized LocationManager getLocationManager() {
if (locationManager != null) {
return locationManager;
}
if (Util.hasPlayServices()) {
try {
// Reflection here prevents linker errors
// if Google Play Services is not used in the client app.
locationManager = (LocationManager) Class
.forName("com.leanplum.LocationManagerImplementation")
.getMethod("instance").invoke(null);
return locationManager;
} catch (Throwable t) {
if (!loggedLocationManagerFailure) {
Log.i("Geofencing support requires leanplum-location module and Google Play " +
"Services v8.1 and higher.\n" +
"Add this to your build.gradle file:\n" +
"implementation 'com.google.android.gms:play-services-location:8.3.0+'\n" +
"implementation 'com.leanplum:leanplum-location:+'");
loggedLocationManagerFailure = true;
}
}
}
return null;
}
private ActionManager() {
}
public Map getMessageImpressionOccurrences(String messageId) {
Map occurrences = messageImpressionOccurrences.get(messageId);
if (occurrences != null) {
return occurrences;
}
Context context = Leanplum.getContext();
SharedPreferences preferences = context.getSharedPreferences(
Defaults.MESSAGING_PREF_NAME, Context.MODE_PRIVATE);
String savedValue = preferences.getString(
String.format(Constants.Defaults.MESSAGE_IMPRESSION_OCCURRENCES_KEY, messageId),
"{}");
occurrences = CollectionUtil.uncheckedCast(JsonConverter.fromJson(savedValue));
messageImpressionOccurrences.put(messageId, occurrences);
return occurrences;
}
public void saveMessageImpressionOccurrences(Map occurrences, String messageId) {
Context context = Leanplum.getContext();
SharedPreferences preferences = context.getSharedPreferences(
Defaults.MESSAGING_PREF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(
String.format(Constants.Defaults.MESSAGE_IMPRESSION_OCCURRENCES_KEY, messageId),
JsonConverter.toJson(occurrences));
messageImpressionOccurrences.put(messageId, occurrences);
SharedPreferencesUtil.commitChanges(editor);
}
public int getMessageTriggerOccurrences(String messageId) {
Number occurrences = messageTriggerOccurrences.get(messageId);
if (occurrences != null) {
return occurrences.intValue();
}
Context context = Leanplum.getContext();
SharedPreferences preferences = context.getSharedPreferences(
Defaults.MESSAGING_PREF_NAME, Context.MODE_PRIVATE);
int savedValue = preferences.getInt(
String.format(Constants.Defaults.MESSAGE_TRIGGER_OCCURRENCES_KEY, messageId), 0);
messageTriggerOccurrences.put(messageId, savedValue);
return savedValue;
}
public void saveMessageTriggerOccurrences(int occurrences, String messageId) {
Context context = Leanplum.getContext();
SharedPreferences preferences = context.getSharedPreferences(
Defaults.MESSAGING_PREF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt(
String.format(Constants.Defaults.MESSAGE_TRIGGER_OCCURRENCES_KEY, messageId), occurrences);
messageTriggerOccurrences.put(messageId, occurrences);
SharedPreferencesUtil.commitChanges(editor);
}
public MessageMatchResult shouldShowMessage(String messageId, Map messageConfig,
String when, String eventName, ContextualValues contextualValues) {
MessageMatchResult result = new MessageMatchResult();
// 1. Must not be muted.
Context context = Leanplum.getContext();
SharedPreferences preferences = context.getSharedPreferences(
Defaults.MESSAGING_PREF_NAME, Context.MODE_PRIVATE);
if (preferences.getBoolean(
String.format(Constants.Defaults.MESSAGE_MUTED_KEY, messageId), false)) {
return result;
}
// 2. Must match at least one trigger.
result.matchedTrigger = matchedTriggers(messageConfig.get("whenTriggers"), when, eventName,
contextualValues);
result.matchedUnlessTrigger =
matchedTriggers(messageConfig.get("unlessTriggers"), when, eventName, contextualValues);
if (!result.matchedTrigger && !result.matchedUnlessTrigger) {
return result;
}
// 3. Must match all limit conditions.
Object limitConfigObj = messageConfig.get("whenLimits");
Map limitConfig = null;
if (limitConfigObj instanceof Map, ?>) {
limitConfig = CollectionUtil.uncheckedCast(limitConfigObj);
}
result.matchedLimit = matchesLimits(messageId, limitConfig);
// 4. Must be within active period.
Object messageStartTime = messageConfig.get("startTime");
Object messageEndTime = messageConfig.get("endTime");
if (messageStartTime == null || messageEndTime == null) {
result.matchedActivePeriod = true;
} else {
long currentTime = Clock.getInstance().newDate().getTime();
result.matchedActivePeriod = currentTime >= (long) messageStartTime &&
currentTime <= (long) messageEndTime;
}
return result;
}
private boolean matchesLimits(String messageId, Map limitConfig) {
if (limitConfig == null) {
return true;
}
List