Update UI logging in Sensor CtsVerifier to improve its readability.

Change-Id: I470c7ad2cc248912ebf418ee5e40711313a9bd78
diff --git a/apps/CtsVerifier/res/layout/snsr_error.xml b/apps/CtsVerifier/res/layout/snsr_error.xml
new file mode 100644
index 0000000..4b3869a
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/snsr_error.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingBottom="@dimen/snsr_boxed_padding_bottom"
+        android:paddingTop="@dimen/snsr_boxed_padding_top"
+        android:paddingLeft="@dimen/snsr_boxed_padding_left"
+        android:paddingRight="@dimen/snsr_boxed_padding_right"
+        android:background="@color/snsr_error_background"
+        android:textColor="@color/snsr_error" />
diff --git a/apps/CtsVerifier/res/layout/snsr_information.xml b/apps/CtsVerifier/res/layout/snsr_information.xml
new file mode 100644
index 0000000..4b4a4cb
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/snsr_information.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingBottom="@dimen/snsr_boxed_padding_bottom"
+        android:paddingTop="@dimen/snsr_boxed_padding_top"
+        android:paddingLeft="@dimen/snsr_boxed_padding_left"
+        android:paddingRight="@dimen/snsr_boxed_padding_right"
+        android:background="@color/snsr_information_background"
+        android:textColor="@color/snsr_information" />
diff --git a/apps/CtsVerifier/res/layout/snsr_instruction.xml b/apps/CtsVerifier/res/layout/snsr_instruction.xml
new file mode 100644
index 0000000..9a48cf6
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/snsr_instruction.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingBottom="@dimen/snsr_log_padding_bottom"
+        android:paddingTop="@dimen/snsr_log_padding_top"
+        android:paddingLeft="@dimen/snsr_log_padding_left"
+        android:paddingRight="@dimen/snsr_log_padding_right" />
diff --git a/apps/CtsVerifier/res/layout/snsr_rotvec.xml b/apps/CtsVerifier/res/layout/snsr_rotvec.xml
index 1a896db..5d7bc8b 100644
--- a/apps/CtsVerifier/res/layout/snsr_rotvec.xml
+++ b/apps/CtsVerifier/res/layout/snsr_rotvec.xml
@@ -16,28 +16,39 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="vertical"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="match_parent" >
 
-    <TextView android:id="@+id/log_text"
-              android:layout_height="0dp"
-              android:layout_width="wrap_content"
-              android:layout_weight="1"
-              android:paddingBottom="5dip"
-              android:paddingLeft="10dip"
-              android:paddingRight="10dip"
-              android:paddingTop="5dip"
-              android:scrollbars="vertical" />
+    <ScrollView android:id="@+id/log_scroll_view"
+                android:layout_height="0dp"
+                android:layout_width="wrap_content"
+                android:layout_weight="1" >
+
+        <LinearLayout android:id="@+id/log_layout"
+                      android:orientation="vertical"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content" />
+
+    </ScrollView>
 
     <android.opengl.GLSurfaceView android:id="@+id/gl_surface_view"
             android:layout_width="match_parent"
             android:layout_height="0dp"
             android:layout_weight="2" />
 
-    <Button android:id="@+id/next_button"
-            android:layout_gravity="center_horizontal"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_weight="0"
-            android:text="@string/next_button_text" />
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="@dimen/snsr_view_padding_bottom"
+        android:paddingTop="@dimen/snsr_view_padding_top" >
+
+        <Button android:id="@+id/next_button"
+                android:layout_gravity="center_horizontal"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/next_button_text" />
+
+    </LinearLayout>
 
 </LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/snsr_semi_auto_test.xml b/apps/CtsVerifier/res/layout/snsr_semi_auto_test.xml
index c816021..7b0d977 100644
--- a/apps/CtsVerifier/res/layout/snsr_semi_auto_test.xml
+++ b/apps/CtsVerifier/res/layout/snsr_semi_auto_test.xml
@@ -16,26 +16,33 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="vertical"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="match_parent" >
 
