Skip to content

Commit

Permalink
Changes for one shot and periodic update base on Job scheduler.
Browse files Browse the repository at this point in the history
Deprecating function in Media API
Minor business logic changes in AppStatemanager
Removing featrue flag on ConfigManager for platform consistency
  • Loading branch information
markvdouw committed Nov 27, 2023
1 parent 522d919 commit 910b714
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.mparticle.JobSchedulerUtilsKt;
import com.mparticle.MPEvent;
import com.mparticle.MParticle;
import com.mparticle.SchedulingBatchingType;
import com.mparticle.identity.IdentityApi;
import com.mparticle.identity.IdentityApiRequest;
import com.mparticle.identity.MParticleUser;
Expand Down Expand Up @@ -377,13 +378,11 @@ private void logBackgrounded() {
}

private void scheduleBackgroundJob() {
if (mConfigManager.isBackgroundEventBatchingEnabled()) {
JobSchedulerUtilsKt.scheduleBatchUploading(this.mContext, delay -> {
mMessageManager.mUploadHandler.sendMessageDelayed(mMessageManager.mUploadHandler.obtainMessage(UploadHandler.UPLOAD_TRIGGER_MESSAGES, 1, 0, mConfigManager.getMpid()), delay);
Logger.debug("Legacy action with delay: " + delay);
return Unit.INSTANCE;
});
}
JobSchedulerUtilsKt.scheduleBatchUploading(this.mContext, mConfigManager.getUploadInterval(), SchedulingBatchingType.ONE_SHOOT, true, delay -> {
mMessageManager.mUploadHandler.sendMessageDelayed(mMessageManager.mUploadHandler.obtainMessage(UploadHandler.UPLOAD_TRIGGER_MESSAGES, 1, 0, mConfigManager.getMpid()), delay);
Logger.debug("Legacy action with delay: " + delay);
return Unit.INSTANCE;
});
}

