DO NOT MERGE Add string and array size limit to extended device info activity API

Change-Id: I23b8bdbb6c151b614feca320b85420b1ed7e3740
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivity.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivity.java
index 02cc1b4..62e512c 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivity.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivity.java
@@ -28,6 +28,7 @@
 import java.io.FileOutputStream;
 import java.io.OutputStreamWriter;
 import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
 import java.util.concurrent.CountDownLatch;
 
 /**
@@ -44,6 +45,9 @@
     /** Device info result code: collector completed success. */
     private static final int DEVICE_INFO_RESULT_OK = 1;
 
+    private static final int MAX_STRING_VALUE_LENGTH = 1000;
+    private static final int MAX_ARRAY_LENGTH = 1000;
+
     private static final String LOG_TAG = "DeviceInfoActivity";
 
     private CountDownLatch mDone = new CountDownLatch(1);
@@ -252,7 +256,7 @@
     public void addResult(String name, String value) {
         checkName(name);
         try {
-            mJsonWriter.name(name).value(value);
+            mJsonWriter.name(name).value(checkString(value));
         } catch (Exception e) {
             error("Failed to add result for type String: " + e.getMessage());
         }
@@ -266,7 +270,7 @@
         try {
             mJsonWriter.name(name);
             mJsonWriter.beginArray();
-            for (double value : list) {
+            for (double value : checkArray(list)) {
                 mJsonWriter.value(value);
             }
             mJsonWriter.endArray();
@@ -280,12 +284,12 @@
      */
     public void addArray(String name, long[] list) {
         checkName(name);
-            try {
-            mJsonWriter.name(name);
-            mJsonWriter.beginArray();
-            for (long value : list) {
-                mJsonWriter.value(value);
-            }
+        try {
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (long value : checkArray(list)) {
+            mJsonWriter.value(value);
+        }
             mJsonWriter.endArray();
         } catch (Exception e) {
             error("Failed to add result array for type long: " + e.getMessage());
@@ -300,7 +304,7 @@
         try {
             mJsonWriter.name(name);
             mJsonWriter.beginArray();
-            for (int value : list) {
+            for (int value : checkArray(list)) {
                 mJsonWriter.value((Number) value);
             }
             mJsonWriter.endArray();
@@ -317,7 +321,7 @@
         try {
             mJsonWriter.name(name);
             mJsonWriter.beginArray();
-            for (boolean value : list) {
+            for (boolean value : checkArray(list)) {
                 mJsonWriter.value(value);
             }
             mJsonWriter.endArray();
@@ -334,8 +338,8 @@
         try {
             mJsonWriter.name(name);
             mJsonWriter.beginArray();
-            for (String value : list) {
-                mJsonWriter.value(value);
+            for (String value : checkArray(list)) {
+                mJsonWriter.value(checkString(value));
             }
             mJsonWriter.endArray();
         } catch (Exception e) {
@@ -343,6 +347,53 @@
         }
     }
 
+    private static boolean[] checkArray(boolean[] values) {
+        if (values.length > MAX_ARRAY_LENGTH) {
+            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+        } else {
+            return values;
+        }
+    }
+
+    private static double[] checkArray(double[] values) {
+        if (values.length > MAX_ARRAY_LENGTH) {
+            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+        } else {
+            return values;
+        }
+    }
+
+    private static int[] checkArray(int[] values) {
+        if (values.length > MAX_ARRAY_LENGTH) {
+            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+        } else {
+            return values;
+        }
+    }
+
+    private static long[] checkArray(long[] values) {
+        if (values.length > MAX_ARRAY_LENGTH) {
+            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+        } else {
+            return values;
+        }
+    }
+
+    private static String[] checkArray(String[] values) {
+        if (values.length > MAX_ARRAY_LENGTH) {
+            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+        } else {
+            return values;
+        }
+    }
+
+    private static String checkString(String value) {
+        if (value.length() > MAX_STRING_VALUE_LENGTH) {
+            return value.substring(0, MAX_STRING_VALUE_LENGTH);
+        }
+        return value;
+    }
+
     private static String checkName(String value) {
         if (TextUtils.isEmpty(value)) {
             throw new NullPointerException();
diff --git a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivityTest.java b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivityTest.java
index 4f8a1b8..8a8a66c 100644
--- a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivityTest.java
+++ b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivityTest.java
@@ -29,38 +29,6 @@
 
     private static final String EXPECTED_FILE_PATH =
             "/storage/emulated/0/device-info-files/SampleDeviceInfo.deviceinfo.json";
-    private static final String EXPECTED_JSON_CONTENT = "{\n" +
-      "  \"foo\": {\n" +
-      "    \"foo_boolean\": true,\n" +
-      "    \"bar\": {\n" +
-      "      \"bar_string\": [\n" +
-      "        \"bar-string-1\",\n" +
-      "        \"bar-string-2\",\n" +
-      "        \"bar-string-3\"\n" +
-      "      ],\n" +
-      "      \"bar_boolean\": [\n" +
-      "        true,\n" +
-      "        false\n" +
-      "      ],\n" +
-      "      \"bar_double\": [\n" +
-      "        1.7976931348623157E308,\n" +
-      "        4.9E-324\n" +
-      "      ],\n" +
-      "      \"bar_int\": [\n" +
-      "        2147483647,\n" +
-      "        -2147483648\n" +
-      "      ],\n" +
-      "      \"bar_long\": [\n" +
-      "        9223372036854775807,\n" +
-      "        -9223372036854775808\n" +
-      "      ]\n" +
-      "    },\n" +
-      "    \"foo_double\": 1.7976931348623157E308,\n" +
-      "    \"foo_int\": 2147483647,\n" +
-      "    \"foo_long\": 9223372036854775807,\n" +
-      "    \"foo_string\": \"foo-string\"\n" +
-      "  }\n" +
-      "}\n";
 
     private SampleDeviceInfo mActivity;
 
@@ -91,7 +59,7 @@
         assertEquals("Incorrect file path", EXPECTED_FILE_PATH, resultFilePath);
         // Check json file content
         String jsonContent = readFile(resultFilePath);
-        assertEquals("Incorrect json output", EXPECTED_JSON_CONTENT, jsonContent);
+        assertEquals("Incorrect json output", ExampleObjects.sampleDeviceInfoJson(), jsonContent);
     }
 
     private String readFile(String filePath) throws IOException {
diff --git a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/ExampleObjects.java b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/ExampleObjects.java
new file mode 100644
index 0000000..92e7df1
--- /dev/null
+++ b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/ExampleObjects.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+/**
+ * Example Objects for {@link DeviceInfoActivity} test package.
+ */
+public final class ExampleObjects {
+
+    private static final int MAX_LENGTH = 1000;
+
+    private static final String SAMPLE_DEVICE_INFO_JSON = "{\n" +
+        "  \"foo\": {\n" +
+        "    \"foo_boolean\": true,\n" +
+        "    \"bar\": {\n" +
+        "      \"bar_string\": [\n" +
+        "        \"bar-string-1\",\n" +
+        "        \"bar-string-2\",\n" +
+        "        \"bar-string-3\"\n" +
+        "      ],\n" +
+        "      \"bar_boolean\": [\n" +
+        "        true,\n" +
+        "        false\n" +
+        "      ],\n" +
+        "      \"bar_double\": [\n" +
+        "        1.7976931348623157E308,\n" +
+        "        4.9E-324\n" +
+        "      ],\n" +
+        "      \"bar_int\": [\n" +
+        "        2147483647,\n" +
+        "        -2147483648\n" +
+        "      ],\n" +
+        "      \"bar_long\": [\n" +
+        "        9223372036854775807,\n" +
+        "        -9223372036854775808\n" +
+        "      ]\n" +
+        "    },\n" +
+        "    \"foo_double\": 1.7976931348623157E308,\n" +
+        "    \"foo_int\": 2147483647,\n" +
+        "    \"foo_long\": 9223372036854775807,\n" +
+        "    \"foo_string\": \"foo-string\",\n" +
+        "    \"long_string\": \"%s\",\n" +
+        "    \"long_int_array\": [\n%s" +
+        "    ]\n" +
+        "  }\n" +
+        "}\n";
+
+    public static String sampleDeviceInfoJson() {
+        StringBuilder longStringSb = new StringBuilder();
+        StringBuilder longArraySb = new StringBuilder();
+        int lastNum = MAX_LENGTH - 1;
+        for (int i = 0; i < MAX_LENGTH; i++) {
+            longStringSb.append("a");
+            longArraySb.append(String.format("      %d%s\n", i, ((i == lastNum)? "" : ",")));
+        }
+        return String.format(SAMPLE_DEVICE_INFO_JSON,
+            longStringSb.toString(), longArraySb.toString());
+    }
+}
\ No newline at end of file
diff --git a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/SampleDeviceInfo.java b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/SampleDeviceInfo.java
index 8b3be40..7da9951 100644
--- a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/SampleDeviceInfo.java
+++ b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/SampleDeviceInfo.java
@@ -17,6 +17,8 @@
 
 import android.os.Bundle;
 
+import java.lang.StringBuilder;
+
 /**
  * Sample device info collector.
  */
@@ -55,6 +57,16 @@
         addResult("foo_int", Integer.MAX_VALUE);
         addResult("foo_long", Long.MAX_VALUE);
         addResult("foo_string", "foo-string");
+
+        StringBuilder sb = new StringBuilder();
+        int[] arr = new int[1001];
+        for (int i = 0; i < 1001; i++) {
+            sb.append("a");
+            arr[i] = i;
+        }
+        addResult("long_string", sb.toString());
+        addArray("long_int_array", arr);
+
         endGroup(); // foo
     }
 }