Merge "Have Arguments expose primitive types only." into flatfoot-background
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkContinuationImplTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkContinuationImplTest.java
index 319b1a9..623ea5d 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkContinuationImplTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkContinuationImplTest.java
@@ -106,7 +106,6 @@
         for (String id : ids) {
             mWorkManagerImpl.cancelWorkById(id);
         }
-        mDatabase.close();
         WorkManagerImpl.setDelegate(null);
         ArchTaskExecutor.getInstance().setDelegate(null);
     }
@@ -274,27 +273,39 @@
                 new WorkContinuationImpl(mWorkManagerImpl, Collections.singletonList(secondWork));
         WorkContinuationImpl dependentContinuation =
                 (WorkContinuationImpl) WorkContinuation.join(firstContinuation, secondContinuation);
-        dependentContinuation.enqueue();
+        dependentContinuation.enqueueBlocking();
 
         String joinId = null;
         for (String id : dependentContinuation.getAllIds()) {
             if (!firstWork.getId().equals(id) && !secondWork.getId().equals(id)) {
                 joinId = id;
-                mWorkManagerImpl.getProcessor().startWork(id);
-                Thread.sleep(5000L);
                 break;
             }
         }
 
+        Thread.sleep(5000L);
+
+        // TODO(sumir): I can't seem to get this kicked off automatically, so I'm running it myself.
+        // Figure out what's going on here.
+        new WorkerWrapper.Builder(InstrumentationRegistry.getTargetContext(), mDatabase, joinId)
+                .build()
+                .run();
+
         assertThat(joinId, is(not(nullValue())));
-        WorkSpec joinWorkSpec = workSpecDao.getWorkSpec(joinId);
+        WorkSpec joinWorkSpec = mDatabase.workSpecDao().getWorkSpec(joinId);
         assertThat(joinWorkSpec, is(not(nullValue())));
+        assertThat(joinWorkSpec.state, is(State.SUCCEEDED));
 
         Arguments output = joinWorkSpec.output;
-        assertThat(output.getIntArray(intTag), is(not(nullValue())));
-        assertThat(Arrays.asList(output.getIntArray(intTag)), containsInAnyOrder(0, 1));
+        int[] intArray = output.getIntArray(intTag);
+
+        assertThat(intArray, is(not(nullValue())));
+        Arrays.sort(intArray);
+        assertThat(Arrays.binarySearch(intArray, 0), is(not(-1)));
+        assertThat(Arrays.binarySearch(intArray, 1), is(not(-1)));
         assertThat(output.getStringArray(stringTag), is(not(nullValue())));
         assertThat(Arrays.asList(output.getStringArray(stringTag)), contains("hello"));
+
     }
 
     @Test
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
index 9fa86f9..b8823d0 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
@@ -137,7 +137,6 @@
         for (String id : ids) {
             mWorkManagerImpl.cancelWorkById(id);
         }
-        mDatabase.close();
         WorkManagerImpl.setDelegate(null);
         ArchTaskExecutor.getInstance().setDelegate(null);
     }
diff --git a/work/workmanager/src/main/java/androidx/work/Arguments.java b/work/workmanager/src/main/java/androidx/work/Arguments.java
index e9917ae..a28f1fe 100644
--- a/work/workmanager/src/main/java/androidx/work/Arguments.java
+++ b/work/workmanager/src/main/java/androidx/work/Arguments.java
@@ -57,26 +57,47 @@
      * @param defaultValue The default value to return if the key is not found
      * @return The value specified by the key if it exists; the default value otherwise
      */
