add test to check usb serial == Build.SERIAL

- follows cdd update for KLP
- checks matches of serial, property ro.serialno, Build.SERIAL, and USB serial
- also updated os.Build test regarding minimum length change
- lsusb should be installed in host to make this test pass: apt-get install usbutils

bug: 10298217
Change-Id: Ibe83dcec34924da7d7d08e3e34cbfa11550b3219
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 37f7ac6..2c25d3d 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -39,6 +39,7 @@
 	SignatureTest \
 	TestDeviceSetup \
 	CtsUiAutomatorApp \
+	CtsUsbSerialTestApp \
 	$(cts_security_apps_list)
 
 cts_external_packages := \
@@ -118,7 +119,8 @@
 	$(PTS_HOST_CASES) \
 	CtsAdbTests \
 	CtsAppSecurityTests \
-	CtsMonkeyTestCases
+	CtsMonkeyTestCases \
+	CtsUsbTests
 
 
 # Native test executables that need to have associated test XMLs.
diff --git a/hostsidetests/usb/Android.mk b/hostsidetests/usb/Android.mk
new file mode 100644
index 0000000..488acbb
--- /dev/null
+++ b/hostsidetests/usb/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2013 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := CtsUsbTests
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt ddmlib-prebuilt junit
+
+LOCAL_CTS_TEST_PACKAGE := android.usb
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+# Build the test APKs using their own makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/usb/SerialTestApp/Android.mk b/hostsidetests/usb/SerialTestApp/Android.mk
new file mode 100644
index 0000000..d36b98e
--- /dev/null
+++ b/hostsidetests/usb/SerialTestApp/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2013 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsUsbSerialTestApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/usb/SerialTestApp/AndroidManifest.xml b/hostsidetests/usb/SerialTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..0667d60
--- /dev/null
+++ b/hostsidetests/usb/SerialTestApp/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.usb.serialtest">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation
+        android:targetPackage="com.android.cts.usb.serialtest"
+        android:name="android.test.InstrumentationCtsTestRunner" />
+</manifest>
diff --git a/hostsidetests/usb/SerialTestApp/src/com/android/cts/usb/serialtest/UsbSerialTest.java b/hostsidetests/usb/SerialTestApp/src/com/android/cts/usb/serialtest/UsbSerialTest.java
new file mode 100644
index 0000000..a2b0c72
--- /dev/null
+++ b/hostsidetests/usb/SerialTestApp/src/com/android/cts/usb/serialtest/UsbSerialTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 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.cts.usb.serialtest;
+
+import android.os.Build;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+
+/**
+ * Device test which reads Build.SERIAL and just print it.
+ */
+public class UsbSerialTest extends AndroidTestCase {
+    private static final String TAG = "CtsUsbSerialTest";
+
+    public void testSerial() throws Exception {
+        Log.e(TAG, Build.SERIAL);
+    }
+}
diff --git a/hostsidetests/usb/src/com/android/cts/usb/TestUsbTest.java b/hostsidetests/usb/src/com/android/cts/usb/TestUsbTest.java
new file mode 100644
index 0000000..f53d210
--- /dev/null
+++ b/hostsidetests/usb/src/com/android/cts/usb/TestUsbTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2013 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.cts.usb;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.IFileEntry;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.result.TestRunResult;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.RunUtil;
+import com.android.tradefed.util.StreamUtil;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Functional tests for usb connection
+ */
+public class TestUsbTest extends DeviceTestCase implements IBuildReceiver {
+
+    private static final String LOG_TAG = "TestUsbTest";
+    private static final String CTS_RUNNER = "android.test.InstrumentationCtsTestRunner";
+    private static final String PACKAGE_NAME = "com.android.cts.usb.serialtest";
+    private static final String APK_NAME="CtsUsbSerialTestApp.apk";
+    private ITestDevice mDevice;
+    private CtsBuildHelper mBuild;
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDevice = getDevice();
+        mDevice.uninstallPackage(PACKAGE_NAME);
+        File app = mBuild.getTestApp(APK_NAME);
+        mDevice.installPackage(app, false);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mDevice.uninstallPackage(PACKAGE_NAME);
+    }
+
+    /**
+     * Check if adb serial number, USB serial number, ro.serialno, and android.os.Build.SERIAL
+     * all matches and meets the format requirement [a-zA-Z0-9]{6,20}
+     */
+    public void testUsbSerial() throws Exception {
+        String adbSerial = mDevice.getSerialNumber().toLowerCase().trim();
+        if (adbSerial.startsWith("emulator-")) {
+            return;
+        }
+        if (mDevice.isAdbTcp()) { // adb over WiFi, no point checking it
+            return;
+        }
+
+        String roSerial = mDevice.executeShellCommand("getprop ro.serialno").toLowerCase().
+                trim();
+        assertEquals("adb serial != ro.serialno" , adbSerial, roSerial);
+
+        CommandResult result = RunUtil.getDefault().runTimedCmd(5000, "lsusb", "-v");
+        assertTrue("lsusb -v failed", result.getStatus() == CommandStatus.SUCCESS);
+        String lsusbOutput = result.getStdout();
+        Pattern pattern = Pattern.compile("^\\s+iSerial\\s+\\d+\\s+([a-zA-Z0-9]{6,20})",
+                Pattern.MULTILINE);
+        Matcher matcher = pattern.matcher(lsusbOutput);
+        String usbSerial = "";
+        while (matcher.find()) {
+            String currentSerial = matcher.group(1).toLowerCase();
+            if (adbSerial.compareTo(currentSerial) == 0) {
+                usbSerial = currentSerial;
+                break;
+            }
+        }
+        assertEquals("usb serial != adb serial" , usbSerial, adbSerial);
+
+        // now check Build.SERIAL
+        clearLogCat();
+        CollectingTestListener listener = new CollectingTestListener();
+        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(PACKAGE_NAME, CTS_RUNNER,
+                mDevice.getIDevice());
+        mDevice.runInstrumentationTests(testRunner, listener);
+        TestRunResult runResult = listener.getCurrentRunResults();
+        if (runResult.isRunFailure()) {
+            fail(runResult.getRunFailureMessage());
+        }
+        String logs = mDevice.executeAdbCommand("logcat", "-d", "CtsUsbSerialTest:W", "*:S");
+        pattern = Pattern.compile("^.*CtsUsbSerialTest\\(.*\\):\\s+([a-zA-Z0-9]{6,20})",
+                Pattern.MULTILINE);
+        matcher = pattern.matcher(logs);
+        String buildSerial = "";
+        while (matcher.find()) {
+            String currentSerial = matcher.group(1).toLowerCase();
+            if (usbSerial.compareTo(currentSerial) == 0) {
+                buildSerial = currentSerial;
+                break;
+            }
+        }
+        assertEquals("usb serial != Build.SERIAL" , usbSerial, buildSerial);
+    }
+
+    private void clearLogCat() throws DeviceNotAvailableException {
+        mDevice.executeAdbCommand("logcat", "-c");
+    }
+}
diff --git a/tests/tests/os/src/android/os/cts/BuildTest.java b/tests/tests/os/src/android/os/cts/BuildTest.java
index fae7d1f..3f6743e 100644
--- a/tests/tests/os/src/android/os/cts/BuildTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildTest.java
@@ -157,7 +157,7 @@
     private static final Pattern PRODUCT_PATTERN =
         Pattern.compile("^([0-9A-Za-z._-]+)$");
     private static final Pattern SERIAL_NUMBER_PATTERN =
-        Pattern.compile("^([0-9A-Za-z]{0,20})$");
+        Pattern.compile("^([0-9A-Za-z]{6,20})$");
     private static final Pattern TAGS_PATTERN =
         Pattern.compile("^([0-9A-Za-z.,_-]+)$");
     private static final Pattern TYPE_PATTERN =