Merge pull request #2864 from AntennaPod/bugfix/security-ex-job-intent-service
Override JobIntentService to catch SecurityExceptions
This commit is contained in:
commit
b918b6a6d7
|
@ -0,0 +1,118 @@
|
|||
package android.support.v4.app;
|
||||
|
||||
import android.app.job.JobParameters;
|
||||
import android.app.job.JobServiceEngine;
|
||||
import android.app.job.JobWorkItem;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
public abstract class SafeJobIntentService extends JobIntentService {
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
mJobImpl = new SafeJobServiceEngineImpl(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of a safe JobServiceEngine for interaction with JobIntentService.
|
||||
*/
|
||||
@RequiresApi(26)
|
||||
static final class SafeJobServiceEngineImpl extends JobServiceEngine
|
||||
implements JobIntentService.CompatJobEngine {
|
||||
static final String TAG = "JobServiceEngineImpl";
|
||||
|
||||
static final boolean DEBUG = false;
|
||||
|
||||
final JobIntentService mService;
|
||||
final Object mLock = new Object();
|
||||
JobParameters mParams;
|
||||
|
||||
final class WrapperWorkItem implements JobIntentService.GenericWorkItem {
|
||||
final JobWorkItem mJobWork;
|
||||
|
||||
WrapperWorkItem(JobWorkItem jobWork) {
|
||||
mJobWork = jobWork;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent getIntent() {
|
||||
return mJobWork.getIntent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete() {
|
||||
synchronized (mLock) {
|
||||
if (mParams != null) {
|
||||
try {
|
||||
mParams.completeWork(mJobWork);
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG, Log.getStackTraceString(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SafeJobServiceEngineImpl(JobIntentService service) {
|
||||
super(service);
|
||||
mService = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder compatGetBinder() {
|
||||
return getBinder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStartJob(JobParameters params) {
|
||||
if (DEBUG) Log.d(TAG, "onStartJob: " + params);
|
||||
mParams = params;
|
||||
// We can now start dequeuing work!
|
||||
mService.ensureProcessorRunningLocked(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStopJob(JobParameters params) {
|
||||
if (DEBUG) Log.d(TAG, "onStartJob: " + params);
|
||||
boolean result = mService.doStopCurrentWork();
|
||||
synchronized (mLock) {
|
||||
// Once we return, the job is stopped, so its JobParameters are no
|
||||
// longer valid and we should not be doing anything with them.
|
||||
mParams = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dequeue some work.
|
||||
*/
|
||||
@Override
|
||||
public JobIntentService.GenericWorkItem dequeueWork() {
|
||||
JobWorkItem work = null;
|
||||
synchronized (mLock) {
|
||||
if (mParams == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
work = mParams.dequeueWork();
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG, Log.getStackTraceString(e));
|
||||
}
|
||||
}
|
||||
if (work != null) {
|
||||
work.getIntent().setExtrasClassLoader(mService.getClassLoader());
|
||||
return new WrapperWorkItem(work);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,8 +6,8 @@ import android.app.PendingIntent;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.JobIntentService;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.SafeJobIntentService;
|
||||
import android.support.v4.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
@ -44,7 +44,7 @@ import de.danoeh.antennapod.core.util.gui.NotificationUtils;
|
|||
* Synchronizes local subscriptions with gpodder.net service. The service should be started with ACTION_SYNC as an action argument.
|
||||
* This class also provides static methods for starting the GpodnetSyncService.
|
||||
*/
|
||||
public class GpodnetSyncService extends JobIntentService {
|
||||
public class GpodnetSyncService extends SafeJobIntentService {
|
||||
|
||||
private static final String TAG = "GpodnetSyncService";
|
||||
|
||||
|
|
|
@ -9,23 +9,24 @@ import android.content.ServiceConnection;
|
|||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.JobIntentService;
|
||||
import android.support.v4.app.SafeJobIntentService;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import de.danoeh.antennapod.core.R;
|
||||
import de.danoeh.antennapod.core.receiver.MediaButtonReceiver;
|
||||
import de.danoeh.antennapod.core.receiver.PlayerWidget;
|
||||
import de.danoeh.antennapod.core.service.playback.PlaybackService;
|
||||
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||
import de.danoeh.antennapod.core.receiver.PlayerWidget;
|
||||
|
||||
/**
|
||||
* Updates the state of the player widget
|
||||
*/
|
||||
public class PlayerWidgetJobService extends JobIntentService {
|
||||
public class PlayerWidgetJobService extends SafeJobIntentService {
|
||||
|
||||
private static final String TAG = "PlayerWidgetJobService";
|
||||
|
||||
|
|
Loading…
Reference in New Issue