-    public Boolean getBoolean(String key, Boolean defaultValue) {
+    public boolean getBoolean(String key, boolean defaultValue) {
         Object value = mValues.get(key);
         if (value instanceof Boolean) {
-            return (Boolean) value;
+            return (boolean) value;
         } else {
             return defaultValue;
         }
     }
 
     /**
+     * Get the boolean array value for the given key.
+     *
+     * @param key The key for the argument
+     * @return The value specified by the key if it exists; {@code null} otherwise
+     */
+    public boolean[] getBooleanArray(String key) {
+        Object value = mValues.get(key);
+        if (value instanceof Boolean[]) {
+            Boolean[] array = (Boolean[]) value;
+            boolean[] returnArray = new boolean[array.length];
+            for (int i = 0; i < array.length; ++i) {
+                returnArray[i] = array[i];
+            }
+            return returnArray;
+        } else {
+            return null;
+        }
+    }
+
+
+    /**
      * Get the integer value for the given key.
      *
      * @param key The key for the argument
      * @param defaultValue The default value to return if the key is not found
      * @return The value specified by the key if it exists; the default value otherwise
      */
-    public Integer getInt(String key, Integer defaultValue) {
+    public int getInt(String key, int defaultValue) {
         Object value = mValues.get(key);
         if (value instanceof Integer) {
-            return (Integer) value;
+            return (int) value;
         } else {
             return defaultValue;
         }
@@ -88,10 +109,15 @@
      * @param key The key for the argument
      * @return The value specified by the key if it exists; {@code null} otherwise
      */
-    public Integer[] getIntArray(String key) {
+    public int[] getIntArray(String key) {
         Object value = mValues.get(key);
         if (value instanceof Integer[]) {
-            return (Integer[]) value;
+            Integer[] array = (Integer[]) value;
+            int[] returnArray = new int[array.length];
+            for (int i = 0; i < array.length; ++i) {
+                returnArray[i] = array[i];
+            }
+            return returnArray;
         } else {
             return null;
         }
@@ -104,10 +130,10 @@
      * @param defaultValue The default value to return if the key is not found
      * @return The value specified by the key if it exists; the default value otherwise
      */
-    public Long getLong(String key, Long defaultValue) {
+    public long getLong(String key, long defaultValue) {
         Object value = mValues.get(key);
         if (value instanceof Long) {
-            return (Long) value;
+            return (long) value;
         } else {
             return defaultValue;
         }
@@ -119,10 +145,51 @@
      * @param key The key for the argument
      * @return The value specified by the key if it exists; {@code null} otherwise
      */
-    public Long[] getLongArray(String key) {
+    public long[] getLongArray(String key) {
         Object value = mValues.get(key);
         if (value instanceof Long[]) {
-            return (Long[]) value;
+            Long[] array = (Long[]) value;
+            long[] returnArray = new long[array.length];
+            for (int i = 0; i < array.length; ++i) {
+                returnArray[i] = array[i];
+            }
+            return returnArray;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Get the float value for the given key.
+     *
+     * @param key The key for the argument
+     * @param defaultValue The default value to return if the key is not found
+     * @return The value specified by the key if it exists; the default value otherwise
+     */
+    public float getFloat(String key, float defaultValue) {
+        Object value = mValues.get(key);
+        if (value instanceof Float) {
+            return (float) value;
+        } else {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Get the float array value for the given key.
+     *
+     * @param key The key for the argument
+     * @return The value specified by the key if it exists; {@code null} otherwise
+     */
+    public float[] getFloatArray(String key) {
+        Object value = mValues.get(key);
+        if (value instanceof Float[]) {
+            Float[] array = (Float[]) value;
+            float[] returnArray = new float[array.length];
+            for (int i = 0; i < array.length; ++i) {
+                returnArray[i] = array[i];
+            }
+            return returnArray;
         } else {
             return null;
         }
@@ -135,10 +202,10 @@
      * @param defaultValue The default value to return if the key is not found
      * @return The value specified by the key if it exists; the default value otherwise
      */
-    public Double getDouble(String key, Double defaultValue) {
+    public double getDouble(String key, double defaultValue) {
         Object value = mValues.get(key);
         if (value instanceof Double) {
-            return (Double) value;
+            return (double) value;
         } else {
             return defaultValue;
         }
@@ -150,10 +217,15 @@
      * @param key The key for the argument
      * @return The value specified by the key if it exists; {@code null} otherwise
      */
-    public Double[] getDoubleArray(String key) {
+    public double[] getDoubleArray(String key) {
         Object value = mValues.get(key);
         if (value instanceof Double[]) {
-            return (Double[]) value;
+            Double[] array = (Double[]) value;
+            double[] returnArray = new double[array.length];
+            for (int i = 0; i < array.length; ++i) {
+                returnArray[i] = array[i];
+            }
+            return returnArray;
         } else {
             return null;
         }
@@ -296,6 +368,46 @@
         return 31 * mValues.hashCode();
     }
 
+    private static Boolean[] convertPrimitiveBooleanArray(boolean[] value) {
+        Boolean[] returnValue = new Boolean[value.length];
+        for (int i = 0; i < value.length; ++i) {
+            returnValue[i] = value[i];
+        }
+        return returnValue;
+    }
+
+    private static Integer[] convertPrimitiveIntArray(int[] value) {
+        Integer[] returnValue = new Integer[value.length];
+        for (int i = 0; i < value.length; ++i) {
+            returnValue[i] = value[i];
+        }
+        return returnValue;
+    }
+
+    private static Long[] convertPrimitiveLongArray(long[] value) {
+        Long[] returnValue = new Long[value.length];
+        for (int i = 0; i < value.length; ++i) {
+            returnValue[i] = value[i];
+        }
+        return returnValue;
+    }
+
+    private static Float[] convertPrimitiveFloatArray(float[] value) {
+        Float[] returnValue = new Float[value.length];
+        for (int i = 0; i < value.length; ++i) {
+            returnValue[i] = value[i];
+        }
+        return returnValue;
+    }
+
+    private static Double[] convertPrimitiveDoubleArray(double[] value) {
+        Double[] returnValue = new Double[value.length];
+        for (int i = 0; i < value.length; ++i) {
+            returnValue[i] = value[i];
+        }
+        return returnValue;
+    }
+
     /**
      * A builder for {@link Arguments}.
      */
@@ -310,24 +422,35 @@
          * @param value The value for this argument
          * @return The {@link Builder}
          */
-        public Builder putBoolean(String key, Boolean value) {
+        public Builder putBoolean(String key, boolean value) {
             mValues.put(key, value);
             return this;
         }
 
         /**
+         * Puts a boolean array into the arguments.
+         *
+         * @param key The key for this argument
+         * @param value The value for this argument
+         * @return The {@link Builder}
+         */
+        public Builder putBooleanArray(String key, boolean[] value) {
+            mValues.put(key, convertPrimitiveBooleanArray(value));
+            return this;
+        }
+
+        /**
          * Puts an integer into the arguments.
          *
          * @param key The key for this argument
          * @param value The value for this argument
          * @return The {@link Builder}
          */
-        public Builder putInt(String key, Integer value) {
+        public Builder putInt(String key, int value) {
             mValues.put(key, value);
             return this;
         }
 
-
         /**
          * Puts an integer array into the arguments.
          *
@@ -335,12 +458,11 @@
          * @param value The value for this argument
          * @return The {@link Builder}
          */
-        public Builder putIntArray(String key, Integer[] value) {
-            mValues.put(key, value);
+        public Builder putIntArray(String key, int[] value) {
+            mValues.put(key, convertPrimitiveIntArray(value));
             return this;
         }
 
-
         /**
          * Puts a long into the arguments.
          *
@@ -348,7 +470,7 @@
          * @param value The value for this argument
          * @return The {@link Builder}
          */
-        public Builder putLong(String key, Long value) {
+        public Builder putLong(String key, long value) {
             mValues.put(key, value);
             return this;
         }
@@ -360,19 +482,43 @@
          * @param value The value for this argument
          * @return The {@link Builder}
          */
-        public Builder putLongArray(String key, Long[] value) {
+        public Builder putLongArray(String key, long[] value) {
+            mValues.put(key, convertPrimitiveLongArray(value));
+            return this;
+        }
+
+        /**
+         * Puts a float into the arguments.
+         *
+         * @param key The key for this argument
+         * @param value The value for this argument
+         * @return The {@link Builder}
+         */
+        public Builder putFloat(String key, float value) {
             mValues.put(key, value);
             return this;
         }
 
         /**
+         * Puts a float array into the arguments.
+         *
+         * @param key The key for this argument
+         * @param value The value for this argument
+         * @return The {@link Builder}
+         */
+        public Builder putFloatArray(String key, float[] value) {
+            mValues.put(key, convertPrimitiveFloatArray(value));
+            return this;
+        }
+
+        /**
          * Puts a double into the arguments.
          *
          * @param key The key for this argument
          * @param value The value for this argument
          * @return The {@link Builder}
          */
-        public Builder putDouble(String key, Double value) {
+        public Builder putDouble(String key, double value) {
             mValues.put(key, value);
             return this;
         }
@@ -384,8 +530,8 @@
          * @param value The value for this argument
          * @return The {@link Builder}
          */
-        public Builder putDoubleArray(String key, Double[] value) {
-            mValues.put(key, value);
+        public Builder putDoubleArray(String key, double[] value) {
+            mValues.put(key, convertPrimitiveDoubleArray(value));
             return this;
         }
 
@@ -451,9 +597,20 @@
                         || valueType == Boolean[].class
                         || valueType == Integer[].class
                         || valueType == Long[].class
+                        || valueType == Float[].class
                         || valueType == Double[].class
                         || valueType == String[].class) {
                     mValues.put(key, value);
+                } else if (valueType == boolean[].class) {
+                    mValues.put(key, convertPrimitiveBooleanArray((boolean[]) value));
+                } else if (valueType == int[].class) {
+                    mValues.put(key, convertPrimitiveIntArray((int[]) value));
+                } else if (valueType == long[].class) {
+                    mValues.put(key, convertPrimitiveLongArray((long[]) value));
+                } else if (valueType == float[].class) {
+                    mValues.put(key, convertPrimitiveFloatArray((float[]) value));
+                } else if (valueType == double[].class) {
+                    mValues.put(key, convertPrimitiveDoubleArray((double[]) value));
                 } else {
                     Logger.warn(TAG, "Ignoring key %s because of invalid type %s", key, valueType);
                 }
diff --git a/work/workmanager/src/test/java/androidx/work/ArgumentsTest.java b/work/workmanager/src/test/java/androidx/work/ArgumentsTest.java
index bd88a44..19f12c9 100644
--- a/work/workmanager/src/test/java/androidx/work/ArgumentsTest.java
+++ b/work/workmanager/src/test/java/androidx/work/ArgumentsTest.java
@@ -71,8 +71,8 @@
 
     @Test
     public void testSerializeIntArray() throws IOException, ClassNotFoundException {
-        Integer[] expectedValue1 = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-        Integer[] expectedValue2 = new Integer[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
+        int[] expectedValue1 = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+        int[] expectedValue2 = new int[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
         Arguments args = new Arguments.Builder()
                 .putIntArray(KEY1, expectedValue1)
                 .putIntArray(KEY2, expectedValue2)
diff --git a/work/workmanager/src/test/java/androidx/work/ArrayCreatingInputMergerTest.java b/work/workmanager/src/test/java/androidx/work/ArrayCreatingInputMergerTest.java
index be4a0f1..127f85f 100644
--- a/work/workmanager/src/test/java/androidx/work/ArrayCreatingInputMergerTest.java
+++ b/work/workmanager/src/test/java/androidx/work/ArrayCreatingInputMergerTest.java
@@ -32,8 +32,8 @@
 
     private static final String KEY = "key";
 
-    private static final Integer[] VALUE_INT_ARRAY = { 0, 1, 2 };
-    private static final Integer VALUE_INT = 3;
+    private static final int[] VALUE_INT_ARRAY = { 0, 1, 2 };
+    private static final int VALUE_INT = 3;
     private static final Long VALUE_LONG = Long.MAX_VALUE;
 
     ArrayCreatingInputMerger mArrayCreatingInputMerger;
@@ -53,7 +53,7 @@
     public void testMerge_singleArgument() {
         Arguments output = getOutputFor(mArgumentsWithInt);
         assertThat(output.size(), is(1));
-        Integer[] outputArray = output.getIntArray(KEY);
+        int[] outputArray = output.getIntArray(KEY);
         assertThat(outputArray.length, is(1));
         assertThat(outputArray[0], is(VALUE_INT));
     }
@@ -62,7 +62,7 @@
     public void testMerge_concatenatesNonArrays() {
         Arguments output = getOutputFor(mArgumentsWithInt, mArgumentsWithInt);
         assertThat(output.size(), is(1));
-        Integer[] outputArray = output.getIntArray(KEY);
+        int[] outputArray = output.getIntArray(KEY);
         assertThat(outputArray.length, is(2));
         assertThat(outputArray[0], is(VALUE_INT));
         assertThat(outputArray[1], is(VALUE_INT));
@@ -72,7 +72,7 @@
     public void testMerge_concatenatesArrays() {
         Arguments output = getOutputFor(mArgumentsWithIntArray, mArgumentsWithIntArray);
         assertThat(output.size(), is(1));
-        Integer[] outputArray = output.getIntArray(KEY);
+        int[] outputArray = output.getIntArray(KEY);
         assertThat(outputArray.length, is(VALUE_INT_ARRAY.length * 2));
         for (int i = 0; i < 2; ++i) {
             for (int j = 0; j < VALUE_INT_ARRAY.length; ++j) {
@@ -85,7 +85,7 @@
     public void testMerge_concatenatesArrayAndPrimitive() {
         Arguments output = getOutputFor(mArgumentsWithIntArray, mArgumentsWithInt);
         assertThat(output.size(), is(1));
-        Integer[] outputArray = output.getIntArray(KEY);
+        int[] outputArray = output.getIntArray(KEY);
         assertThat(outputArray.length, is(VALUE_INT_ARRAY.length + 1));
         for (int i = 0; i < VALUE_INT_ARRAY.length; ++i) {
             assertThat(outputArray[i], is(VALUE_INT_ARRAY[i]));