TaskExecutor's background executor is now SerialExecutor.

* This gives us visibility into the number of pending tasks which will
  be important in the next CL.

  There is a race condition between the SerialExecutor draining its queue
  of pending tasks and SystemAlarmDispatcher's onAllCommandsCompleted() callback.
  This is because SystemAlarmDispatcher thinks there are no more things to be
  done even though there are pending runnables in the SerialExecutor.
  This CL makes this information available. In the next CL, CommandHandler
  will check for pending runnables in the SerialExecutor queue.
  (b/138238197)

* Fixed TestWorkManagerImpl to use Configuration#getTaskExecutor().
* Updated unit tests.

Test: Updated unit tests.
Change-Id: I5f32f1e1ef2563d4598934aed3b61d62a6d6167c
diff --git a/work/workmanager-gcm/src/androidTest/java/androidx/work/impl/background/gcm/WorkManagerGcmDispatcherTest.kt b/work/workmanager-gcm/src/androidTest/java/androidx/work/impl/background/gcm/WorkManagerGcmDispatcherTest.kt
index c67dfd2..f127aba 100644
--- a/work/workmanager-gcm/src/androidTest/java/androidx/work/impl/background/gcm/WorkManagerGcmDispatcherTest.kt
+++ b/work/workmanager-gcm/src/androidTest/java/androidx/work/impl/background/gcm/WorkManagerGcmDispatcherTest.kt
@@ -25,6 +25,7 @@
 import androidx.test.filters.MediumTest
 import androidx.work.Configuration
 import androidx.work.impl.WorkManagerImpl
+import androidx.work.impl.utils.SerialExecutor
 import androidx.work.impl.utils.SynchronousExecutor
 import com.google.android.gms.gcm.GcmNetworkManager
 import com.google.android.gms.gcm.TaskParams
