New API methods for Script Group

Use a single vararg Object array for both kernel/invoke arguments
and global bindings. The assumption is that global bindings are in
the end after the kernel/invoke arguments.
This simplifies the api to add a kernel or invoke to a script group.

Change-Id: I7efb1035c5967e2cadd15e6fe27f20c80ba197a2
diff --git a/rs/java/android/renderscript/ScriptGroup2.java b/rs/java/android/renderscript/ScriptGroup2.java
index 2e171b6..4a56572 100644
--- a/rs/java/android/renderscript/ScriptGroup2.java
+++ b/rs/java/android/renderscript/ScriptGroup2.java
@@ -345,11 +345,22 @@
     /**
        @hide Pending Android public API approval.
     */
+    public static final class Binding {
+        public Script.FieldID mField;
+        public Object mValue;
+        public Binding(Script.FieldID field, Object value) {
+            mField = field;
+            mValue = value;
+        }
+    }
+
+    /**
+       @hide Pending Android public API approval.
+    */
     public static final class Builder {
         RenderScript mRS;
         List<Closure> mClosures;
         List<UnboundValue> mInputs;
-
         private static final String TAG = "ScriptGroup2.Builder";
 
         public Builder(RenderScript rs) {
@@ -378,10 +389,50 @@
             return unbound;
         }
 
+        public Closure addKernel(Script.KernelID k, Type returnType, Object... argsAndBindings) {
+            ArrayList<Object> args = new ArrayList<Object>();
+            Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
+            if (!seperateArgsAndBindings(argsAndBindings, args, bindingMap)) {
+                return null;
+            }
+            return addKernel(k, returnType, args.toArray(), bindingMap);
+        }
+
+        public Closure addInvoke(Script.InvokeID invoke, Object... argsAndBindings) {
+            ArrayList<Object> args = new ArrayList<Object>();
+            Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
+            if (!seperateArgsAndBindings(argsAndBindings, args, bindingMap)) {
+                return null;
+            }
+            return addInvoke(invoke, args.toArray(), bindingMap);
+        }
+
         public ScriptGroup2 create(Future... outputs) {
             ScriptGroup2 ret = new ScriptGroup2(mRS, mClosures, mInputs, outputs);
             return ret;
         }
 
+        private boolean seperateArgsAndBindings(Object[] argsAndBindings,
+                                                ArrayList<Object> args,
+                                                Map<Script.FieldID, Object> bindingMap) {
+            int i;
+            for (i = 0; i < argsAndBindings.length; i++) {
+                if (argsAndBindings[i] instanceof Binding) {
+                    break;
+                }
+                args.add(argsAndBindings[i]);
+            }
+
+            for (; i < argsAndBindings.length; i++) {
+                if (!(argsAndBindings[i] instanceof Binding)) {
+                    return false;
+                }
+                Binding b = (Binding)argsAndBindings[i];
+                bindingMap.put(b.mField, b.mValue);
+            }
+
+            return true;
+        }
+
     }
 }