Added workaround passing empty arg array for proxy invocation.

This recreates old Dalvik behavior for older target sdk versions,
but will still pass null for newer ones.

Bug: 13247236

Change-Id: I663c44f729dd173b47da692a753b986daa0463e9
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index 39b2ec2..320273d 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -148,7 +148,9 @@
   soa.Self()->AssertThreadSuspensionIsAllowable();
   jobjectArray args_jobj = NULL;
   const JValue zero;
-  if (args.size() > 0) {
+  int32_t target_sdk_version = Runtime::Current()->GetTargetSdkVersion();
+  // Do not create empty arrays unless needed to maintain Dalvik bug compatibility.
+  if (args.size() > 0 || (target_sdk_version > 0 && target_sdk_version <= 21)) {
     args_jobj = soa.Env()->NewObjectArray(args.size(), WellKnownClasses::java_lang_Object, NULL);
     if (args_jobj == NULL) {
       CHECK(soa.Self()->IsExceptionPending());
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index d9c9b59..2572938 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -170,13 +170,12 @@
   return Runtime::Current()->GetJavaVM()->check_jni ? JNI_TRUE : JNI_FALSE;
 }
 
-static void VMRuntime_setTargetSdkVersionNative(JNIEnv* env, jobject, jint targetSdkVersion) {
+static void VMRuntime_setTargetSdkVersionNative(JNIEnv*, jobject, jint target_sdk_version) {
   // This is the target SDK version of the app we're about to run. It is intended that this a place
   // where workarounds can be enabled.
   // Note that targetSdkVersion may be CUR_DEVELOPMENT (10000).
   // Note that targetSdkVersion may be 0, meaning "current".
-  UNUSED(env);
-  UNUSED(targetSdkVersion);
+  Runtime::Current()->SetTargetSdkVersion(target_sdk_version);
 }
 
 static void VMRuntime_registerNativeAllocation(JNIEnv* env, jobject, jint bytes) {
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index dcbf42d..5ab22f6 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -141,7 +141,8 @@
       null_pointer_handler_(nullptr),
       suspend_handler_(nullptr),
       stack_overflow_handler_(nullptr),
-      verify_(false) {
+      verify_(false),
+      target_sdk_version_(0) {
   for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
     callee_save_methods_[i] = nullptr;
   }
diff --git a/runtime/runtime.h b/runtime/runtime.h
index f7074f6..55c3878 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -439,6 +439,14 @@
     return running_on_valgrind_;
   }
 
+  void SetTargetSdkVersion(int32_t version) {
+    target_sdk_version_ = version;
+  }
+
+  int32_t GetTargetSdkVersion() const {
+    return target_sdk_version_;
+  }
+
   static const char* GetDefaultInstructionSetFeatures() {
     return kDefaultInstructionSetFeatures;
   }
@@ -585,6 +593,9 @@
   // If false, verification is disabled. True by default.
   bool verify_;
 
+  // Specifies target SDK version to allow workarounds for certain API levels.
+  int32_t target_sdk_version_;
+
   DISALLOW_COPY_AND_ASSIGN(Runtime);
 };