@@ -63,7 +64,8 @@
 
         val workTaskExecutor: androidx.work.impl.utils.taskexecutor.TaskExecutor =
             object : androidx.work.impl.utils.taskexecutor.TaskExecutor {
-                override fun postToMainThread(runnable: Runnable?) {
+                private val mSerialExecutor = SerialExecutor(mExecutor)
+                override fun postToMainThread(runnable: Runnable) {
                     mExecutor.execute(runnable)
                 }
 
@@ -71,12 +73,12 @@
                     return mExecutor
                 }
 
-                override fun executeOnBackgroundThread(runnable: Runnable?) {
-                    mExecutor.execute(runnable)
+                override fun executeOnBackgroundThread(runnable: Runnable) {
+                    mSerialExecutor.execute(runnable)
                 }
 
-                override fun getBackgroundExecutor(): Executor {
-                    return mExecutor
+                override fun getBackgroundExecutor(): SerialExecutor {
+                    return mSerialExecutor
                 }
             }
 
diff --git a/work/workmanager-ktx/src/androidTest/java/androidx/work/CoroutineWorkerTest.kt b/work/workmanager-ktx/src/androidTest/java/androidx/work/CoroutineWorkerTest.kt
index 125f4e7..301e7e1 100644
--- a/work/workmanager-ktx/src/androidTest/java/androidx/work/CoroutineWorkerTest.kt
+++ b/work/workmanager-ktx/src/androidTest/java/androidx/work/CoroutineWorkerTest.kt
@@ -25,6 +25,7 @@
 import androidx.test.filters.SmallTest
 import androidx.work.impl.WorkDatabase
 import androidx.work.impl.WorkManagerImpl
+import androidx.work.impl.utils.SerialExecutor
 import androidx.work.impl.utils.WorkProgressUpdater
 import androidx.work.impl.utils.futures.SettableFuture
 import androidx.work.impl.utils.taskexecutor.TaskExecutor
@@ -197,6 +198,7 @@
     class InstantWorkTaskExecutor : TaskExecutor {
 
         private val mSynchronousExecutor = SynchronousExecutor()
+        private val mSerialExecutor = SerialExecutor(mSynchronousExecutor)
 
         override fun postToMainThread(runnable: Runnable) {
             runnable.run()
@@ -207,11 +209,11 @@
         }
 
         override fun executeOnBackgroundThread(runnable: Runnable) {
-            runnable.run()
+            mSerialExecutor.execute(runnable)
         }
 
-        override fun getBackgroundExecutor(): Executor {
-            return mSynchronousExecutor
+        override fun getBackgroundExecutor(): SerialExecutor {
+            return mSerialExecutor
         }
     }
 
diff --git a/work/workmanager-rxjava2/src/test/java/androidx/work/RxWorkerTest.kt b/work/workmanager-rxjava2/src/test/java/androidx/work/RxWorkerTest.kt
index bf07147..2e7c0a0 100644
--- a/work/workmanager-rxjava2/src/test/java/androidx/work/RxWorkerTest.kt
+++ b/work/workmanager-rxjava2/src/test/java/androidx/work/RxWorkerTest.kt
@@ -17,6 +17,7 @@
 package androidx.work
 
 import android.content.Context
+import androidx.work.impl.utils.SerialExecutor
 import androidx.work.impl.utils.SynchronousExecutor
 import androidx.work.impl.utils.taskexecutor.TaskExecutor
 import io.reactivex.Single
@@ -140,6 +141,7 @@
     class InstantWorkTaskExecutor : TaskExecutor {
 
         private val mSynchronousExecutor = SynchronousExecutor()
+        private val mSerialExecutor = SerialExecutor(mSynchronousExecutor)
 
         override fun postToMainThread(runnable: Runnable) {
             runnable.run()
@@ -150,11 +152,11 @@
         }
 
         override fun executeOnBackgroundThread(runnable: Runnable) {
-            runnable.run()
+            mSerialExecutor.execute(runnable)
         }
 
-        override fun getBackgroundExecutor(): Executor {
-            return mSynchronousExecutor
+        override fun getBackgroundExecutor(): SerialExecutor {
+            return mSerialExecutor
         }
     }
 }
diff --git a/work/workmanager-testing/src/androidTest/java/androidx/work/testing/WorkManagerInitHelperTest.java b/work/workmanager-testing/src/androidTest/java/androidx/work/testing/WorkManagerInitHelperTest.java
index d089045..32f1a86 100644
--- a/work/workmanager-testing/src/androidTest/java/androidx/work/testing/WorkManagerInitHelperTest.java
+++ b/work/workmanager-testing/src/androidTest/java/androidx/work/testing/WorkManagerInitHelperTest.java
@@ -28,6 +28,7 @@
 import androidx.work.Configuration;
 import androidx.work.WorkManager;
 import androidx.work.impl.WorkManagerImpl;
+import androidx.work.impl.utils.SerialExecutor;
 
 import org.junit.After;
 import org.junit.Before;
@@ -60,11 +61,13 @@
     public void testWorkManagerIsInitialized() {
         Configuration configuration = new Configuration.Builder()
                 .setExecutor(mExecutor)
+                .setTaskExecutor(mExecutor)
                 .build();
 
         WorkManagerTestInitHelper.initializeTestWorkManager(mContext, configuration);
         WorkManagerImpl workManager = (WorkManagerImpl) WorkManager.getInstance(mContext);
         assertThat(workManager, is(notNullValue()));
-        assertThat(workManager.getWorkTaskExecutor().getBackgroundExecutor(), is(mExecutor));
+        SerialExecutor serialExecutor = workManager.getWorkTaskExecutor().getBackgroundExecutor();
+        assertThat(serialExecutor.getDelegatedExecutor(), is(mExecutor));
     }
 }
diff --git a/work/workmanager-testing/src/main/java/androidx/work/testing/InstantWorkTaskExecutor.java b/work/workmanager-testing/src/main/java/androidx/work/testing/InstantWorkTaskExecutor.java
index f727fd7..36e7764 100644
--- a/work/workmanager-testing/src/main/java/androidx/work/testing/InstantWorkTaskExecutor.java
+++ b/work/workmanager-testing/src/main/java/androidx/work/testing/InstantWorkTaskExecutor.java
@@ -17,6 +17,7 @@
 package androidx.work.testing;
 
 import androidx.annotation.NonNull;
+import androidx.work.impl.utils.SerialExecutor;
 import androidx.work.impl.utils.SynchronousExecutor;
 import androidx.work.impl.utils.taskexecutor.TaskExecutor;
 
@@ -28,6 +29,7 @@
 class InstantWorkTaskExecutor implements TaskExecutor {
 
     private Executor mSynchronousExecutor = new SynchronousExecutor();
+    private SerialExecutor mSerialExecutor = new SerialExecutor(mSynchronousExecutor);
 
     @NonNull
     Executor getSynchronousExecutor() {
@@ -46,11 +48,11 @@
 
     @Override
     public void executeOnBackgroundThread(Runnable runnable) {
-        runnable.run();
+        mSerialExecutor.execute(runnable);
     }
 
     @Override
-    public Executor getBackgroundExecutor() {
-        return mSynchronousExecutor;
+    public SerialExecutor getBackgroundExecutor() {
+        return mSerialExecutor;
     }
 }
diff --git a/work/workmanager-testing/src/main/java/androidx/work/testing/TestWorkManagerImpl.java b/work/workmanager-testing/src/main/java/androidx/work/testing/TestWorkManagerImpl.java
index f956bdb..4e7c916 100644
--- a/work/workmanager-testing/src/main/java/androidx/work/testing/TestWorkManagerImpl.java
+++ b/work/workmanager-testing/src/main/java/androidx/work/testing/TestWorkManagerImpl.java
@@ -54,7 +54,8 @@
                 configuration,
                 new TaskExecutor() {
                     Executor mSynchronousExecutor = new SynchronousExecutor();
-                    Executor mBackgroundExecutor = new SerialExecutor(configuration.getExecutor());
+                    SerialExecutor mSerialExecutor =
+                            new SerialExecutor(configuration.getTaskExecutor());
 
                     @Override
                     public void postToMainThread(Runnable runnable) {
@@ -68,12 +69,12 @@
 
                     @Override
                     public void executeOnBackgroundThread(Runnable runnable) {
-                        mBackgroundExecutor.execute(runnable);
+                        mSerialExecutor.execute(runnable);
                     }
 
                     @Override
-                    public Executor getBackgroundExecutor() {
-                        return configuration.getExecutor();
+                    public SerialExecutor getBackgroundExecutor() {
+                        return mSerialExecutor;
                     }
                 },
                 true);
diff --git a/work/workmanager-testing/src/main/java/androidx/work/testing/WorkManagerTestInitHelper.java b/work/workmanager-testing/src/main/java/androidx/work/testing/WorkManagerTestInitHelper.java
index f0e3c34..1864168 100644
--- a/work/workmanager-testing/src/main/java/androidx/work/testing/WorkManagerTestInitHelper.java
+++ b/work/workmanager-testing/src/main/java/androidx/work/testing/WorkManagerTestInitHelper.java
@@ -37,6 +37,7 @@
         SynchronousExecutor synchronousExecutor = new SynchronousExecutor();
         Configuration configuration = new Configuration.Builder()
                 .setExecutor(synchronousExecutor)
+                .setTaskExecutor(synchronousExecutor)
                 .build();
         initializeTestWorkManager(context, configuration);
     }
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/utils/taskexecutor/InstantWorkTaskExecutor.java b/work/workmanager/src/androidTest/java/androidx/work/impl/utils/taskexecutor/InstantWorkTaskExecutor.java
index 8bfee8e..965f9b3 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/utils/taskexecutor/InstantWorkTaskExecutor.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/utils/taskexecutor/InstantWorkTaskExecutor.java
@@ -16,6 +16,7 @@
 
 package androidx.work.impl.utils.taskexecutor;
 
+import androidx.work.impl.utils.SerialExecutor;
 import androidx.work.impl.utils.SynchronousExecutor;
 
 import java.util.concurrent.Executor;
@@ -26,6 +27,7 @@
 public class InstantWorkTaskExecutor implements TaskExecutor {
 
     private Executor mSynchronousExecutor = new SynchronousExecutor();
+    private SerialExecutor mBackgroundExecutor = new SerialExecutor(mSynchronousExecutor);
 
     @Override
     public void postToMainThread(Runnable runnable) {
@@ -43,7 +45,7 @@
     }
 
     @Override
-    public Executor getBackgroundExecutor() {
-        return mSynchronousExecutor;
+    public SerialExecutor getBackgroundExecutor() {
+        return mBackgroundExecutor;
     }
 }
diff --git a/work/workmanager/src/main/java/androidx/work/impl/utils/SerialExecutor.java b/work/workmanager/src/main/java/androidx/work/impl/utils/SerialExecutor.java
index 90e9adc..e48ef4a 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/utils/SerialExecutor.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/utils/SerialExecutor.java
@@ -17,6 +17,7 @@
 package androidx.work.impl.utils;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
 
 import java.util.ArrayDeque;
 import java.util.concurrent.Executor;
@@ -56,6 +57,12 @@
         }
     }
 
+    @NonNull
+    @VisibleForTesting
+    public Executor getDelegatedExecutor() {
+        return mExecutor;
+    }
+
     /**
      * A {@link Runnable} which tells the {@link SerialExecutor} to schedule the next command
      * after completion.
diff --git a/work/workmanager/src/main/java/androidx/work/impl/utils/taskexecutor/TaskExecutor.java b/work/workmanager/src/main/java/androidx/work/impl/utils/taskexecutor/TaskExecutor.java
index e5df2d9..2542e40 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/utils/taskexecutor/TaskExecutor.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/utils/taskexecutor/TaskExecutor.java
@@ -17,6 +17,7 @@
 package androidx.work.impl.utils.taskexecutor;
 
 import androidx.annotation.RestrictTo;
+import androidx.work.impl.utils.SerialExecutor;
 
 import java.util.concurrent.Executor;
 
@@ -44,7 +45,7 @@
     void executeOnBackgroundThread(Runnable runnable);
 
     /**
-     * @return The {@link Executor} for background task processing
+     * @return The {@link SerialExecutor} for background task processing
      */
-    Executor getBackgroundExecutor();
+    SerialExecutor getBackgroundExecutor();
 }
diff --git a/work/workmanager/src/main/java/androidx/work/impl/utils/taskexecutor/WorkManagerTaskExecutor.java b/work/workmanager/src/main/java/androidx/work/impl/utils/taskexecutor/WorkManagerTaskExecutor.java
index d689d89..6717838 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/utils/taskexecutor/WorkManagerTaskExecutor.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/utils/taskexecutor/WorkManagerTaskExecutor.java
@@ -32,7 +32,7 @@
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class WorkManagerTaskExecutor implements TaskExecutor {
 
-    private final Executor mBackgroundExecutor;
+    private final SerialExecutor mBackgroundExecutor;
 
     public WorkManagerTaskExecutor(@NonNull Executor backgroundExecutor) {
         // Wrap it with a serial executor so we have ordering guarantees on commands
@@ -65,7 +65,8 @@
     }
 
     @Override
-    public Executor getBackgroundExecutor() {
+    @NonNull
+    public SerialExecutor getBackgroundExecutor() {
         return mBackgroundExecutor;
     }
 }