Merge "Add a Configuration.Builder that takes in a template Configuration." into androidx-master-dev
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 5270422..c13b28c 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
@@ -56,16 +56,8 @@
         // Check if the configuration being used has overridden the task executor. If not,
         // swap to SynchronousExecutor. This is to preserve existing behavior.
         if (configuration.isUsingDefaultTaskExecutor()) {
-            Configuration.Builder builder = new Configuration.Builder()
-                    .setExecutor(configuration.getExecutor())
-                    .setTaskExecutor(new SynchronousExecutor())
-                    .setInputMergerFactory(configuration.getInputMergerFactory())
-                    .setJobSchedulerJobIdRange(configuration.getMinJobSchedulerId(),
-                            configuration.getMaxJobSchedulerId())
-                    .setMaxSchedulerLimit(configuration.getMaxSchedulerLimit())
-                    .setMinimumLoggingLevel(configuration.getMinimumLoggingLevel())
-                    .setWorkerFactory(configuration.getWorkerFactory());
-
+            Configuration.Builder builder = new Configuration.Builder(configuration)
+                    .setTaskExecutor(new SynchronousExecutor());
             configuration = builder.build();
         }
 
diff --git a/work/workmanager/src/main/java/androidx/work/Configuration.java b/work/workmanager/src/main/java/androidx/work/Configuration.java
index 1b3aea0..4be8448 100644
--- a/work/workmanager/src/main/java/androidx/work/Configuration.java
+++ b/work/workmanager/src/main/java/androidx/work/Configuration.java
@@ -48,14 +48,23 @@
      */
     public static final int MIN_SCHEDULER_LIMIT = 20;
 
-    private final @NonNull Executor mExecutor;
-    private final @NonNull Executor mTaskExecutor;
-    private final @NonNull WorkerFactory mWorkerFactory;
-    private final @NonNull InputMergerFactory mInputMergerFactory;
-    private final int mLoggingLevel;
-    private final int mMinJobSchedulerId;
-    private final int mMaxJobSchedulerId;
-    private final int mMaxSchedulerLimit;
+    // Synthetic access
+    @SuppressWarnings("WeakerAccess")
+    final @NonNull Executor mExecutor;
+    @SuppressWarnings("WeakerAccess")
+    final @NonNull Executor mTaskExecutor;
+    @SuppressWarnings("WeakerAccess")
+    final @NonNull WorkerFactory mWorkerFactory;
+    @SuppressWarnings("WeakerAccess")
+    final @NonNull InputMergerFactory mInputMergerFactory;
+    @SuppressWarnings("WeakerAccess")
+    final int mLoggingLevel;
+    @SuppressWarnings("WeakerAccess")
+    final int mMinJobSchedulerId;
+    @SuppressWarnings("WeakerAccess")
+    final int mMaxJobSchedulerId;
+    @SuppressWarnings("WeakerAccess")
+    final int mMaxSchedulerLimit;
     private final boolean mIsUsingDefaultTaskExecutor;
 
     Configuration(@NonNull Configuration.Builder builder) {
@@ -216,10 +225,41 @@
         InputMergerFactory mInputMergerFactory;
         Executor mTaskExecutor;
 
-        int mLoggingLevel = Log.INFO;
-        int mMinJobSchedulerId = IdGenerator.INITIAL_ID;
-        int mMaxJobSchedulerId = Integer.MAX_VALUE;
-        int mMaxSchedulerLimit = MIN_SCHEDULER_LIMIT;
+        int mLoggingLevel;
+        int mMinJobSchedulerId;
+        int mMaxJobSchedulerId;
+        int mMaxSchedulerLimit;
+
+        /**
+         * Creates a new {@link Configuration.Builder}.
+         */
+        public Builder() {
+            mLoggingLevel = Log.INFO;
+            mMinJobSchedulerId = IdGenerator.INITIAL_ID;
+            mMaxJobSchedulerId = Integer.MAX_VALUE;
+            mMaxSchedulerLimit = MIN_SCHEDULER_LIMIT;
+        }
+
+        /**
+         * Creates a new {@link Configuration.Builder} with an existing {@link Configuration} as its
+         * template.
+         *
+         * @param configuration An existing {@link Configuration} to use as a template
+         * @hide
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        public Builder(@NonNull Configuration configuration) {
+            // Note that these must be accessed through fields and not the getters, which can
+            // otherwise manipulate the returned value (see getMaxSchedulerLimit(), for example).
+            mExecutor = configuration.mExecutor;
+            mWorkerFactory = configuration.mWorkerFactory;
+            mInputMergerFactory = configuration.mInputMergerFactory;
+            mTaskExecutor = configuration.mTaskExecutor;
+            mLoggingLevel = configuration.mLoggingLevel;
+            mMinJobSchedulerId = configuration.mMinJobSchedulerId;
+            mMaxJobSchedulerId = configuration.mMaxJobSchedulerId;
+            mMaxSchedulerLimit = configuration.mMaxSchedulerLimit;
+        }
 
         /**
          * Specifies a custom {@link WorkerFactory} for WorkManager.