-    <TextView android:id="@+id/log_text"
-              android:layout_height="0dp"
-              android:layout_width="wrap_content"
-              android:layout_weight="1"
-              android:layout_gravity="bottom"
-              android:paddingBottom="5dip"
-              android:paddingLeft="10dip"
-              android:paddingRight="10dip"
-              android:paddingTop="5dip"
-              android:scrollbars="vertical"
-            />
+    <ScrollView android:id="@+id/log_scroll_view"
+        android:layout_height="0dp"
+        android:layout_width="wrap_content"
+        android:layout_weight="1" >
 
-    <Button android:id="@+id/next_button"
-            android:layout_gravity="center_horizontal"
-            android:layout_height="wrap_content"
+        <LinearLayout android:id="@+id/log_layout"
+            android:orientation="vertical"
             android:layout_width="wrap_content"
-            android:paddingBottom="5dip"
-            android:text="@string/next_button_text"
-            />
+            android:layout_height="wrap_content" />
+
+    </ScrollView>
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="@dimen/snsr_view_padding_bottom"
+        android:paddingTop="@dimen/snsr_view_padding_top" >
+
+        <Button android:id="@+id/next_button"
+                android:layout_gravity="center_horizontal"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/next_button_text" />
+
+    </LinearLayout>
 
 </LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/snsr_success.xml b/apps/CtsVerifier/res/layout/snsr_success.xml
new file mode 100644
index 0000000..7aaad57
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/snsr_success.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingBottom="@dimen/snsr_boxed_padding_bottom"
+        android:paddingTop="@dimen/snsr_boxed_padding_top"
+        android:paddingLeft="@dimen/snsr_boxed_padding_left"
+        android:paddingRight="@dimen/snsr_boxed_padding_right"
+        android:background="@color/snsr_success_background"
+        android:textColor="@color/snsr_success" />
diff --git a/apps/CtsVerifier/res/layout/snsr_test_title.xml b/apps/CtsVerifier/res/layout/snsr_test_title.xml
new file mode 100644
index 0000000..69e9fad
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/snsr_test_title.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingBottom="@dimen/snsr_boxed_padding_bottom"
+        android:paddingTop="@dimen/snsr_boxed_padding_top"
+        android:paddingLeft="@dimen/snsr_boxed_padding_left"
+        android:paddingRight="@dimen/snsr_boxed_padding_right"
+        android:textStyle="bold" />
diff --git a/apps/CtsVerifier/res/layout/snsr_warning.xml b/apps/CtsVerifier/res/layout/snsr_warning.xml
new file mode 100644
index 0000000..6f102bb
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/snsr_warning.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingBottom="@dimen/snsr_boxed_padding_bottom"
+        android:paddingTop="@dimen/snsr_boxed_padding_top"
+        android:paddingLeft="@dimen/snsr_boxed_padding_left"
+        android:paddingRight="@dimen/snsr_boxed_padding_right"
+        android:background="@color/snsr_warning_background"
+        android:textColor="@color/snsr_warning" />
diff --git a/apps/CtsVerifier/res/values/colors.xml b/apps/CtsVerifier/res/values/colors.xml
index 707255b..c855d5f 100644
--- a/apps/CtsVerifier/res/values/colors.xml
+++ b/apps/CtsVerifier/res/values/colors.xml
@@ -2,4 +2,14 @@
 <resources>
     <color name="red">#F00</color>
     <color name="green">#0F0</color>
+
+    <!-- Sensor tests log colors -->
+    <color name="snsr_error_background">#F5D1D1</color>
+    <color name="snsr_error">#AA0404</color>
+    <color name="snsr_success_background">#DDF6D2</color>
+    <color name="snsr_success">#467701</color>
+    <color name="snsr_warning_background">#F0E4B6</color>
+    <color name="snsr_warning">#75540C</color>
+    <color name="snsr_information_background">#D0D2F6</color>
+    <color name="snsr_information">#41576B</color>
 </resources>
diff --git a/apps/CtsVerifier/res/values/dimens.xml b/apps/CtsVerifier/res/values/dimens.xml
index 00257a9..b1367f7 100644
--- a/apps/CtsVerifier/res/values/dimens.xml
+++ b/apps/CtsVerifier/res/values/dimens.xml
@@ -18,4 +18,22 @@
     <dimen name="widget_margin_bottom">8dp</dimen>
     <dimen name="widget_margin_left">8dp</dimen>
     <dimen name="widget_margin_right">8dp</dimen>
