summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Fietz <martin.fietz@gmail.com>2018-10-16 20:31:42 +0200
committerMartin Fietz <martin.fietz@gmail.com>2018-10-16 20:31:42 +0200
commit790dce9164e26f9553cb6b1a152ae02ea241ecab (patch)
tree2ca064716d5277d8e98d6c892cc3dff90f05bf86
parenta6377250930539fdbd183645fed60038d09345ac (diff)
downloadAntennaPod-790dce9164e26f9553cb6b1a152ae02ea241ecab.zip
Override JobIntentService to catch SecurityExceptions
-rw-r--r--core/src/main/java/android/support/v4/app/SafeJobIntentService.java118
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java7
3 files changed, 124 insertions, 5 deletions
diff --git a/core/src/main/java/android/support/v4/app/SafeJobIntentService.java b/core/src/main/java/android/support/v4/app/SafeJobIntentService.java
new file mode 100644
index 000000000..c07c409ee
--- /dev/null
+++ b/core/src/main/java/android/support/v4/app/SafeJobIntentService.java
@@ -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;
+ }
+ }
+ }
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java
index fe6e8c400..5584991ca 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java
@@ -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";
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java
index d2214cac8..6dab9a561 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java
@@ -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";