@TargetApi(14)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ public class ConfigManager {
private JSONObject mProviderPersistence;
private int mRampValue = -1;
private int mUserBucket = -1;
private boolean isBackgroundEventBatchingEnabled = false;

private int mSessionTimeoutInterval = -1;
private int mUploadInterval = -1;
Expand Down Expand Up @@ -231,10 +230,6 @@ public void deleteUserStorage(long mpId) {
deleteUserStorage(mContext, mpId);
}

public boolean isBackgroundEventBatchingEnabled() {
return isBackgroundEventBatchingEnabled;
}

static void deleteConfigManager(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
context.deleteSharedPreferences(PREFERENCES_FILE);
Expand Down Expand Up @@ -413,8 +408,6 @@ private synchronized void updateCoreConfig(JSONObject responseJSON, boolean newC
}

mRampValue = responseJSON.optInt(KEY_RAMP, -1);
isBackgroundEventBatchingEnabled = responseJSON.optBoolean(ENABLE_BACKGROUND_BATCHING, false);

if (responseJSON.has(KEY_OPT_OUT)) {
mSendOoEvents = responseJSON.getBoolean(KEY_OPT_OUT);
} else {
Expand Down Expand Up @@ -929,11 +922,11 @@ public boolean shouldTrigger(BaseMPMessage message) {
isBackgroundAst = (message.getMessageType().equals(Constants.MessageType.APP_STATE_TRANSITION) && message.get(Constants.MessageKey.STATE_TRANSITION_TYPE).equals(Constants.StateTransitionType.STATE_TRANS_BG));
} catch (JSONException ex) {
}
if(isBackgroundEventBatchingEnabled && isBackgroundAst){
if (isBackgroundAst) {
return false;
}
boolean shouldTrigger = message.getMessageType().equals(Constants.MessageType.PUSH_RECEIVED)
|| message.getMessageType().equals(Constants.MessageType.COMMERCE_EVENT) || isBackgroundAst;
|| message.getMessageType().equals(Constants.MessageType.COMMERCE_EVENT);

if (!shouldTrigger && messageMatches != null && messageMatches.length() > 0) {
shouldTrigger = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -815,10 +815,8 @@ public void onFailed() {

@Override
public void endUploadLoop() {
if (!mConfigManager.isBackgroundEventBatchingEnabled()) {
mUploadHandler.removeMessages(UploadHandler.UPLOAD_MESSAGES);
MParticle.getInstance().upload();
}
mUploadHandler.removeMessages(UploadHandler.UPLOAD_MESSAGES);
MParticle.getInstance().upload();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

import androidx.annotation.Nullable;

import com.mparticle.JobSchedulerUtilsKt;
import com.mparticle.MParticle;
import com.mparticle.SchedulingBatchingType;
import com.mparticle.identity.AliasRequest;
import com.mparticle.identity.AliasResponse;
import com.mparticle.internal.database.services.MParticleDBManager;
Expand All @@ -25,6 +27,8 @@

import javax.net.ssl.SSLHandshakeException;

import kotlin.Unit;

/**
* Primary queue handler which is responsible for querying, packaging, and uploading data.
*/
Expand Down Expand Up @@ -133,10 +137,12 @@ public void handleMessageImpl(Message msg) {
break;
case UPLOAD_MESSAGES:
case UPLOAD_TRIGGER_MESSAGES:
boolean anythingToUpload = false;
long uploadInterval = mConfigManager.getUploadInterval();
if (isNetworkConnected) {
if (uploadInterval > 0 || msg.arg1 == 1) {
while (mParticleDBManager.hasMessagesForUpload()) {
anythingToUpload = true;
prepareMessageUploads(false);
}
boolean needsHistory = upload(false);
Expand All @@ -145,11 +151,19 @@ public void handleMessageImpl(Message msg) {
}
}
}

if (!mConfigManager.isBackgroundEventBatchingEnabled()) {
if (mAppStateManager.getSession().isActive() && uploadInterval > 0 && msg.arg1 == 0) {
this.sendEmptyDelayed(UPLOAD_MESSAGES, uploadInterval);
}
if (!anythingToUpload && (!mAppStateManager.getSession().isActive() || mAppStateManager.isBackgrounded())) {
//If there isn't anything to upload and is in background or inactive, cancel schedule job until a new message is stored
JobSchedulerUtilsKt.cancelScheduledUploadBatchJob(mContext);
}
if (mAppStateManager.getSession().isActive() && uploadInterval > 0 && msg.arg1 == 0) {
JobSchedulerUtilsKt.scheduleBatchUploading(mContext,
uploadInterval,
SchedulingBatchingType.PERIODIC,
true,
delay -> {
sendEmptyDelayed(UPLOAD_MESSAGES, uploadInterval);
return Unit.INSTANCE;
});
}
break;
case UPLOAD_HISTORY:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public MPMediaAPI(@Nullable Context context, @NonNull MediaCallbacks callbacks)
*
* @param playing Is your app currently playing music for the user.
*/
@Deprecated
public void setAudioPlaying(boolean playing) {
mAudioPlaying.set(playing);
if (playing) {
Expand All @@ -45,6 +46,7 @@ public void setAudioPlaying(boolean playing) {
}
}

@Deprecated
public boolean getAudioPlaying() {
return mAudioPlaying.get();
}
Expand Down
63 changes: 50 additions & 13 deletions android-core/src/main/kotlin/com.mparticle/JobSchedulerUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,70 @@ import com.mparticle.uploadbatching.BatchUploadingJob

const val UPLOAD_BATCH_JOB = 123

private fun Int.minutesToMillis(): Long = this * 60000L
fun Long.secondsToMillis(): Long = this * 1000
fun Long.minutesToMillis(): Long = (this * 60).secondsToMillis()

fun scheduleBatchUploading(context: Context, legacyAction: (delay: Long) -> Unit) {
val delay = 15.minutesToMillis()
enum class SchedulingBatchingType { PERIODIC, ONE_SHOOT; }

fun cancelScheduledUploadBatchJob(context: Context) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val jobScheduler = context.getJobScheduler()
val jobRunning = context.getScheduledJob(UPLOAD_BATCH_JOB)
jobRunning?.let { jobScheduler?.cancel(UPLOAD_BATCH_JOB) }
}
} catch (e: Exception) {
}
}

fun scheduleBatchUploading(
context: Context,
delayInSeconds: Long,
type: SchedulingBatchingType,
cancelPrevious: Boolean = true,
legacyAction: (delay: Long) -> Unit
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val job =
JobInfo.Builder(
try {
if (cancelPrevious) {
context.getJobScheduler()?.cancel(UPLOAD_BATCH_JOB)
}
val builder = JobInfo.Builder(
UPLOAD_BATCH_JOB,
ComponentName(context, BatchUploadingJob::class.java.name)
)
.setMinimumLatency(delay)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.build()
context.scheduleJob(job)
if (type == SchedulingBatchingType.PERIODIC) {
builder.setPeriodic(delayInSeconds.secondsToMillis())
} else if (type == SchedulingBatchingType.ONE_SHOOT) {
builder.setMinimumLatency(delayInSeconds.secondsToMillis())
}
builder.apply {
setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
}
context.scheduleJob(builder.build())
} catch (e: Exception) {
Logger.error("Error while trying to use JobSceduler for batch upload")
legacyAction.invoke(delayInSeconds.secondsToMillis())
}
} else {
legacyAction.invoke(delay)
legacyAction.invoke(delayInSeconds.secondsToMillis())
}
}

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun Context.getJobScheduler(): JobScheduler? =
this.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler?

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun Context.getScheduledJob(jobId: Int): JobInfo? =
this.getJobScheduler()?.allPendingJobs?.firstOrNull { it.id == jobId }

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun Context.scheduleJob(job: JobInfo) {
val jobScheduler = this.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler?
val jobRunning = jobScheduler?.allPendingJobs?.firstOrNull { it.id == job.id } != null
val jobRunning = this.getScheduledJob(job.id) != null
if (!jobRunning) {
//Schedule / Re-schedule the job if its not running/scheduled to run at the system service
jobScheduler?.schedule(job)
this.getJobScheduler()?.schedule(job)
} else {
Logger.debug("Trying to schedule job in uploadBatch service. Service ALREADY RUNNING")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class BatchUploadingJob : JobService() {
} ?: run {
Logger.debug("MParticle instance null while trying to call uploadBatching:upload")
}
return false
return true
}

override fun onStopJob(params: JobParameters?): Boolean = false
Expand Down

0 comments on commit 910b714

Please sign in to comment.