Merge "Add allowSynchronousMode to SurfaceTexture constructor."
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index c0c4c17..7183267 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -24,7 +24,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.Manifest;
-import android.text.TextUtils;
 import android.util.Log;
 
 import java.util.Arrays;
@@ -136,17 +135,8 @@
                 if (result != null) {
                     response.onResult(result);
                 }
-            } catch (NetworkErrorException e) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "addAccount", e);
-                }
-                response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
-            } catch (UnsupportedOperationException e) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "addAccount", e);
-                }
-                response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
-                        "addAccount not supported");
+            } catch (Exception e) {
+                handleException(response, "addAccount", accountType, e);
             }
         }
 
@@ -167,17 +157,8 @@
                 if (result != null) {
                     response.onResult(result);
                 }
-            } catch (NetworkErrorException e) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "confirmCredentials", e);
-                }
-                response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
-            } catch (UnsupportedOperationException e) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "confirmCredentials", e);
-                }
-                response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
-                        "confirmCredentials not supported");
+            } catch (Exception e) {
+                handleException(response, "confirmCredentials", account.toString(), e);
             }
         }
 
@@ -197,21 +178,9 @@
                     Log.v(TAG, "getAuthTokenLabel: result "
                             + AccountManager.sanitizeResult(result));
                 }
-                if (result != null) {
-                    response.onResult(result);
-                }
-            } catch (IllegalArgumentException e) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "getAuthTokenLabel", e);
-                }
-                response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
-                        "unknown authTokenType");
-            } catch (UnsupportedOperationException e) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "getAuthTokenLabel", e);
-                }
-                response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
-                        "getAuthTokenTypeLabel not supported");
+                response.onResult(result);
+            } catch (Exception e) {
+                handleException(response, "getAuthTokenLabel", authTokenType, e);
             }
         }
 
@@ -234,17 +203,9 @@
                 if (result != null) {
                     response.onResult(result);
                 }
-            } catch (UnsupportedOperationException e) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "getAuthToken", e);
-                }
-                response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
-                        "getAuthToken not supported");
-            } catch (NetworkErrorException e) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "getAuthToken", e);
-                }
-                response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
+            } catch (Exception e) {
+                handleException(response, "getAuthToken",
+                        account.toString() + "," + authTokenType, e);
             }
         }
 
@@ -267,17 +228,9 @@
                 if (result != null) {
                     response.onResult(result);
                 }
-            } catch (NetworkErrorException e) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "updateCredentials", e);
-                }
-                response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
-            } catch (UnsupportedOperationException e) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "updateCredentials", e);
-                }
-                response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
-                        "updateCredentials not supported");
+            } catch (Exception e) {
+                handleException(response, "updateCredentials",
+                        account.toString() + "," + authTokenType, e);
             }
         }
 
@@ -290,9 +243,8 @@
                 if (result != null) {
                     response.onResult(result);
                 }
-            } catch (UnsupportedOperationException e) {
-                response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
-                        "editProperties not supported");
+            } catch (Exception e) {
+                handleException(response, "editProperties", accountType, e);
             }
         }
 
@@ -305,11 +257,8 @@
                 if (result != null) {
                     response.onResult(result);
                 }
-            } catch (UnsupportedOperationException e) {
-                response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
-                        "hasFeatures not supported");
-            } catch (NetworkErrorException e) {
-                response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
+            } catch (Exception e) {
+                handleException(response, "hasFeatures", account.toString(), e);
             }
         }
 
@@ -322,15 +271,38 @@
                 if (result != null) {
                     response.onResult(result);
                 }
-            } catch (UnsupportedOperationException e) {
-                response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
-                        "getAccountRemovalAllowed not supported");
-            } catch (NetworkErrorException e) {
-                response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
+            } catch (Exception e) {
+                handleException(response, "getAccountRemovalAllowed", account.toString(), e);
             }
         }
     }
 
+    private void handleException(IAccountAuthenticatorResponse response, String method,
+            String data, Exception e) throws RemoteException {
+        if (e instanceof NetworkErrorException) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, method + "(" + data + ")", e);
+            }
+            response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage());
+        } else if (e instanceof UnsupportedOperationException) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, method + "(" + data + ")", e);
+            }
+            response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
+                    method + " not supported");
+        } else if (e instanceof IllegalArgumentException) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, method + "(" + data + ")", e);
+            }
+            response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
+                    method + " not supported");
+        } else {
+            Log.w(TAG, method + "(" + data + ")", e);
+            response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION,
+                    method + " failed");
+        }
+    }
+
     private void checkBinderPermission() {
         final int uid = Binder.getCallingUid();
         final String perm = Manifest.permission.ACCOUNT_MANAGER;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 77df7c8..17aea8b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7668,7 +7668,7 @@
         }
         String searchedLowerCase = searched.toString().toLowerCase();
         String thisTextLowerCase = thisText.toString().toLowerCase();
-        if (thisTextLowerCase.contains(searched)) {
+        if (thisTextLowerCase.contains(searchedLowerCase)) {
             outViews.add(this);
         }
     }
diff --git a/include/media/stagefright/ColorConverter.h b/include/media/stagefright/ColorConverter.h
index 2ae8a5b..85ba920 100644
--- a/include/media/stagefright/ColorConverter.h
+++ b/include/media/stagefright/ColorConverter.h
@@ -76,6 +76,9 @@
     status_t convertYUV420SemiPlanar(
             const BitmapParams &src, const BitmapParams &dst);
 
+    status_t convertTIYUV420PackedSemiPlanar(
+            const BitmapParams &src, const BitmapParams &dst);
+
     ColorConverter(const ColorConverter &);
     ColorConverter &operator=(const ColorConverter &);
 };
diff --git a/include/media/stagefright/openmax/OMX_IVCommon.h b/include/media/stagefright/openmax/OMX_IVCommon.h
index 12b4f93..7ed072b 100644
--- a/include/media/stagefright/openmax/OMX_IVCommon.h
+++ b/include/media/stagefright/openmax/OMX_IVCommon.h
@@ -149,6 +149,7 @@
     OMX_COLOR_Format24BitABGR6666,
     OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
     OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x7F000100,
     OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00,
     OMX_COLOR_FormatMax = 0x7FFFFFFF
 } OMX_COLOR_FORMATTYPE;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index bb8a8be..314425f 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -180,6 +180,7 @@
     { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "G711Decoder" },
     { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "OMX.google.g711.mlaw.decoder" },
     { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "G711Decoder" },
+    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.DUCATI1.VIDEO.DECODER" },
     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.decode" },
     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.decoder.mpeg4" },
     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
