Panagiotis Triantafyllou

update sdk to version 4.5.4.4

......@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
ext {
PUBLISH_GROUP_ID = 'ly.warp'
PUBLISH_VERSION = '4.5.4.3'
PUBLISH_VERSION = '4.5.4.4'
PUBLISH_ARTIFACT_ID = 'warply-android-sdk'
}
......@@ -58,9 +58,9 @@ dependencies {
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
//------------------------------ Huawei -----------------------------//
api 'com.huawei.agconnect:agconnect-core:1.6.2.300'
api 'com.huawei.hms:base:6.2.0.300'
api 'com.huawei.hms:push:6.1.0.300'
api 'com.huawei.agconnect:agconnect-core:1.6.5.300'
api 'com.huawei.hms:base:6.4.0.302'
api 'com.huawei.hms:push:6.3.0.304'
api 'com.huawei.hms:ads-identifier:3.4.39.302'
//------------------------------ SQLCipher -----------------------------//
......
......@@ -5,11 +5,8 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="com.google.android.c2dm.permission.SEND" />
<application>
<!-- For Huawei Push -->
......
......@@ -203,62 +203,6 @@ public enum Warply {
return isInitialized(false);
}
/* GCM Related methods */
public static void registerGCM(String senderId) {
INSTANCE.isInitializedOrThrow();
INSTANCE.registerGCMInternal(senderId, false);
}
/**
* Method used to register with the GCM service, this will automatically
* check if a registration is present and if not start the process.
*
* @param senderId The project ID, got from Google API Console
*/
private void registerGCMInternal(String senderId, boolean force) {
if (WarpUtils.isWaitingGCM(mContext.get())) {
WarpUtils
.log("************* WARPLY GCM Registration ********************");
WarpUtils
.log("[WARP TRace] Waiting to finish registration to GCM service.");
WarpUtils
.log("**********************************************************");
} else if ((WarpUtils.isRegisteredGCM(mContext.get()) && (WarpUtils
.getLastGCMSenderId(mContext.get()).equalsIgnoreCase(senderId)))
&& (!force)) {
WarpUtils
.log("************* WARPLY GCM Registration ********************");
WarpUtils.log("[WARP TRace] Already registered to GCM service.");
WarpUtils
.log("**********************************************************");
} else {
WarpUtils
.log("************* WARPLY GCM Registration ********************");
WarpUtils
.log("[WARP TRace] Try to register to GCM service with ID: "
+ senderId);
WarpUtils
.log("**********************************************************");
WarpConstants.GCM_SENDER_ID = senderId;
WarpUtils.setLastGCMSenderId(mContext.get(), senderId);
GCMRegistrar.register(mContext.get(), senderId);
}
}
/**
* Method used to unregister from the GCM service.
*/
public static void unregisterGCM() {
INSTANCE.isInitializedOrThrow();
GCMRegistrar.unregister(INSTANCE.mContext.get());
WarpUtils
.log("************* WARPLY GCM Registration ********************");
WarpUtils.log("[WARP TRace] Unregistered from GCM");
WarpUtils
.log("**********************************************************");
}
/* Locking methods */
private boolean acquirePostLockInternal() {
......@@ -883,6 +827,10 @@ public enum Warply {
}
private boolean hasDeviceInfoDifference(JSONObject savedDeviceInfo, JSONObject toSendDeviceInfo) {
if (savedDeviceInfo.length() != toSendDeviceInfo.length()) {
return true;
}
for (Iterator<String> iterToSend = toSendDeviceInfo.keys(); iterToSend.hasNext(); ) {
String keyToSend = iterToSend.next();
for (Iterator<String> iterSaved = savedDeviceInfo.keys(); iterSaved.hasNext(); ) {
......@@ -998,7 +946,6 @@ public enum Warply {
return;
if (lastGCMSenderId.equals(""))
return;
registerGCMInternal(lastGCMSenderId, true);
}
public void onGCMRegistrationSuccess() {
......
......@@ -189,14 +189,14 @@ public class WarpViewActivity extends WarpBaseActivity {
private void setUpPushEvents(String sessionUUID) {
WarplyAnalyticsManager.logUserEngagedPush(WarpJSONParser.createJSONObjectFromString("session_uuid", sessionUUID));
// if (WorkManager.getInstance().getWorkInfosByTag(PushEventsWorkerService.TAG).isDone() || WorkManager.getInstance().getWorkInfosByTag(PushEventsWorkerService.TAG).isCancelled()) {
// if (WorkManager.getInstance(this).getWorkInfosByTag(PushEventsWorkerService.TAG).isDone() || WorkManager.getInstance(this).getWorkInfosByTag(PushEventsWorkerService.TAG).isCancelled()) {
Constraints constraints = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
OneTimeWorkRequest sendEvent = new OneTimeWorkRequest.Builder(PushEventsClickedWorkerService.class)
.setConstraints(constraints)
.setInitialDelay(defineRandomStart(), TimeUnit.MINUTES)
.build();
WorkManager.getInstance().enqueue(sendEvent);
WorkManager.getInstance(this).enqueue(sendEvent);
// }
}
......
/*
* Copyright 2010-2013 Warply Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package ly.warp.sdk.receivers;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;
import ly.warp.sdk.services.GCMBaseIntentService;
import ly.warp.sdk.services.WarpIntentService;
import ly.warp.sdk.utils.WarpUtils;
import ly.warp.sdk.utils.WarplyProperty;
/**
* {@link BroadcastReceiver} that receives GCM messages and delivers them to an
* application-specific {@link ly.warp.sdk.services.GCMBaseIntentService} subclass.
* <p/>
* By default, the {@link ly.warp.sdk.services.GCMBaseIntentService} class belongs to the application
* main package and is named
* {@link ly.warp.sdk.utils.constants.GCMConstants#DEFAULT_INTENT_SERVICE_CLASS_NAME}. To use a new class,
* the {@link #getGCMIntentServiceClassName(Context)} must be overridden.
*/
public class GCMBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "GCMBroadcastReceiver";
@Override
public final void onReceive(Context context, Intent intent) {
Log.v(TAG, "onReceive: " + intent.getAction());
String className = getGCMIntentServiceClassName(context);
Log.v(TAG, "GCM IntentService class: " + className);
// Delegates to the application-specific intent service.
GCMBaseIntentService.runIntentInService(context, intent, className);
if (isOrderedBroadcast()) {
setResult(Activity.RESULT_OK, null /* data */, null /* extra */);
}
}
/**
* Gets the class name of the intent service that will handle GCM messages.
*/
protected String getGCMIntentServiceClassName(Context context) {
try {
String customName = WarplyProperty.getCustomPushServiceClassName(context);
if (!TextUtils.isEmpty(customName)) {
Class.forName(customName);
return customName;
}
} catch (ClassNotFoundException e) {
WarpUtils.log("No custom push service class is implemented, using the default one");
}
return WarpIntentService.class.getCanonicalName();
}
}
package ly.warp.sdk.services;
import static ly.warp.sdk.utils.constants.WarpConstants.CHANNEL_ID;
import static ly.warp.sdk.utils.constants.WarpConstants.RANDOM_MAX;
import static ly.warp.sdk.utils.constants.WarpConstants.RANDOM_MIN;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
......@@ -13,12 +17,18 @@ import android.graphics.Color;
import android.media.RingtoneManager;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.widget.RemoteViews;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.work.Constraints;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import android.text.TextUtils;
import android.widget.RemoteViews;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import org.apache.http.HttpStatus;
import org.json.JSONException;
......@@ -33,26 +43,13 @@ import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import androidx.work.Constraints;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import ly.warp.sdk.Warply;
import ly.warp.sdk.activities.WarpViewActivity;
import ly.warp.sdk.io.models.PushCampaign;
import ly.warp.sdk.utils.GCMRegistrar;
import ly.warp.sdk.utils.WarpUtils;
import ly.warp.sdk.utils.WarplyProperty;
import ly.warp.sdk.utils.managers.WarplyAnalyticsManager;
import static ly.warp.sdk.utils.constants.WarpConstants.CHANNEL_ID;
import static ly.warp.sdk.utils.constants.WarpConstants.RANDOM_MAX;
import static ly.warp.sdk.utils.constants.WarpConstants.RANDOM_MIN;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
/**
* Created by Panagiotis Triantafyllou on 14-Feb-19.
*/
......@@ -97,7 +94,6 @@ public class FCMBaseMessagingService extends FirebaseMessagingService {
@Override
public void onNewToken(@NonNull String s) {
super.onNewToken(s);
GCMRegistrar.setRegistrationId(this, s);
WarpUtils.setDeviceToken(this, s);
}
......@@ -132,14 +128,14 @@ public class FCMBaseMessagingService extends FirebaseMessagingService {
Warply.getInitializer(this).init();
WarplyAnalyticsManager.logUserReceivedPush(pc);
// if (WorkManager.getInstance().getWorkInfosByTag(PushEventsWorkerService.TAG).isDone() || WorkManager.getInstance().getWorkInfosByTag(PushEventsWorkerService.TAG).isCancelled()) {
// if (WorkManager.getInstance(this).getWorkInfosByTag(PushEventsWorkerService.TAG).isDone() || WorkManager.getInstance(this).getWorkInfosByTag(PushEventsWorkerService.TAG).isCancelled()) {
Constraints constraints = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
OneTimeWorkRequest sendEvent = new OneTimeWorkRequest.Builder(PushEventsWorkerService.class)
.setConstraints(constraints)
.setInitialDelay(defineRandomStart(), TimeUnit.MINUTES)
.build();
WorkManager.getInstance().enqueue(sendEvent);
WorkManager.getInstance(this).enqueue(sendEvent);
// }
}
......
/*
* Copyright 2010-2013 Warply Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package ly.warp.sdk.services;
import android.app.AlarmManager;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.PowerManager;
import android.os.SystemClock;
import androidx.core.app.NotificationCompat;
import android.util.Log;
import java.security.SecureRandom;
import java.util.concurrent.TimeUnit;
import ly.warp.sdk.utils.GCMRegistrar;
import ly.warp.sdk.utils.WarpUtils;
import ly.warp.sdk.utils.constants.GCMConstants;
import static androidx.core.app.NotificationCompat.PRIORITY_DEFAULT;
import static ly.warp.sdk.utils.constants.WarpConstants.CHANNEL_ID;
/**
* Skeleton for application-specific {@link IntentService}s responsible for
* handling communication from Google Cloud Messaging service.
* <p/>
* The abstract methods in this class are called from its worker thread, and
* hence should run in a limited amount of time. If they execute long
* operations, they should spawn new threads, otherwise the worker thread will
* be blocked.
*/
public abstract class GCMBaseIntentService extends IntentService {
public static final String TAG = "GCMBaseIntentService";
// wakelock
private static final String WAKELOCK_KEY = "GCM_LIB";
private static PowerManager.WakeLock sWakeLock;
// Java lock used to synchronize access to sWakelock
private static final Object LOCK = GCMBaseIntentService.class;
private final String mSenderId;
// instance counter
private static int sCounter = 0;
private static final SecureRandom sRandom = new SecureRandom();
private static final int MAX_BACKOFF_MS = (int) TimeUnit.SECONDS
.toMillis(3600); // 1 hour
// token used to check intent origin
private static final String TOKEN = Long.toBinaryString(sRandom.nextLong());
private static final String EXTRA_TOKEN = "token";
/**
* Subclasses must create a public no-arg constructor and pass the sender id
* to be used for registration.
*/
protected GCMBaseIntentService(String senderId) {
// name is used as base name for threads, etc.
super("GCMIntentService-" + senderId + "-" + (++sCounter));
mSenderId = senderId;
}
/**
* Called when a cloud message has been received.
*
* @param context application's context.
* @param intent intent containing the message payload as extras.
*/
protected abstract void onMessage(Context context, Intent intent);
/**
* Called when the GCM server tells pending messages have been deleted
* because the device was idle.
*
* @param context application's context.
* @param total total number of collapsed messages
*/
protected void onDeletedMessages(Context context, int total) {
}
/**
* Called on a registration error that could be retried.
* <p/>
* <p/>
* By default, it does nothing and returns {@literal true}, but could be
* overridden to change that behavior and/or display the error.
*
* @param context application's context.
* @param errorId error id returned by the GCM service.
* @return if {@literal true}, failed operation will be retried (using
* exponential backoff).
*/
protected boolean onRecoverableError(Context context, String errorId) {
return true;
}
/**
* Called on registration or unregistration error.
*
* @param context application's context.
* @param errorId error id returned by the GCM service.
*/
protected abstract void onError(Context context, String errorId);
/**
* Called after a device has been registered.
*
* @param context application's context.
* @param registrationId the registration id returned by the GCM service.
*/
protected abstract void onRegistered(Context context, String registrationId);
/**
* Called after a device has been unregistered.
*
* @param registrationId the registration id that was previously registered.
* @param context application's context.
*/
protected abstract void onUnregistered(Context context,
String registrationId);
@Override
public void onHandleIntent(Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startForeground(1, /*new Notification()*/ getNotification() );
try {
Context context = getApplicationContext();
if (intent != null) {
String action = intent.getAction();
if (action != null) {
if (action.equals(GCMConstants.INTENT_FROM_GCM_REGISTRATION_CALLBACK)) {
handleRegistration(context, intent);
} else if (action.equals(GCMConstants.INTENT_FROM_GCM_MESSAGE)) {
// checks for special messages
String messageType = intent
.getStringExtra(GCMConstants.EXTRA_SPECIAL_MESSAGE);
if (messageType != null) {
if (messageType.equals(GCMConstants.VALUE_DELETED_MESSAGES)) {
String sTotal = intent
.getStringExtra(GCMConstants.EXTRA_TOTAL_DELETED);
if (sTotal != null) {
try {
int total = Integer.parseInt(sTotal);
Log.v(TAG, "Received deleted messages "
+ "notification: " + total);
onDeletedMessages(context, total);
} catch (NumberFormatException e) {
Log.e(TAG,
"GCM returned invalid number of "
+ "deleted messages: "
+ sTotal);
}
}
} else {
// application is not using the latest GCM
// library
Log.e(TAG, "Received unknown special message: "
+ messageType);
}
} else {
onMessage(context, intent);
}
} else if (action.equals(GCMConstants.INTENT_FROM_GCM_LIBRARY_RETRY)) {
String token = intent.getStringExtra(EXTRA_TOKEN);
if (!TOKEN.equals(token)) {
// make sure intent was generated by this class, not
// by
// a
// malicious app.
Log.e(TAG, "Received invalid token: " + token);
return;
}
// retry last call
if (GCMRegistrar.isRegistered(context)) {
GCMRegistrar.internalUnregister(context);
} else {
GCMRegistrar.internalRegister(context, mSenderId);
}
}
}
}
} finally {
// Release the power lock, so phone can get back to sleep.
// The lock is reference-counted by default, so multiple
// messages are ok.
// If onMessage() needs to spawn a thread or do something else,
// it should use its own lock.
synchronized (LOCK) {
// sanity check for null as this is a public method
if (sWakeLock != null) {
Log.v(TAG, "Releasing wakelock");
sWakeLock.release();
} else {
// should never happen during normal workflow
Log.e(TAG, "Wakelock reference is null");
}
}
}
}
/**
* Called from the broadcast receiver.
* <p/>
* Will process the received intent, call handleMessage(), registered(),
* etc. in background threads, with a wake lock, while keeping the service
* alive.
*/
public static void runIntentInService(Context context, Intent intent, String className) {
synchronized (LOCK) {
if (sWakeLock == null) {
// This is called from BroadcastReceiver, there is no init.
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
sWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE,
WAKELOCK_KEY);
}
}
Log.v(TAG, "Acquiring wakelock");
sWakeLock.acquire(10 * 60 * 1000L /*10 minutes*/);
intent.setClassName(context, className);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
}
private void handleRegistration(final Context context, Intent intent) {
String registrationId = intent.getStringExtra(GCMConstants.EXTRA_REGISTRATION_ID);
String error = intent.getStringExtra(GCMConstants.EXTRA_ERROR);
String unregistered = intent.getStringExtra(GCMConstants.EXTRA_UNREGISTERED);
WarpUtils.log("handleRegistration: registrationId = " + registrationId
+ ", error = " + error + ", unregistered = " + unregistered);
// Registration succeeded
if (registrationId != null) {
GCMRegistrar.resetBackoff(context);
GCMRegistrar.setRegistrationId(context, registrationId);
onRegistered(context, registrationId);
WarpUtils
.log("************* WARPLY GCM Registration ********************");
WarpUtils
.log("[WARP Trace] Sucessfuly registered to GCM service with ID: "
+ registrationId);
WarpUtils
.log("**********************************************************");
return;
}
// Deregister succeeded
if (unregistered != null) {
// Remember we are unregistered
GCMRegistrar.resetBackoff(context);
String oldRegistrationId = GCMRegistrar
.clearRegistrationId(context);
onUnregistered(context, oldRegistrationId);
WarpUtils
.log("************* WARPLY GCM Registration ********************");
WarpUtils
.log("[WARP Trace] Sucessfuly unregistered from GCM service: "
+ unregistered);
WarpUtils
.log("**********************************************************");
return;
}
// Registration failed
if (GCMConstants.ERROR_SERVICE_NOT_AVAILABLE.equals(error)) {
boolean retry = onRecoverableError(context, error);
if (retry) {
int backoffTimeMs = GCMRegistrar.getBackoff(context);
int nextAttempt = backoffTimeMs / 2
+ sRandom.nextInt(backoffTimeMs);
if (backoffTimeMs >= MAX_BACKOFF_MS) {
GCMRegistrar.setBackoff(context, MAX_BACKOFF_MS);
}
WarpUtils
.log("************* WARPLY GCM Registration ********************");
WarpUtils
.log("[WARP Trace] Retry to register with GCM serivce in"
+ nextAttempt
+ " msec"
+ " as failed with error: " + error);
WarpUtils
.log("**********************************************************");
Intent retryIntent = new Intent(GCMConstants.INTENT_FROM_GCM_LIBRARY_RETRY);
retryIntent.putExtra(EXTRA_TOKEN, TOKEN);
PendingIntent retryPendingIntent = PendingIntent.getBroadcast(
context, 0, retryIntent, 0);
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + nextAttempt,
retryPendingIntent);
}
} else {
// Unrecoverable error, notify app
WarpUtils
.log("************* WARPLY GCM Registration ********************");
WarpUtils
.log("[WARP Trace] Failed to register at GCM serivce with error: "
+ error);
WarpUtils
.log("**********************************************************");
onError(context, error);
}
}
/**
* Created by Panagiotis Triantafyllou on 29-10-2018
* Custom fix for 8.1 and up
*/
private Notification getNotification() {
String channel;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
channel = CHANNEL_ID;
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel mChannel = new NotificationChannel(channel, "notification_channel", NotificationManager.IMPORTANCE_NONE);
if (mNotificationManager != null)
mNotificationManager.createNotificationChannel(mChannel);
} else {
channel = "";
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, channel);
Notification notification = mBuilder
.setPriority(PRIORITY_DEFAULT)
.build();
return notification;
}
}
package ly.warp.sdk.services;
import static ly.warp.sdk.utils.constants.WarpConstants.CHANNEL_ID;
import static ly.warp.sdk.utils.constants.WarpConstants.RANDOM_MAX;
import static ly.warp.sdk.utils.constants.WarpConstants.RANDOM_MIN;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
......@@ -41,15 +45,10 @@ import java.util.concurrent.TimeUnit;
import ly.warp.sdk.Warply;
import ly.warp.sdk.activities.WarpViewActivity;
import ly.warp.sdk.io.models.PushCampaign;
import ly.warp.sdk.utils.GCMRegistrar;
import ly.warp.sdk.utils.WarpUtils;
import ly.warp.sdk.utils.WarplyProperty;
import ly.warp.sdk.utils.managers.WarplyAnalyticsManager;
import static ly.warp.sdk.utils.constants.WarpConstants.CHANNEL_ID;
import static ly.warp.sdk.utils.constants.WarpConstants.RANDOM_MAX;
import static ly.warp.sdk.utils.constants.WarpConstants.RANDOM_MIN;
/**
* Created by Panagiotis Triantafyllou on 17-June-21.
*/
......@@ -133,7 +132,6 @@ public class HMSBaseMessagingService extends HmsMessageService {
@Override
public void onNewToken(String s, Bundle bundle) {
super.onNewToken(s, bundle);
GCMRegistrar.setRegistrationId(this, s);
WarpUtils.setDeviceToken(this, s);
}
......@@ -177,14 +175,14 @@ public class HMSBaseMessagingService extends HmsMessageService {
Warply.getInitializer(this).init();
WarplyAnalyticsManager.logUserReceivedPush(pc);
// if (WorkManager.getInstance().getWorkInfosByTag(PushEventsWorkerService.TAG).isDone() || WorkManager.getInstance().getWorkInfosByTag(PushEventsWorkerService.TAG).isCancelled()) {
// if (WorkManager.getInstance(this).getWorkInfosByTag(PushEventsWorkerService.TAG).isDone() || WorkManager.getInstance(this).getWorkInfosByTag(PushEventsWorkerService.TAG).isCancelled()) {
Constraints constraints = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
OneTimeWorkRequest sendEvent = new OneTimeWorkRequest.Builder(PushEventsWorkerService.class)
.setConstraints(constraints)
.setInitialDelay(defineRandomStart(), TimeUnit.MINUTES)
.build();
WorkManager.getInstance().enqueue(sendEvent);
WorkManager.getInstance(this).enqueue(sendEvent);
// }
}
......
/*
* Copyright 2010-2013 Warply Ltd. All rights reserved.
*
*
* Redistribution and use in source and binary forms, without modification, are
* permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
......@@ -25,6 +25,9 @@
package ly.warp.sdk.services;
import static ly.warp.sdk.utils.constants.WarpConstants.CHANNEL_ID;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
......@@ -38,10 +41,11 @@ import android.graphics.Color;
import android.media.RingtoneManager;
import android.os.Build;
import android.os.Bundle;
import androidx.core.app.NotificationCompat;
import android.text.TextUtils;
import android.widget.RemoteViews;
import androidx.core.app.NotificationCompat;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
......@@ -55,16 +59,12 @@ import java.io.InputStream;
import java.security.SecureRandom;
import java.util.List;
import ly.warp.sdk.Warply;
import ly.warp.sdk.activities.WarpViewActivity;
import ly.warp.sdk.io.models.PushCampaign;
import ly.warp.sdk.utils.WarpUtils;
import ly.warp.sdk.utils.WarplyProperty;
import ly.warp.sdk.utils.constants.WarpConstants;
import static ly.warp.sdk.utils.constants.WarpConstants.CHANNEL_ID;
public abstract class WarpBaseIntentService extends GCMBaseIntentService {
public abstract class WarpBaseIntentService extends IntentService {
private static final String KEY_TITLE = "alert";
private static final String KEY_SUBTITLE = "subtitle";
......@@ -72,65 +72,8 @@ public abstract class WarpBaseIntentService extends GCMBaseIntentService {
private static final String KEY_MESSAGE = "message";
private static final String KEY_PAYLOAD = "payload";
public WarpBaseIntentService() {
super(WarpConstants.GCM_SENDER_ID);
}
protected WarpBaseIntentService(String senderId) {
super(senderId);
}
public abstract void onPushReceived(Context context, int action, Bundle data);
@Override
protected void onMessage(Context context, Intent intent) {
Bundle data = intent.getExtras();
if (data == null || !data.containsKey("loyalty-action"))
return;
PushCampaign pc = new PushCampaign(data);
Warply.getInitializer(context).init();
// WarplyAnalyticsManager.logUserReceivedPush(pc.getSessionUUID());
WarpUtils.log("Received push with action: " + pc.getAction());
if (pc.getAction() == 0 && !pc.hasActions())
showCampaignNotification(context, pc);
else
onPushReceived(context, pc.getAction(), data);
}
@Override
protected void onError(Context context, String errorId) {
int errorCode = -1;
try {
errorCode = Integer.valueOf(errorId);
} catch (NumberFormatException e) {
WarpUtils.warn("[Warp Trace] Error id is not a number", e);
}
Warply.getInitializer(context).init();
Warply.INSTANCE.onGCMRegistrationFail(errorCode);
}
@Override
protected void onRegistered(Context context, String registrationId) {
WarpUtils.log("Registration to GCM successful");
/*
* Initialize Warply only if it is not initialized. This is to make sure
* device info are not sent in check (called in init) and then resent
* using the reset (called in onGCMRegistrationSuccess)
*/
if (!Warply.isInitialized())
Warply.getInitializer(context).init();
Warply.INSTANCE.onGCMRegistrationSuccess();
}
@Override
protected void onUnregistered(Context context, String registrationId) {
WarpUtils.log("Unregistration from GCM successful");
Warply.getInitializer(context).init();
if (WarpUtils.getIsDEVICEINFOENABLED(context))
Warply.INSTANCE.postDeviceInfoData();
Warply.INSTANCE.onGCMUnregistrationSuccess();
super("WarpBaseIntentService");
}
public static void showCampaignNotification(Context context, PushCampaign pc) {
......
/*
* Copyright 2010-2013 Warply Ltd. All rights reserved.
*
*
* Redistribution and use in source and binary forms, without modification, are
* permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
......@@ -33,7 +33,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
......@@ -54,12 +54,7 @@ public class WarpInAppNotificationService extends WarpBaseIntentService {
public WarpInAppNotificationService() {
super("WarpInAppNotificationService");
}
@Override
public void onPushReceived(Context context, int action, Bundle data) {
super();
}
@Override
......
/*
* Copyright 2010-2013 Warply Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package ly.warp.sdk.services;
import android.content.Context;
import android.os.Bundle;
public class WarpIntentService extends WarpBaseIntentService {
@Override
public void onPushReceived(Context context, int action, Bundle data) {
showDefaultNotification(context, data);
}
}
/*
* Copyright 2010-2013 Warply Ltd. All rights reserved.
*
*
* Redistribution and use in source and binary forms, without modification, are
* permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
......@@ -25,7 +25,6 @@
package ly.warp.sdk.utils;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
......@@ -44,7 +43,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import ly.warp.sdk.receivers.GCMBroadcastReceiver;
import ly.warp.sdk.utils.constants.GCMConstants;
......@@ -66,15 +64,6 @@ public final class GCMRegistrar {
private static final String PROPERTY_ON_SERVER = "onServer";
/**
* {@link GCMBroadcastReceiver} instance used to handle the retry intent.
* <p/>
* <p/>
* This instance cannot be the same as the one defined in the manifest
* because it needs a different permission.
*/
private static GCMBroadcastReceiver sRetryReceiver;
/**
* Checks if the device has the proper dependencies installed.
* <p/>
* This method should be called when the application starts to verify that
......@@ -214,29 +203,6 @@ public final class GCMRegistrar {
// internalRegister(context, senderIds);
}
public static void internalRegister(Context context, String... senderIds) {
if (senderIds == null || senderIds.length == 0) {
throw new IllegalArgumentException("No senderIds");
}
StringBuilder builder = new StringBuilder(senderIds[0]);
for (int i = 1; i < senderIds.length; i++) {
builder.append(',').append(senderIds[i]);
}
String senders = builder.toString();
Log.v(TAG, "Registering app " + context.getPackageName()
+ " of senders " + senders);
Intent intent = new Intent(GCMConstants.INTENT_TO_GCM_REGISTRATION);
intent.setPackage(GSF_PACKAGE);
intent.putExtra(GCMConstants.EXTRA_APPLICATION_PENDING_INTENT,
PendingIntent.getBroadcast(context, 0, new Intent(), 0));
intent.putExtra(GCMConstants.EXTRA_SENDER, senders);
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// context.startForegroundService(intent);
// } else {
context.startService(intent);
// }
}
/**
* Unregister the application.
* <p/>
......@@ -245,60 +211,7 @@ public final class GCMRegistrar {
* {@link GCMConstants#EXTRA_UNREGISTERED} extra.
*/
public static void unregister(Context context) {
setRetryBroadcastReceiver(context);
GCMRegistrar.resetBackoff(context);
internalUnregister(context);
}
/**
* Clear internal resources.
* <p/>
* <p/>
* This method should be called by the main activity's {@code onDestroy()}
* method.
*/
public static synchronized void onDestroy(Context context) {
if (sRetryReceiver != null) {
Log.v(TAG, "Unregistering receiver");
context.unregisterReceiver(sRetryReceiver);
sRetryReceiver = null;
}
}
public static void internalUnregister(Context context) {
Log.v(TAG, "Unregistering app " + context.getPackageName());
Intent intent = new Intent(GCMConstants.INTENT_TO_GCM_UNREGISTRATION);
intent.setPackage(GSF_PACKAGE);
intent.putExtra(GCMConstants.EXTRA_APPLICATION_PENDING_INTENT,
PendingIntent.getBroadcast(context, 0, new Intent(), 0));
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// context.startForegroundService(intent);
// } else {
context.startService(intent);
// }
}
/**
* Lazy initializes the {@link GCMBroadcastReceiver} instance.
*/
private static synchronized void setRetryBroadcastReceiver(Context context) {
if (sRetryReceiver == null) {
sRetryReceiver = new GCMBroadcastReceiver();
String category = context.getPackageName();
IntentFilter filter = new IntentFilter(
GCMConstants.INTENT_FROM_GCM_LIBRARY_RETRY);
filter.addCategory(category);
// must use a permission that is defined on manifest for sure
String permission = category + ".permission.C2D_MESSAGE";
Log.v(TAG, "Registering receiver");
// context.registerReceiver(sRetryReceiver, filter, permission, null);
if (Build.VERSION.SDK_INT >= 27) {
context.sendBroadcast(new Intent(context, GCMBroadcastReceiver.class)
.setAction(GCMConstants.INTENT_FROM_GCM_REGISTRATION_CALLBACK));
} else {
context.registerReceiver(sRetryReceiver, filter, permission, null);
}
}
}
/**
......
......@@ -141,16 +141,6 @@ public class WarpUtils {
return GCMRegistrar.getRegistrationId(context);
}
/**
* Method used return whether this device is registered with GCM or not
*
* @return True or False
*/
public static boolean isRegisteredGCM(Context context) {
return GCMRegistrar.isRegistered(context);
}
public static void setRegistrationGCM(Context context, String registrationGCM) {
SharedPreferences.Editor editor = getPreferences(context).edit();
......@@ -180,11 +170,6 @@ public class WarpUtils {
editor.apply();
}
static boolean isRegisteredGCMOrWaiting(Context context) {
return isRegisteredGCM(context) || isWaitingGCM(context);
}
public static boolean isRegisteredWarply(Context context) {
return !("".equalsIgnoreCase(getWebId(context)));
}
......
......@@ -80,6 +80,7 @@ public class WarplyDeviceInfoCollector {
adInfo.isLimitAdTrackingEnabled() : "");
jObj.putOpt("unique_device_id", getUniqueDeviceId());
jObj.putOpt("os_version", getOsVersion());
jObj.putOpt("app_version", getAppVersion());
} catch (JSONException e) {
WarpUtils.log("************* WARPLY Warning ********************");
WarpUtils.log("Problem when creating Device Info JSON", e);
......@@ -106,6 +107,7 @@ public class WarplyDeviceInfoCollector {
jObj.putOpt("advertising_id", info != null ? info.getId() : "");
jObj.putOpt("unique_device_id", getUniqueDeviceId());
jObj.putOpt("os_version", getOsVersion());
jObj.putOpt("app_version", getAppVersion());
//jObj.putOpt("opt_out_of_interest_based_ads_enabled", info != null ?
//info.isLimitAdTrackingEnabled() : "");
} catch (JSONException | IOException e) {
......@@ -137,6 +139,7 @@ public class WarplyDeviceInfoCollector {
jObj.putOpt("platform", "android");
jObj.putOpt("os_version", getOsVersion());
jObj.putOpt("vendor", "google");
jObj.putOpt("app_version", getAppVersion());
} catch (JSONException e) {
WarpUtils.log("************* WARPLY Warning ********************");
WarpUtils.log("Problem when creating Device Info JSON", e);
......@@ -154,6 +157,7 @@ public class WarplyDeviceInfoCollector {
jObj.putOpt("platform", "android");
jObj.putOpt("os_version", getOsVersion());
jObj.putOpt("vendor", "huawei");
jObj.putOpt("app_version", getAppVersion());
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
......@@ -204,9 +208,23 @@ public class WarplyDeviceInfoCollector {
}
private String getRegistrationGCM() {
if (!TextUtils.isEmpty(WarpUtils.getDeviceToken(mContext)))
return WarpUtils.getDeviceToken(mContext);
WarpUtils.setDeviceToken(mContext, WarpUtils.getRegistrationGCM(mContext));
return WarpUtils.getRegistrationGCM(mContext);
}
private String getAppVersion() {
try {
PackageInfo pInfo = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
return pInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return "";
}
}
private String getHardwareId() {
return (Build.SERIAL == null ||
Build.SERIAL.equals(android.os.Build.UNKNOWN)) ? "" : Build.SERIAL;
......
......@@ -30,7 +30,7 @@ public class WarpConstants {
/**
* The version of the SDK installed in the device
*/
public static final String SDK_VERSION = "4.5.4.3";
public static final String SDK_VERSION = "4.5.4.4";
/**
* The URL of the server where it should ping
......