+
+    <!-- Sensor logging values -->
+
+    <dimen name="snsr_boxed_padding_top">15dp</dimen>
+    <dimen name="snsr_boxed_padding_bottom">15dp</dimen>
+    <dimen name="snsr_boxed_padding_left">15dp</dimen>
+    <dimen name="snsr_boxed_padding_right">15dp</dimen>
+
+    <dimen name="snsr_log_padding_top">1dp</dimen>
+    <dimen name="snsr_log_padding_bottom">1dp</dimen>
+    <dimen name="snsr_log_padding_left">8dp</dimen>
+    <dimen name="snsr_log_padding_right">8dp</dimen>
+
+    <dimen name="snsr_view_padding_top">8dp</dimen>
+    <dimen name="snsr_view_padding_bottom">8dp</dimen>
+    <dimen name="snsr_view_padding_left">8dp</dimen>
+    <dimen name="snsr_view_padding_right">8dp</dimen>
+
 </resources>
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BaseSensorTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BaseSensorTestActivity.java
index 429be27..9a5fb6f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BaseSensorTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BaseSensorTestActivity.java
@@ -33,13 +33,11 @@
 import android.os.Bundle;
 import android.os.Vibrator;
 import android.provider.Settings;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
-import android.text.method.ScrollingMovementMethod;
-import android.text.style.ForegroundColorSpan;
 import android.util.Log;
 import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
 import android.widget.TextView;
 
 import java.lang.reflect.InvocationTargetException;
@@ -73,7 +71,8 @@
     protected final SensorFeaturesDeactivator mSensorFeaturesDeactivator;
     private final Semaphore mSemaphore = new Semaphore(0);
 
-    private TextView mLogView;
+    private ScrollView mLogScrollView;
+    private LinearLayout mLogLayout;
     private View mNextView;
     private Thread mWorkerThread;
 
@@ -97,10 +96,10 @@
         super.onCreate(savedInstanceState);
         setContentView(mLayoutId);
 
-        mLogView = (TextView) this.findViewById(R.id.log_text);
-        mNextView = this.findViewById(R.id.next_button);
+        mLogScrollView = (ScrollView) findViewById(R.id.log_scroll_view);
+        mLogLayout = (LinearLayout) findViewById(R.id.log_layout);
+        mNextView = findViewById(R.id.next_button);
         mNextView.setOnClickListener(this);
-        mLogView.setMovementMethod(new ScrollingMovementMethod());
 
         updateButton(false /*enabled*/);
         mWorkerThread = new Thread(this);
@@ -133,6 +132,8 @@
             logTestDetails(testDetails.result, testDetails.summary);
             overallTestResults.append(testDetails.toString() + "\n");
         }
+        appendText(R.string.snsr_test_complete);
+
         // log to screen and save the overall test summary (activity level)
         SensorTestDetails testDetails = getOverallTestDetails();
         logTestDetails(testDetails.result, testDetails.summary);
@@ -146,7 +147,6 @@
             Log.e(LOG_TAG, "An error occurred on Activity CleanUp.", e);
         }
 
-        appendText(R.string.snsr_test_complete);
         waitForUser();
         finish();
     }
@@ -195,33 +195,36 @@
     }
 
     private void logTestDetails(SensorTestResult testResult, String testSummary) {
-        int textColor;
+        int textViewResId;
+        int testResultResId;
         int logPriority;
-        String testResultString;
         switch(testResult) {
             case SKIPPED:
-                textColor = Color.YELLOW;
+                textViewResId = R.layout.snsr_warning;
+                testResultResId = R.string.snsr_test_skipped;
                 logPriority = Log.INFO;
-                testResultString = getString(R.string.snsr_test_skipped);
                 break;
             case PASS:
-                textColor = Color.GREEN;
+                textViewResId = R.layout.snsr_success;
+                testResultResId = R.string.snsr_test_pass;
                 logPriority = Log.DEBUG;
-                testResultString = getString(R.string.snsr_test_pass);
                 break;
             case FAIL:
-                textColor = Color.RED;
+                textViewResId = R.layout.snsr_error;
+                testResultResId = R.string.snsr_test_fail;
                 logPriority = Log.ERROR;
-                testResultString = getString(R.string.snsr_test_fail);
                 break;
             default:
                 throw new InvalidParameterException("Unrecognized testResult.");
         }
         if (TextUtils.isEmpty(testSummary)) {
-            testSummary = testResultString;
+            testSummary = getString(testResultResId);
         }
-        appendText("\n" + testSummary, textColor);
         Log.println(logPriority, LOG_TAG, testSummary);
+
+        TextAppender textAppender = new TextAppender(textViewResId);
+        textAppender.setText(testSummary);
+        textAppender.append();
     }
 
     /**
@@ -240,29 +243,36 @@
      */
     protected void activityCleanUp() throws Throwable {}
 