@@ -187,12 +188,14 @@
     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Decoder" },
     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.google.mpeg4.decoder" },
     { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" },
+    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.DUCATI1.VIDEO.DECODER" },
     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.decode" },
     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.decoder.h263" },
     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Decoder" },
     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.google.h263.decoder" },
     { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" },
+    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.DUCATI1.VIDEO.DECODER" },
     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.decode" },
     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.decoder.avc" },
     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
@@ -387,7 +390,10 @@
         quirks |= kDefersOutputBufferAllocation;
     }
 
-    if (!strncmp(componentName, "OMX.TI.", 7)) {
+    if (!strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.DECODER")) {
+        quirks |= kRequiresAllocateBufferOnInputPorts;
+        quirks |= kRequiresAllocateBufferOnOutputPorts;
+    } else if (!strncmp(componentName, "OMX.TI.", 7)) {
         // Apparently I must not use OMX_UseBuffer on either input or
         // output ports on any of the TI components or quote:
         // "(I) may have unexpected problem (sic) which can be timing related
@@ -1390,6 +1396,7 @@
         CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
                || format.eColorFormat == OMX_COLOR_FormatCbYCrY
+               || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
                || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
 
         err = mOMX->setParameter(
@@ -3789,7 +3796,9 @@
 
     size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
 
-    if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
+    if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
+        return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar";
+    } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
         return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
     } else if (type < 0 || (size_t)type >= numNames) {
         return "UNKNOWN";
diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp
index b28d947..fd933cc 100644
--- a/media/libstagefright/colorconversion/ColorConverter.cpp
+++ b/media/libstagefright/colorconversion/ColorConverter.cpp
@@ -42,6 +42,7 @@
         case OMX_COLOR_FormatCbYCrY:
         case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
         case OMX_COLOR_FormatYUV420SemiPlanar:
+        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
             return true;
 
         default:
@@ -113,6 +114,10 @@
             err = convertYUV420SemiPlanar(src, dst);
             break;
 
+        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
+            err = convertTIYUV420PackedSemiPlanar(src, dst);
+            break;
+
         default:
         {
             CHECK(!"Should not be here. Unknown color conversion.");
@@ -417,6 +422,102 @@
     return OK;
 }
 
+status_t ColorConverter::convertTIYUV420PackedSemiPlanar(
+        const BitmapParams &src, const BitmapParams &dst) {
+
+/*
+The TIYUV420PackedSemiPlanar format is same as YUV420PackedSemiPlanar but with
+additional padding as shown in the diagram below. The padded width and padded
+height is different for different compression formats and it is read from the
+codec. In this color conversion routine, the padded resolution is obtained from
+src bitmap.
+
+ ------------------------------------
+|                                    |
+|                                    |
+|      -------------------------     |
+|     |                         |    |
+|     |                         |    |
+|     |          Y DATA         |    |
+|     |                         |    |
+|     |                         |    |
+|     |                         |    |
+|      -------------------------     |
+|                                    |
+|      ------------                  |
+|     |            |                 |
+|     |            |                 |
+|     |  UV DATA   |                 |
+|     |            |                 |
+|     |            |                 |
+|     |            |                 |
+|      ------------                  |
+|                                    |
+|                                    |
+ ------------------------------------
+*/
+
+    LOGV("src.mCropLeft = %d src.mCropTop =%d src.mWidth = %d src.mHeight = %d"
+        " dst.mWidth = %d dst.mHeight = %d", src.mCropLeft , src.mCropTop,
+        src.mWidth, src.mHeight, dst.mWidth, dst.mHeight);
+
+    size_t offset = (src.mWidth * src.mCropTop) + src.mCropLeft;
+
+    uint8_t *kAdjustedClip = initClip();
+
+    uint32_t *dst_ptr = (uint32_t *)dst.mBits;
+    const uint8_t *src_y = (const uint8_t *)src.mBits;
+    const uint8_t *src_u = (const uint8_t *)(src_y-offset) + (src.mWidth * src.mHeight);
+    src_u += ( ( src.mWidth * (src.mCropTop/2) ) + src.mCropLeft );
+    const uint8_t *src_v = src_u + 1;
+
+    for (size_t y = 0; y < dst.mHeight; ++y) {
+        for (size_t x = 0; x < dst.mWidth; x += 2) {
+
+            signed y1 = (signed)src_y[x] - 16;    //Y pixel
+            signed y2 = (signed)src_y[x + 1] - 16; //2nd Y pixel
+
+            signed u = (signed)src_u[x & ~1] - 128;   //U component
+            signed v = (signed)src_u[(x & ~1) + 1] - 128; //V component
+
+            signed u_b = u * 517;
+            signed u_g = -u * 100;
+            signed v_g = -v * 208;
+            signed v_r = v * 409;
+
+            signed tmp1 = y1 * 298;
+            signed b1 = (tmp1 + u_b) / 256;
+            signed g1 = (tmp1 + v_g + u_g) / 256;
+            signed r1 = (tmp1 + v_r) / 256;
+
+            signed tmp2 = y2 * 298;
+            signed b2 = (tmp2 + u_b) / 256;
+            signed g2 = (tmp2 + v_g + u_g) / 256;
+            signed r2 = (tmp2 + v_r) / 256;
+
+            uint32_t rgb1 =
+                ((kAdjustedClip[r1] >> 3) << 11)
+                | ((kAdjustedClip[g1] >> 2) << 5)
+                | (kAdjustedClip[b1] >> 3);
+
+            uint32_t rgb2 =
+                ((kAdjustedClip[r2] >> 3) << 11)
+                | ((kAdjustedClip[g1] >> 2) << 5)
+                | (kAdjustedClip[b1] >> 3);
+
+            dst_ptr[x / 2] = (rgb2 << 16) | rgb1;
+        }
+
+        src_y += src.mWidth; //increment Y-pixel line
+        if (y&1) {
+          src_u += src.mWidth; //increment U-V line
+        }
+
+        dst_ptr += dst.mWidth / 2;
+    }
+    return OK;
+}
+
 uint8_t *ColorConverter::initClip() {
     static const signed kClipMin = -278;
     static const signed kClipMax = 535;
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index ca2578f..1ccf50d 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -109,7 +109,9 @@
     void addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id);
     void removeActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id);
     void freeActiveBuffers();
-
+    status_t useGraphicBuffer2_l(
+            OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
+            OMX::buffer_id *buffer);
     static OMX_ERRORTYPE OnEvent(
             OMX_IN OMX_HANDLETYPE hComponent,
             OMX_IN OMX_PTR pAppData,
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 8462988..12ab941 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -406,12 +406,77 @@
     return OK;
 }
 
+status_t OMXNodeInstance::useGraphicBuffer2_l(
+        OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
+        OMX::buffer_id *buffer) {
+
+    // port definition
+    OMX_PARAM_PORTDEFINITIONTYPE def;
+    def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
+    def.nVersion.s.nVersionMajor = 1;
+    def.nVersion.s.nVersionMinor = 0;
+    def.nVersion.s.nRevision = 0;
+    def.nVersion.s.nStep = 0;
+    def.nPortIndex = portIndex;
+    OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def);
+    if (err != OK)
+    {
+        LOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__);
+        return err;
+    }
+
+    BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
+
+    OMX_BUFFERHEADERTYPE *header = NULL;
+    OMX_U8* bufferHandle = const_cast<OMX_U8*>(
+            reinterpret_cast<const OMX_U8*>(graphicBuffer->handle));
+
+    err = OMX_UseBuffer(
+            mHandle,
+            &header,
+            portIndex,
+            bufferMeta,
+            def.nBufferSize,
+            bufferHandle);
+
+    if (err != OMX_ErrorNone) {
+        LOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
+        delete bufferMeta;
+        bufferMeta = NULL;
+        *buffer = 0;
+        return UNKNOWN_ERROR;
+    }
+
+    CHECK_EQ(header->pBuffer, bufferHandle);
+    CHECK_EQ(header->pAppPrivate, bufferMeta);
+
+    *buffer = header;
+
+    addActiveBuffer(portIndex, *buffer);
+
+    return OK;
+}
+
+// XXX: This function is here for backwards compatibility.  Once the OMX
+// implementations have been updated this can be removed and useGraphicBuffer2
+// can be renamed to useGraphicBuffer.
 status_t OMXNodeInstance::useGraphicBuffer(
         OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
         OMX::buffer_id *buffer) {
     Mutex::Autolock autoLock(mLock);
 
+    // See if the newer version of the extension is present.
     OMX_INDEXTYPE index;
+    if (OMX_GetExtensionIndex(
+            mHandle,
+            const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"),
+            &index) == OMX_ErrorNone) {
+        return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer);
+    }
+
+    LOGW("Falling back to the deprecated useAndroidNativeBuffer support.  You "
+        "should switch to the useAndroidNativeBuffer2 extension.");
+
     OMX_ERRORTYPE err = OMX_GetExtensionIndex(
             mHandle,
             const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer"),
diff --git a/tests/BiDiTests/res/drawable/end.png b/tests/BiDiTests/res/drawable/end.png
new file mode 100644
index 0000000..0c110be
--- /dev/null
+++ b/tests/BiDiTests/res/drawable/end.png
Binary files differ
diff --git a/tests/BiDiTests/res/drawable/start.png b/tests/BiDiTests/res/drawable/start.png
new file mode 100644
index 0000000..783bf90
--- /dev/null
+++ b/tests/BiDiTests/res/drawable/start.png
Binary files differ
diff --git a/tests/BiDiTests/res/layout/textview_locale.xml b/tests/BiDiTests/res/layout/textview_locale.xml
new file mode 100644
index 0000000..a2dcbf9
--- /dev/null
+++ b/tests/BiDiTests/res/layout/textview_locale.xml
@@ -0,0 +1,275 @@
+<?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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/textview_locale"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layoutDirection="locale">
+
+    <LinearLayout android:orientation="vertical"
+                  android:layout_width="match_parent"
+                  android:layout_height="match_parent">
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="start"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="start"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="start"
+                />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="end"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="end"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="end"
+                />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="left"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="left"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="left"
+                />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="right"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="right"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="right"
+                />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="center"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="center"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="center"
+                />
+
+    </LinearLayout>
+
+
+</FrameLayout>
diff --git a/tests/BiDiTests/res/layout/textview_ltr.xml b/tests/BiDiTests/res/layout/textview_ltr.xml
new file mode 100644
index 0000000..6e6b976
--- /dev/null
+++ b/tests/BiDiTests/res/layout/textview_ltr.xml
@@ -0,0 +1,275 @@
+<?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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/textview_ltr"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layoutDirection="ltr">
+
+    <LinearLayout android:orientation="vertical"
+                  android:layout_width="match_parent"
+                  android:layout_height="match_parent">
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="start"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="start"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="start"
+                />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="end"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="end"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="end"
+                />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="left"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="left"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="left"
+                />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="right"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="right"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="right"
+                />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="center"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="center"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="center"
+                />
+
+    </LinearLayout>
+
+
+</FrameLayout>
diff --git a/tests/BiDiTests/res/layout/textview_rtl.xml b/tests/BiDiTests/res/layout/textview_rtl.xml
new file mode 100644
index 0000000..117227d
--- /dev/null
+++ b/tests/BiDiTests/res/layout/textview_rtl.xml
@@ -0,0 +1,275 @@
+<?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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/textview_rtl"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layoutDirection="rtl">
+
+    <LinearLayout android:orientation="vertical"
+                  android:layout_width="match_parent"
+                  android:layout_height="match_parent">
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="start"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="start"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="start"
+                />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="end"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="end"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="end"
+                />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="left"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="left"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="left"
+                />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="right"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="right"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="right"
+                />
+
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_hebrew_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="center"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_latin_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="center"
+                />
+        <TextView android:id="@+id/textview"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:textSize="24dip"
+                  android:text="@string/textview_multiline_text"
+                  android:minWidth="200dip"
+                  android:drawableLeft="@drawable/start"
+                  android:drawableRight="@drawable/end"
+                  android:paddingLeft="5dip"
+                  android:paddingRight="15dip"
+                  android:drawablePadding="3dip"
+                  android:background="#884"
+                  android:layout_marginLeft="5dip"
+                  android:layout_marginRight="15dip"
+                  android:gravity="center"
+                />
+
+    </LinearLayout>
+
+
+</FrameLayout>
diff --git a/tests/BiDiTests/res/values/strings.xml b/tests/BiDiTests/res/values/strings.xml
index 16dc263..c0bbe94 100644
--- a/tests/BiDiTests/res/values/strings.xml
+++ b/tests/BiDiTests/res/values/strings.xml
@@ -38,4 +38,8 @@
     <string name="hebrew_text">&#x05DD;&#x05DE;</string>
     <string name="menu_add">Add</string>
     <string name="menu_delete">Delete</string>
-</resources>
\ No newline at end of file
+    <string name="textview_hebrew_text">&#x05DD;&#x05DE;ab?!</string>
+    <string name="textview_latin_text">ab&#x05DD;&#x05DE;?!</string>
+    <string name="textview_multiline_text">&#x05DD;&#x05DE;?!\nab?!</string>
+</resources>
+
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
index bee1881..c2683c2 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
@@ -100,8 +100,9 @@
         List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
 
         addItem(result, "Basic", BiDiTestBasic.class, R.id.basic);
+
         addItem(result, "Canvas", BiDiTestCanvas.class, R.id.canvas);
-        
+
         addItem(result, "Linear LTR", BiDiTestLinearLayoutLtr.class, R.id.linear_layout_ltr);
         addItem(result, "Linear RTL", BiDiTestLinearLayoutRtl.class, R.id.linear_layout_rtl);
         addItem(result, "Linear LOC", BiDiTestLinearLayoutLocale.class, R.id.linear_layout_locale);
@@ -121,6 +122,10 @@
         addItem(result, "Table RTL", BiDiTestTableLayoutRtl.class, R.id.table_layout_rtl);
         addItem(result, "Table LOC", BiDiTestTableLayoutLocale.class, R.id.table_layout_locale);
 
+        addItem(result, "TextView LTR", BiDiTestTextViewLtr.class, R.id.textview_ltr);
+        addItem(result, "TextView RTL", BiDiTestTextViewRtl.class, R.id.textview_rtl);
+        addItem(result, "TextView LOC", BiDiTestTextViewLocale.class, R.id.textview_locale);
+
         addItem(result, "ViewPadding", BiDiTestViewPadding.class, R.id.view_padding);
         addItem(result, "ViewPadding MIXED", BiDiTestViewPaddingMixed.class, R.id.view_padding_mixed);
 
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewLocale.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewLocale.java
new file mode 100644
index 0000000..6c64755
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewLocale.java
@@ -0,0 +1,32 @@
+/*
+ * 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.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class BiDiTestTextViewLocale extends Fragment {
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.textview_locale, container, false);
+    }
+}
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewLtr.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewLtr.java
new file mode 100644
index 0000000..b168411
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewLtr.java
@@ -0,0 +1,32 @@
+/*
+ * 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.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class BiDiTestTextViewLtr extends Fragment {
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.textview_ltr, container, false);
+    }
+}
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewRtl.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewRtl.java
new file mode 100644
index 0000000..6f36ce6
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewRtl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class BiDiTestTextViewRtl extends Fragment {
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.textview_rtl, container, false);
+    }
+}