RTL Ordering of visual elements in LinearLayout

- also update unit tests for testing LinearLayout

Change-Id: I0794d48c45a8fd4a899fdf6f6a1d05485b416e1a
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 86fefaf..bac849e 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -1331,7 +1331,7 @@
     void layoutVertical() {
         final int paddingLeft = mPaddingLeft;
 
-        int childTop = mPaddingTop;
+        int childTop;
         int childLeft;
         
         // Where right end of child should go
@@ -1346,19 +1346,21 @@
         final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
         final int minorGravity = mGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
 
-        if (majorGravity != Gravity.TOP) {
-           switch (majorGravity) {
-               case Gravity.BOTTOM:
-                   // mTotalLength contains the padding already, we add the top
-                   // padding to compensate
-                   childTop = mBottom - mTop + mPaddingTop - mTotalLength;
-                   break;
+        switch (majorGravity) {
+           case Gravity.BOTTOM:
+               // mTotalLength contains the padding already
+               childTop = mPaddingTop + mBottom - mTop - mTotalLength;
+               break;
 
-               case Gravity.CENTER_VERTICAL:
-                   childTop += ((mBottom - mTop)  - mTotalLength) / 2;
-                   break;
-           }
-           
+               // mTotalLength contains the padding already
+           case Gravity.CENTER_VERTICAL:
+               childTop = mPaddingTop + (mBottom - mTop - mTotalLength) / 2;
+               break;
+
+           case Gravity.TOP:
+           default:
+               childTop = mPaddingTop;
+               break;
         }
 
         for (int i = 0; i < count; i++) {
@@ -1376,12 +1378,8 @@
                 if (gravity < 0) {
                     gravity = minorGravity;
                 }
-                
-                switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
-                    case Gravity.LEFT:
-                        childLeft = paddingLeft + lp.leftMargin;
-                        break;
 
+                switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
                     case Gravity.CENTER_HORIZONTAL:
                         childLeft = paddingLeft + ((childSpace - childWidth) / 2)
                                 + lp.leftMargin - lp.rightMargin;
@@ -1390,11 +1388,13 @@
                     case Gravity.RIGHT:
                         childLeft = childRight - childWidth - lp.rightMargin;
                         break;
+
+                    case Gravity.LEFT:
                     default:
-                        childLeft = paddingLeft;
+                        childLeft = paddingLeft + lp.leftMargin;
                         break;
                 }
-                
+
                 if (hasDividerBeforeChildAt(i)) {
                     childTop += mDividerHeight;
                 }
@@ -1418,10 +1418,11 @@
      * @see #onLayout(boolean, int, int, int, int)
      */
     void layoutHorizontal() {
+        final boolean isLayoutRtl = isLayoutRtl();
         final int paddingTop = mPaddingTop;
 
         int childTop;
-        int childLeft = mPaddingLeft;
+        int childLeft;
         
         // Where bottom of child should go
         final int height = mBottom - mTop;
@@ -1440,25 +1441,37 @@
         final int[] maxAscent = mMaxAscent;
         final int[] maxDescent = mMaxDescent;
 
-        if (majorGravity != Gravity.LEFT) {
-            switch (majorGravity) {
-                case Gravity.RIGHT:
-                    // mTotalLength contains the padding already, we add the left
-                    // padding to compensate
-                    childLeft = mRight - mLeft + mPaddingLeft - mTotalLength;
-                    break;
+        switch (majorGravity) {
+            case Gravity.RIGHT:
+                // mTotalLength contains the padding already
+                childLeft = mPaddingLeft + mRight - mLeft - mTotalLength;
+                break;
 
-                case Gravity.CENTER_HORIZONTAL:
-                    childLeft += ((mRight - mLeft) - mTotalLength) / 2;
-                    break;
-            }
+            case Gravity.CENTER_HORIZONTAL:
+                // mTotalLength contains the padding already
+                childLeft = mPaddingLeft + (mRight - mLeft - mTotalLength) / 2;
+                break;
+
+            case Gravity.LEFT:
+            default:
+                childLeft = mPaddingLeft;
+                break;
+        }
+
+        int start = 0;
+        int dir = 1;
+        //In case of RTL, start drawing from the last child.
+        if (isLayoutRtl) {
+            start = count - 1;
+            dir = -1;
         }
 
         for (int i = 0; i < count; i++) {
-            final View child = getVirtualChildAt(i);
+            int childIndex = start + dir * i;
+            final View child = getVirtualChildAt(childIndex);
 
             if (child == null) {
-                childLeft += measureNullChild(i);
+                childLeft += measureNullChild(childIndex);
             } else if (child.getVisibility() != GONE) {
                 final int childWidth = child.getMeasuredWidth();
                 final int childHeight = child.getMeasuredHeight();
@@ -1512,7 +1525,7 @@
                         break;
                 }
 
-                if (hasDividerBeforeChildAt(i)) {
+                if (hasDividerBeforeChildAt(childIndex)) {
                     childLeft += mDividerWidth;
                 }
 
@@ -1522,7 +1535,7 @@
                 childLeft += childWidth + lp.rightMargin +
                         getNextLocationOffset(child);
 
-                i += getChildrenSkipCount(child, i);
+                i += getChildrenSkipCount(child, childIndex);
             }
         }
     }
diff --git a/tests/BiDiTests/AndroidManifest.xml b/tests/BiDiTests/AndroidManifest.xml
index 727f980..8a77519 100644
--- a/tests/BiDiTests/AndroidManifest.xml
+++ b/tests/BiDiTests/AndroidManifest.xml
@@ -14,24 +14,49 @@
      limitations under the License.
 -->
 
-<!-- Declare the contents of this Android application.  The namespace
-     attribute brings in the Android platform namespace, and the package
-     supplies a unique name for the application.  When writing your
-     own application, the package name must be changed from "com.example.*"
-     to come from a domain that you own or have control over. -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.bidi"
     android:versionCode="1"
     android:versionName="1.0">
 
     <application android:label="BiDiTests">
-        <activity android:name="BiDiTestActivity"
-                android:windowSoftInputMode="stateAlwaysHidden">
+
+        <activity android:name=".BiDiTestActivity"
+            android:windowSoftInputMode="stateAlwaysHidden">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
 
+        <activity android:name=".BiDiTestBasicActivity"
+                android:windowSoftInputMode="stateAlwaysHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".BiDiTestCanvasActivity"
+                  android:windowSoftInputMode="stateAlwaysHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".BiDiTestLinearLayoutLtrActivity"
+                  android:windowSoftInputMode="stateAlwaysHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".BiDiTestLinearLayoutRtlActivity"
+                  android:windowSoftInputMode="stateAlwaysHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+
     </application>
+
 </manifest>
\ No newline at end of file
diff --git a/tests/BiDiTests/res/layout/biditest_main.xml b/tests/BiDiTests/res/layout/basic.xml
similarity index 79%
rename from tests/BiDiTests/res/layout/biditest_main.xml
rename to tests/BiDiTests/res/layout/basic.xml
index 044a355..c4807ff 100644
--- a/tests/BiDiTests/res/layout/biditest_main.xml
+++ b/tests/BiDiTests/res/layout/basic.xml
@@ -20,7 +20,7 @@
     android:layout_height="match_parent">
 
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="horizontal"
+        android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="wrap_content">
 
@@ -39,7 +39,7 @@
                   android:text="@string/textview_text"
         />
 
-        <EditText android:id="@+id/textview"
+        <EditText android:id="@+id/edittext"
                   android:layout_height="wrap_content"
                   android:layout_width="match_parent"
                   android:textSize="32dip"
@@ -47,16 +47,4 @@
 
     </LinearLayout>
 
-    <SeekBar android:id="@+id/seekbar"
-               android:layout_height="wrap_content"
-               android:layout_width="match_parent"
-               />
-
-    <view class="com.android.bidi.BiDiTestView"
-        android:id="@+id/main"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:background="#FF0000"
-    />
-
 </LinearLayout>
\ No newline at end of file
diff --git a/tests/BiDiTests/res/layout/canvas.xml b/tests/BiDiTests/res/layout/canvas.xml
new file mode 100644
index 0000000..371cc23
--- /dev/null
+++ b/tests/BiDiTests/res/layout/canvas.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <SeekBar android:id="@+id/seekbar"
+               android:layout_height="wrap_content"
+               android:layout_width="match_parent"
+               />
+
+    <view class="com.android.bidi.BiDiTestView"
+        android:id="@+id/testview"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="#FF0000"
+    />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/BiDiTests/res/layout/linear_layout_ltr.xml b/tests/BiDiTests/res/layout/linear_layout_ltr.xml
new file mode 100644
index 0000000..a95fb0e
--- /dev/null
+++ b/tests/BiDiTests/res/layout/linear_layout_ltr.xml
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/layouttest"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:horizontalDirection="ltr">
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:horizontalDirection="inherit">
+
+       <Button android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:text="@string/button1_text"
+               android:textSize="32dip"
+        />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="32dip"
+                  android:text="@string/textview_text"
+        />
+
+        <Button android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/button2_text"
+                android:textSize="32dip"
+         />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:horizontalDirection="ltr">
+
+       <Button android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:text="@string/button1_text"
+               android:textSize="32dip"
+        />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="32dip"
+                  android:text="@string/textview_text"
+        />
+
+        <Button android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/button2_text"
+                android:textSize="32dip"
+         />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:horizontalDirection="rtl">
+
+       <Button android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:text="@string/button1_text"
+               android:textSize="32dip"
+        />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="32dip"
+                  android:text="@string/textview_text"
+        />
+
+        <Button android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/button2_text"
+                android:textSize="32dip"
+         />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:horizontalDirection="inherit">
+
+       <Button android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:text="@string/button1_text"
+               android:textSize="32dip"
+        />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="32dip"
+                  android:text="@string/textview_text"
+        />
+
+        <Button android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/button2_text"
+                android:textSize="32dip"
+         />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:horizontalDirection="ltr">
+
+       <Button android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:text="@string/button1_text"
+               android:textSize="32dip"
+        />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="32dip"
+                  android:text="@string/textview_text"
+        />
+
+        <Button android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/button2_text"
+                android:textSize="32dip"
+         />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:horizontalDirection="rtl">
+
+       <Button android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:text="@string/button1_text"
+               android:textSize="32dip"
+        />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="32dip"
+                  android:text="@string/textview_text"
+        />
+
+        <Button android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/button2_text"
+                android:textSize="32dip"
+         />
+
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/BiDiTests/res/layout/linear_layout_rtl.xml b/tests/BiDiTests/res/layout/linear_layout_rtl.xml
new file mode 100644
index 0000000..0d60950
--- /dev/null
+++ b/tests/BiDiTests/res/layout/linear_layout_rtl.xml
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/layouttest"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:horizontalDirection="rtl">
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:horizontalDirection="inherit">
+
+       <Button android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:text="@string/button1_text"
+               android:textSize="32dip"
+        />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="32dip"
+                  android:text="@string/textview_text"
+        />
+
+        <Button android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/button2_text"
+                android:textSize="32dip"
+         />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:horizontalDirection="ltr">
+
+       <Button android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:text="@string/button1_text"
+               android:textSize="32dip"
+        />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="32dip"
+                  android:text="@string/textview_text"
+        />
+
+        <Button android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/button2_text"
+                android:textSize="32dip"
+         />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:horizontalDirection="rtl">
+
+       <Button android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:text="@string/button1_text"
+               android:textSize="32dip"
+        />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="32dip"
+                  android:text="@string/textview_text"
+        />
+
+        <Button android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/button2_text"
+                android:textSize="32dip"
+         />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:horizontalDirection="inherit">
+
+       <Button android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:text="@string/button1_text"
+               android:textSize="32dip"
+        />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="32dip"
+                  android:text="@string/textview_text"
+        />
+
+        <Button android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/button2_text"
+                android:textSize="32dip"
+         />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:horizontalDirection="ltr">
+
+       <Button android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:text="@string/button1_text"
+               android:textSize="32dip"
+        />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="32dip"
+                  android:text="@string/textview_text"
+        />
+
+        <Button android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/button2_text"
+                android:textSize="32dip"
+         />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:horizontalDirection="rtl">
+
+       <Button android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:text="@string/button1_text"
+               android:textSize="32dip"
+        />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="32dip"
+                  android:text="@string/textview_text"
+        />
+
+        <Button android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:text="@string/button2_text"
+                android:textSize="32dip"
+         />
+
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/BiDiTests/res/layout/main.xml b/tests/BiDiTests/res/layout/main.xml
new file mode 100644
index 0000000..e39d1d6
--- /dev/null
+++ b/tests/BiDiTests/res/layout/main.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/tabhost"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:padding="5dp">
+
+        <TabWidget
+            android:id="@android:id/tabs"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content" />
+
+        <FrameLayout
+            android:id="@android:id/tabcontent"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:padding="5dp" />
+
+    </LinearLayout>
+
+</TabHost>
diff --git a/tests/BiDiTests/res/values/strings.xml b/tests/BiDiTests/res/values/strings.xml
index c272df1..3795d4b 100644
--- a/tests/BiDiTests/res/values/strings.xml
+++ b/tests/BiDiTests/res/values/strings.xml
@@ -14,6 +14,9 @@
 -->
 <resources>
     <string name="button_text">Button</string>
+    <string name="button1_text">Button1</string>
+    <string name="button2_text">Button2</string>
+    <string name="button_requestlayout_text">Request Layout</string>
     <string name="textview_text">This is a text for a TextView</string>
     <string name="edittext_text">mmmmmmmmmmmmmmmmmmmmmmmm</string>
     <string name="normal_text">Normal String</string>
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
index 6c71574..0d9b4f7 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
@@ -16,56 +16,43 @@
 
 package com.android.bidi;
 
-import android.app.Activity;
+import android.app.TabActivity;
+import android.content.Intent;
 import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.widget.SeekBar;
+import android.widget.TabHost;
 
-import static com.android.bidi.BiDiTestConstants.FONT_MIN_SIZE;
-import static com.android.bidi.BiDiTestConstants.FONT_MAX_SIZE;
-
-public class BiDiTestActivity extends Activity {
-
-    static final String TAG = "BiDiTestActivity";
-
-    static final int INIT_TEXT_SIZE = (FONT_MAX_SIZE - FONT_MIN_SIZE) / 2;
-
-    private BiDiTestView textView;
-    private SeekBar textSizeSeekBar;
+public class BiDiTestActivity extends TabActivity {
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        setContentView(R.layout.biditest_main);
+        setContentView(R.layout.main);
 
-        textView = (BiDiTestView) findViewById(R.id.main);
-        textView.setCurrentTextSize(INIT_TEXT_SIZE);
+        TabHost tabHost = getTabHost();
+        TabHost.TabSpec spec;
+        Intent intent;
 
-        textSizeSeekBar = (SeekBar) findViewById(R.id.seekbar);
-        textSizeSeekBar.setProgress(INIT_TEXT_SIZE);
-        textSizeSeekBar.setMax(FONT_MAX_SIZE - FONT_MIN_SIZE);
+        // Create an Intent to launch an Activity for the tab (to be reused)
+        intent = new Intent().setClass(this, BiDiTestBasicActivity.class);
 
-        textSizeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
-            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-                textView.setCurrentTextSize(FONT_MIN_SIZE + progress);
-            }
+        // Initialize a TabSpec for each tab and add it to the TabHost
+        spec = tabHost.newTabSpec("basic").setIndicator("Basic").setContent(intent);
+        tabHost.addTab(spec);
 
-            public void onStartTrackingTouch(SeekBar seekBar) {
-            }
+        // Do the same for the other tabs
+        intent = new Intent().setClass(this, BiDiTestCanvasActivity.class);
+        spec = tabHost.newTabSpec("canvas").setIndicator("Canvas").setContent(intent);
+        tabHost.addTab(spec);
 
-            public void onStopTrackingTouch(SeekBar seekBar) {
-            }
-        });
-    }
+        intent = new Intent().setClass(this, BiDiTestLinearLayoutLtrActivity.class);
+        spec = tabHost.newTabSpec("layout-ltr").setIndicator("LinearLayout LTR").setContent(intent);
+        tabHost.addTab(spec);
 
-    @Override
-    protected void onResume() {
-        super.onResume();
-    }
+        intent = new Intent().setClass(this, BiDiTestLinearLayoutRtlActivity.class);
+        spec = tabHost.newTabSpec("layout-rtl").setIndicator("LinearLayout RTL").setContent(intent);
+        tabHost.addTab(spec);
 
-    public void onButtonClick(View v) {
-        Log.v(TAG, "onButtonClick");
+        tabHost.setCurrentTab(0);
     }
 }