+    @Deprecated
     protected void appendText(int resId, int textColor) {
-        appendText(getString(resId), textColor);
+        appendText(resId);
     }
 
     @Deprecated
     protected void appendText(String text, int textColor) {
-        this.runOnUiThread(new TextAppender(mLogView, text, textColor));
+        appendText(text);
     }
 
+    @Deprecated
     protected void appendText(int resId) {
-        appendText(getString(resId));
+        TextAppender textAppender = new TextAppender(R.layout.snsr_instruction);
+        textAppender.setText(resId);
+        textAppender.append();
     }
 
     @Deprecated
     protected void appendText(String text) {
-        this.runOnUiThread(new TextAppender(mLogView, text));
+        TextAppender textAppender = new TextAppender(R.layout.snsr_instruction);
+        textAppender.setText(text);
+        textAppender.append();
     }
 
+    @Deprecated
     protected void clearText() {
         this.runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                mLogView.setText("");
+                mLogLayout.removeAllViews();
             }
         });
     }
@@ -333,10 +343,14 @@
 
     private SensorTestDetails executeTest(Method testMethod) {
         SensorTestDetails testDetails = new SensorTestDetails();
-        testDetails.name = String.format("%s#%s", getTestClassName(), testMethod.getName());
+        String testMethodName = testMethod.getName();
+        testDetails.name = String.format("%s#%s", getTestClassName(), testMethodName);
 
         try {
-            appendText(getString(R.string.snsr_executing_test, testDetails.name));
+            TextAppender textAppender = new TextAppender(R.layout.snsr_test_title);
+            textAppender.setText(testMethodName);
+            textAppender.append();
+
             testDetails.summary = (String) testMethod.invoke(this);
             testDetails.result = SensorTestResult.PASS;
             ++mTestPassedCounter;
@@ -387,29 +401,34 @@
         return mTestClass.getName();
     }
 
-    private class TextAppender implements Runnable {
+    private class TextAppender {
         private final TextView mTextView;
-        private final SpannableStringBuilder mMessageBuilder;
 
-        public TextAppender(TextView textView, String message, int textColor) {
-            mTextView = textView;
-            mMessageBuilder = new SpannableStringBuilder(message + "\n");
-
-            ForegroundColorSpan colorSpan = new ForegroundColorSpan(textColor);
-            mMessageBuilder.setSpan(
-                    colorSpan,
-                    0 /*start*/,
-                    message.length(),
-                    Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+        public TextAppender(int textViewResId) {
+            mTextView = (TextView) getLayoutInflater().inflate(textViewResId, null /* viewGroup */);
         }
 
-        public TextAppender(TextView textView, String message) {
-            this(textView, message, textView.getCurrentTextColor());
+        public void setText(String text) {
+            mTextView.setText(text);
         }
 
-        @Override
-        public void run() {
-            mTextView.append(mMessageBuilder);
+        public void setText(int textResId) {
+            mTextView.setText(textResId);
+        }
+
+        public void append() {
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mLogLayout.addView(mTextView);
+                    mLogScrollView.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            mLogScrollView.fullScroll(View.FOCUS_DOWN);
+                        }
+                    });
+                }
+            });
         }
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/StepCounterTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/StepCounterTestActivity.java
index fd1f057..cc75a11 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/StepCounterTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/StepCounterTestActivity.java
@@ -71,7 +71,7 @@
         mSensorStepCounter = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
         mSensorStepDetector = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
 
-        View screen = findViewById(R.id.log_text);
+        View screen = findViewById(R.id.log_layout);
         screen.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {