Fix crash in anomaly job service

If job has been stopped by any reason, we should cancel the background
thread, otherwise it will throw SecurityException when dequeuing from
JobParams.

This CL adds a lock to synchronize the method and stops dequeue work
if job has been canceled.

Change-Id: I7732b7f7d444a55a4b4ba6645cd2c16b6f840a6c
Merged-In: I7732b7f7d444a55a4b4ba6645cd2c16b6f840a6c
Fixes: 77968649
Test: RunSettingsRoboTests
This commit is contained in:
Lei Yu
2018-04-12 16:44:45 -07:00
parent f6e2c19fcc
commit 162c81e1d5
2 changed files with 81 additions and 16 deletions

View File

@@ -38,6 +38,7 @@ import android.os.StatsDimensionsValue;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.support.annotation.GuardedBy;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.Pair;
@@ -65,10 +66,13 @@ public class AnomalyDetectionJobService extends JobService {
static final int UID_NULL = -1;
@VisibleForTesting
static final int STATSD_UID_FILED = 1;
@VisibleForTesting
static final long MAX_DELAY_MS = TimeUnit.MINUTES.toMillis(30);
private final Object mLock = new Object();
@GuardedBy("mLock")
private boolean mIsJobCanceled = false;
public static void scheduleAnomalyDetection(Context context, Intent intent) {
final JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
final ComponentName component = new ComponentName(context,
@@ -102,14 +106,14 @@ public class AnomalyDetectionJobService extends JobService {
.getFactory(this).getMetricsFeatureProvider();
batteryUtils.initBatteryStatsHelper(batteryStatsHelper, null /* bundle */, userManager);
for (JobWorkItem item = params.dequeueWork(); item != null;
item = params.dequeueWork()) {
for (JobWorkItem item = dequeueWork(params); item != null; item = dequeueWork(params)) {
saveAnomalyToDatabase(context, batteryStatsHelper, userManager,
batteryDatabaseManager, batteryUtils, policy, powerWhitelistBackend,
contentResolver, powerUsageFeatureProvider, metricsFeatureProvider,
item.getIntent().getExtras());
completeWork(params, item);
}
jobFinished(params, false /* wantsReschedule */);
});
return true;
@@ -117,7 +121,10 @@ public class AnomalyDetectionJobService extends JobService {
@Override
public boolean onStopJob(JobParameters jobParameters) {
return false;
synchronized (mLock) {
mIsJobCanceled = true;
}
return true; // Need to reschedule
}
@VisibleForTesting
@@ -229,4 +236,26 @@ public class AnomalyDetectionJobService extends JobService {
return anomalyInfo.anomalyType
== StatsManagerConfig.AnomalyType.EXCESSIVE_BACKGROUND_SERVICE;
}
@VisibleForTesting
JobWorkItem dequeueWork(JobParameters parameters) {
synchronized (mLock) {
if (mIsJobCanceled) {
return null;
}
return parameters.dequeueWork();
}
}
@VisibleForTesting
void completeWork(JobParameters parameters, JobWorkItem item) {
synchronized (mLock) {
if (mIsJobCanceled) {
return;
}
parameters.completeWork(item);
}
}
}