Fix issue with older structure sizes

When structures are enlarged in RS we need to use the script
API number to properly handle the older cases.

Bug: 19734267

Change-Id: I0ffd3dc4cea1640f2b14c588df3a93eee749e74e
diff --git a/driver/rsdRuntimeStubs.cpp b/driver/rsdRuntimeStubs.cpp
index c728ca7..bc5c892 100644
--- a/driver/rsdRuntimeStubs.cpp
+++ b/driver/rsdRuntimeStubs.cpp
@@ -439,8 +439,9 @@
                                              const void *usr,
                                              const rs_script_call *call) {
     Context *rsc = RsdCpuReference::getTlsContext();
+    const Script *sc = RsdCpuReference::getTlsScript();
     rsrForEach(rsc, (Script *)script.p, (Allocation *)in.p,
-               (Allocation *)out.p, usr, 0, (RsScriptCall *)call);
+               (Allocation *)out.p, usr, 0, (RsScriptCall *)call, sc);
 }
 
 void __attribute__((overloadable)) rsForEach(::rs_script script,
@@ -448,16 +449,18 @@
                                              ::rs_allocation out,
                                              const void *usr) {
     Context *rsc = RsdCpuReference::getTlsContext();
+    const Script *sc = RsdCpuReference::getTlsScript();
     rsrForEach(rsc, (Script *)script.p, (Allocation *)in.p, (Allocation *)out.p,
-               usr, 0, nullptr);
+               usr, 0, nullptr, sc);
 }
 
 void __attribute__((overloadable)) rsForEach(::rs_script script,
                                              ::rs_allocation in,
                                              ::rs_allocation out) {
     Context *rsc = RsdCpuReference::getTlsContext();
+    const Script *sc = RsdCpuReference::getTlsScript();
     rsrForEach(rsc, (Script *)script.p, (Allocation *)in.p, (Allocation *)out.p,
-               nullptr, 0, nullptr);
+               nullptr, 0, nullptr, sc);
 }
 
 // These functions are only supported in 32-bit.
@@ -468,8 +471,9 @@
                                              const void *usr,
                                              uint32_t usrLen) {
     Context *rsc = RsdCpuReference::getTlsContext();
+    const Script *sc = RsdCpuReference::getTlsScript();
     rsrForEach(rsc, (Script *)script.p, (Allocation *)in.p, (Allocation *)out.p,
-               usr, usrLen, nullptr);
+               usr, usrLen, nullptr, sc);
 }
 
 void __attribute__((overloadable)) rsForEach(::rs_script script,
@@ -479,8 +483,9 @@
                                              uint32_t usrLen,
                                              const rs_script_call *call) {
     Context *rsc = RsdCpuReference::getTlsContext();
+    const Script *sc = RsdCpuReference::getTlsScript();
     rsrForEach(rsc, (Script *)script.p, (Allocation *)in.p, (Allocation *)out.p,
-               usr, usrLen, (RsScriptCall *)call);
+               usr, usrLen, (RsScriptCall *)call, sc);
 }
 #endif
 
diff --git a/rsRuntime.h b/rsRuntime.h
index 5a05883..de6ede3 100644
--- a/rsRuntime.h
+++ b/rsRuntime.h
@@ -159,7 +159,8 @@
                 Allocation *out,
                 const void *usr,
                 uint32_t usrBytes,
-                const RsScriptCall *call);
+                const RsScriptCall *call,
+                const Script *callingScript);
 
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/rsScript.cpp b/rsScript.cpp
index cb611af..7ea9857 100644
--- a/rsScript.cpp
+++ b/rsScript.cpp
@@ -28,6 +28,7 @@
     mTypes = nullptr;
     mInitialized = false;
     mHasObjectSlots = false;
+    mApiLevel = 0;
 }
 
 Script::~Script() {
diff --git a/rsScript.h b/rsScript.h
index 80bc622..12de95c 100644
--- a/rsScript.h
+++ b/rsScript.h
@@ -142,9 +142,14 @@
     }
     virtual void callUpdateCacheObject(const Context *rsc, void *dstObj) const;
 
+    uint32_t getApiLevel() const {
+        return mApiLevel;
+    }
+
 protected:
     bool mInitialized;
     bool mHasObjectSlots;
+    uint32_t mApiLevel;
     ObjectBaseRef<Allocation> *mSlots;
     ObjectBaseRef<const Type> *mTypes;
 
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index 4d791f7..e1685b9 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -310,6 +310,10 @@
         sdkVersion = rsc->getTargetSdkVersion();
     }
 
+    // Save off the sdkVersion, so that we can handle broken cases later.
+    // Bug 19734267
+    mApiLevel = sdkVersion;
+
     if (BT) {
         delete BT;
     }
diff --git a/rsScriptC_Lib.cpp b/rsScriptC_Lib.cpp
index 628190d..6404095 100644
--- a/rsScriptC_Lib.cpp
+++ b/rsScriptC_Lib.cpp
@@ -224,17 +224,30 @@
                 Script *target,
                 Allocation *in, Allocation *out,
                 const void *usr, uint32_t usrBytes,
-                const RsScriptCall *call) {
+                const RsScriptCall *call,
+                const Script *callingScript) {
+
+    RsScriptCall c, *cptr = nullptr;
+    memset(&c, 0, sizeof(c));
+    if (call != nullptr) {
+        cptr = &c;
+        if (callingScript->getApiLevel() < 23) {
+            // Up to API 23, the structure was smaller and we need to zero extend
+            memcpy(&c, call, 7*4);
+        } else {
+            c = *call;
+        }
+    }
 
     if (in == nullptr) {
         target->runForEach(rsc, /* root slot */ 0, nullptr, 0, out, usr,
-                           usrBytes, call);
+                           usrBytes, cptr);
 
     } else {
         const Allocation *ins[1] = {in};
         target->runForEach(rsc, /* root slot */ 0, ins,
                            sizeof(ins) / sizeof(RsAllocation), out, usr,
-                           usrBytes, call);
+                           usrBytes, cptr);
     }
 }