\ No newline at end of file
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestBasicActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestBasicActivity.java
new file mode 100644
index 0000000..2a8de04
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestBasicActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 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.bidi;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class BiDiTestBasicActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.basic);
+    }
+}
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestCanvasActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestCanvasActivity.java
new file mode 100644
index 0000000..3ab75d5
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestCanvasActivity.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 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.bidi;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.SeekBar;
+
+import static com.android.bidi.BiDiTestConstants.FONT_MAX_SIZE;
+import static com.android.bidi.BiDiTestConstants.FONT_MIN_SIZE;
+
+public class BiDiTestCanvasActivity extends Activity {
+
+    static final int INIT_TEXT_SIZE = (FONT_MAX_SIZE - FONT_MIN_SIZE) / 2;
+
+    private BiDiTestView testView;
+    private SeekBar textSizeSeekBar;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.canvas);
+
+        testView = (BiDiTestView) findViewById(R.id.testview);
+        testView.setCurrentTextSize(INIT_TEXT_SIZE);
+
+        textSizeSeekBar = (SeekBar) findViewById(R.id.seekbar);
+        textSizeSeekBar.setProgress(INIT_TEXT_SIZE);
+        textSizeSeekBar.setMax(FONT_MAX_SIZE - FONT_MIN_SIZE);
+
+        textSizeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                testView.setCurrentTextSize(FONT_MIN_SIZE + progress);
+            }
+
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+        });
+    }
+}
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestLinearLayoutLtrActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestLinearLayoutLtrActivity.java
new file mode 100644
index 0000000..6d8f11d
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestLinearLayoutLtrActivity.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 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.bidi;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+
+public class BiDiTestLinearLayoutLtrActivity extends Activity {
+
+    private LinearLayout layout;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.linear_layout_ltr);
+
+        layout = (LinearLayout) findViewById(R.id.layouttest);
+    }
+}
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestLinearLayoutRtlActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestLinearLayoutRtlActivity.java
new file mode 100644
index 0000000..0130793
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestLinearLayoutRtlActivity.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 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.bidi;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+
+public class BiDiTestLinearLayoutRtlActivity extends Activity {
+
+    private LinearLayout layout;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.linear_layout_rtl);
+
+        layout = (LinearLayout) findViewById(R.id.layouttest);
+    }
+}