Merge "Minor tweak of NumberPicker to draw the scroll wheel at the right locaion"
diff --git a/api/current.txt b/api/current.txt
index 6693647..a49fa9f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -975,6 +975,7 @@
     field public static final int textColorTertiary = 16843282; // 0x1010212
     field public static final int textColorTertiaryInverse = 16843283; // 0x1010213
     field public static final int textCursorDrawable = 16843618; // 0x1010362
+    field public static final int textDirection = 16843677; // 0x101039d
     field public static final int textEditNoPasteWindowLayout = 16843541; // 0x1010315
     field public static final int textEditPasteWindowLayout = 16843540; // 0x1010314
     field public static final int textEditSideNoPasteWindowLayout = 16843615; // 0x101035f
@@ -9397,6 +9398,7 @@
     method public void onUpdateExtractingViews(android.view.inputmethod.EditorInfo);
     method public void onUpdateExtractingVisibility(android.view.inputmethod.EditorInfo);
     method public void onUpdateSelection(int, int, int, int, int, int);
+    method public void onViewClicked(boolean);
     method public void onWindowHidden();
     method public void onWindowShown();
     method public void requestHideSelf(int);
@@ -9440,6 +9442,7 @@
     method public void updateCursor(android.graphics.Rect);
     method public void updateExtractedText(int, android.view.inputmethod.ExtractedText);
     method public void updateSelection(int, int, int, int, int, int);
+    method public void viewClicked(boolean);
   }
 
   public static final class InputMethodService.Insets {
@@ -21878,6 +21881,7 @@
     method public boolean isHovered();
     method public boolean isInEditMode();
     method public boolean isInTouchMode();
+    method protected static boolean isLayoutDirectionRtl(java.util.Locale);
     method public boolean isLayoutRequested();
     method public boolean isLongClickable();
     method public boolean isOpaque();
@@ -21963,8 +21967,10 @@
     method public void requestLayout();
     method public boolean requestRectangleOnScreen(android.graphics.Rect);
     method public boolean requestRectangleOnScreen(android.graphics.Rect, boolean);
+    method protected void resetResolvedTextDirection();
     method public static int resolveSize(int, int);
     method public static int resolveSizeAndState(int, int, int);
+    method protected void resolveTextDirection();
     method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>);
     method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>);
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
@@ -22064,6 +22070,7 @@
     method public boolean willNotCacheDrawing();
     method public boolean willNotDraw();
     field public static android.util.Property ALPHA;
+    field protected static int DEFAULT_TEXT_DIRECTION;
     field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
     field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
     field public static final int DRAWING_CACHE_QUALITY_LOW = 524288; // 0x80000
@@ -23511,6 +23518,7 @@
     method public void updateCursor(android.view.View, int, int, int, int);
     method public void updateExtractedText(android.view.View, int, android.view.inputmethod.ExtractedText);
     method public void updateSelection(android.view.View, int, int, int, int);
+    method public void viewClicked(android.view.View);
     field public static final int HIDE_IMPLICIT_ONLY = 1; // 0x1
     field public static final int HIDE_NOT_ALWAYS = 2; // 0x2
     field public static final int RESULT_HIDDEN = 3; // 0x3
@@ -23531,6 +23539,7 @@
     method public abstract void updateCursor(android.graphics.Rect);
     method public abstract void updateExtractedText(int, android.view.inputmethod.ExtractedText);
     method public abstract void updateSelection(int, int, int, int, int, int);
+    method public abstract void viewClicked(boolean);
   }
 
   public static abstract interface InputMethodSession.EventCallback {
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index f780afb..41ccd91 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -20,6 +20,11 @@
 #include <media/mediaplayer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MPEG2TSWriter.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
 
 #include <binder/IServiceManager.h>
 #include <media/IMediaPlayerService.h>
@@ -31,7 +36,7 @@
 using namespace android;
 
 struct MyStreamSource : public BnStreamSource {
-    // Caller retains ownership of fd.
+    // Object assumes ownership of fd.
     MyStreamSource(int fd);
 
     virtual void setListener(const sp<IStreamListener> &listener);
@@ -64,6 +69,8 @@
 }
 
 MyStreamSource::~MyStreamSource() {
+    close(mFd);
+    mFd = -1;
 }
 
 void MyStreamSource::setListener(const sp<IStreamListener> &listener) {
@@ -99,6 +106,143 @@
         mListener->queueBuffer(index, n);
     }
 }
+////////////////////////////////////////////////////////////////////////////////
+
+struct MyConvertingStreamSource : public BnStreamSource {
+    MyConvertingStreamSource(const char *filename);
+
+    virtual void setListener(const sp<IStreamListener> &listener);
+    virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
+
+    virtual void onBufferAvailable(size_t index);
+
+protected:
+    virtual ~MyConvertingStreamSource();
+
+private:
+    Mutex mLock;
+    Condition mCondition;
+
+    sp<IStreamListener> mListener;
+    Vector<sp<IMemory> > mBuffers;
+
+    sp<MPEG2TSWriter> mWriter;
+
+    ssize_t mCurrentBufferIndex;
+    size_t mCurrentBufferOffset;
+
+    List<size_t> mBufferQueue;
+
+    static ssize_t WriteDataWrapper(void *me, const void *data, size_t size);
+    ssize_t writeData(const void *data, size_t size);
+
+    DISALLOW_EVIL_CONSTRUCTORS(MyConvertingStreamSource);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+MyConvertingStreamSource::MyConvertingStreamSource(const char *filename)
+    : mCurrentBufferIndex(-1),
+      mCurrentBufferOffset(0) {
+    sp<DataSource> dataSource = DataSource::CreateFromURI(filename);
+    CHECK(dataSource != NULL);
+
+    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
+    CHECK(extractor != NULL);
+
+    mWriter = new MPEG2TSWriter(
+            this, &MyConvertingStreamSource::WriteDataWrapper);
+
+    for (size_t i = 0; i < extractor->countTracks(); ++i) {
+        const sp<MetaData> &meta = extractor->getTrackMetaData(i);
+
+        const char *mime;
+        CHECK(meta->findCString(kKeyMIMEType, &mime));
+
+        if (strncasecmp("video/", mime, 6) && strncasecmp("audio/", mime, 6)) {
+            continue;
+        }
+
+        CHECK_EQ(mWriter->addSource(extractor->getTrack(i)), (status_t)OK);
+    }
+
+    CHECK_EQ(mWriter->start(), (status_t)OK);
+}
+
+MyConvertingStreamSource::~MyConvertingStreamSource() {
+}
+
+void MyConvertingStreamSource::setListener(
+        const sp<IStreamListener> &listener) {
+    mListener = listener;
+}
+
+void MyConvertingStreamSource::setBuffers(
+        const Vector<sp<IMemory> > &buffers) {
+    mBuffers = buffers;
+}
+
+ssize_t MyConvertingStreamSource::WriteDataWrapper(
+        void *me, const void *data, size_t size) {
+    return static_cast<MyConvertingStreamSource *>(me)->writeData(data, size);
+}
+
+ssize_t MyConvertingStreamSource::writeData(const void *data, size_t size) {
+    size_t totalWritten = 0;
+
+    while (size > 0) {
+        Mutex::Autolock autoLock(mLock);
+
+        if (mCurrentBufferIndex < 0) {
+            while (mBufferQueue.empty()) {
+                mCondition.wait(mLock);
+            }
+
+            mCurrentBufferIndex = *mBufferQueue.begin();
+            mCurrentBufferOffset = 0;
+
+            mBufferQueue.erase(mBufferQueue.begin());
+        }
+
+        sp<IMemory> mem = mBuffers.itemAt(mCurrentBufferIndex);
+
+        size_t copy = size;
+        if (copy + mCurrentBufferOffset > mem->size()) {
+            copy = mem->size() - mCurrentBufferOffset;
+        }
+
+        memcpy((uint8_t *)mem->pointer() + mCurrentBufferOffset, data, copy);
+        mCurrentBufferOffset += copy;
+
+        if (mCurrentBufferOffset == mem->size()) {
+            mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset);
+            mCurrentBufferIndex = -1;
+        }
+
+        data = (const uint8_t *)data + copy;
+        size -= copy;
+
+        totalWritten += copy;
+    }
+
+    return (ssize_t)totalWritten;
+}
+
+void MyConvertingStreamSource::onBufferAvailable(size_t index) {
+    Mutex::Autolock autoLock(mLock);
+
+    mBufferQueue.push_back(index);
+    mCondition.signal();
+
+    if (mWriter->reachedEOS()) {
+        if (mCurrentBufferIndex >= 0) {
+            mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset);
+            mCurrentBufferIndex = -1;
+        }
+
+        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
+    }
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -139,6 +283,8 @@
 int main(int argc, char **argv) {
     android::ProcessState::self()->startThreadPool();
 
+    DataSource::RegisterDefaultSniffers();
+
     if (argc != 2) {
         fprintf(stderr, "Usage: %s filename\n", argv[0]);
         return 1;
@@ -173,17 +319,28 @@
 
     CHECK(service.get() != NULL);
 
-    int fd = open(argv[1], O_RDONLY);
-
-    if (fd < 0) {
-        fprintf(stderr, "Failed to open file '%s'.", argv[1]);
-        return 1;
-    }
-
     sp<MyClient> client = new MyClient;
 
+    sp<IStreamSource> source;
+
+    size_t len = strlen(argv[1]);
+    if (len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) {
+        int fd = open(argv[1], O_RDONLY);
+
+        if (fd < 0) {
+            fprintf(stderr, "Failed to open file '%s'.", argv[1]);
+            return 1;
+        }
+
+        source = new MyStreamSource(fd);
+    } else {
+        printf("Converting file to transport stream for streaming...\n");
+
+        source = new MyConvertingStreamSource(argv[1]);
+    }
+
     sp<IMediaPlayer> player =
-        service->create(getpid(), client, new MyStreamSource(fd), 0);
+        service->create(getpid(), client, source, 0);
 
     if (player != NULL) {
         player->setVideoSurface(surface);
@@ -196,9 +353,6 @@
         fprintf(stderr, "failed to instantiate player.\n");
     }
 
-    close(fd);
-    fd = -1;
-
     composerClient->dispose();
 
     return 0;
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index df8cf9a..e10f218 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -47,6 +47,7 @@
     private static final int DO_APP_PRIVATE_COMMAND = 100;
     private static final int DO_TOGGLE_SOFT_INPUT = 105;
     private static final int DO_FINISH_SESSION = 110;
+    private static final int DO_VIEW_CLICKED = 115;
 
     HandlerCaller mCaller;
     InputMethodSession mInputMethodSession;
@@ -133,6 +134,10 @@
                 mInputMethodSession = null;
                 return;
             }
+            case DO_VIEW_CLICKED: {
+                mInputMethodSession.viewClicked(msg.arg1 == 1);
+                return;
+            }
         }
         Log.w(TAG, "Unhandled message code: " + msg.what);
     }
@@ -167,7 +172,11 @@
                 oldSelStart, oldSelEnd, newSelStart, newSelEnd,
                 candidatesStart, candidatesEnd));
     }
-    
+
+    public void viewClicked(boolean focusChanged) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageI(DO_VIEW_CLICKED, focusChanged ? 1 : 0));
+    }
+
     public void updateCursor(Rect newCursor) {
         mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_UPDATE_CURSOR,
                 newCursor));
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index feb246e..9481a88 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -488,7 +488,15 @@
             InputMethodService.this.onUpdateSelection(oldSelStart, oldSelEnd,
                     newSelStart, newSelEnd, candidatesStart, candidatesEnd);
         }
-        
+
+        @Override
+        public void viewClicked(boolean focusChanged) {
+            if (!isEnabled()) {
+                return;
+            }
+            InputMethodService.this.onViewClicked(focusChanged);
+        }
+
         /**
          * Call {@link InputMethodService#onUpdateCursor
          * InputMethodService.onUpdateCursor()}.
@@ -1609,6 +1617,16 @@
     }
 
     /**
+     * Called when the user tapped or clicked a text view.
+     * IMEs can't rely on this method being called because this was not part of the original IME
+     * protocol, so applications with custom text editing written before this method appeared will
+     * not call to inform the IME of this interaction.
+     * @param focusChanged true if the user changed the focused view by this click.
+     */
+    public void onViewClicked(boolean focusChanged) {
+    }
+
+    /**
      * Called when the application has reported a new location of its text
      * cursor.  This is only called if explicitly requested by the input method.
      * The default implementation does nothing.
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index 040489e..2b59dba 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -25,8 +25,9 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 
-import dalvik.system.BlockGuard;
+import com.android.server.NetworkManagementSocketTagger;
 
+import dalvik.system.SocketTagger;
 import java.net.Socket;
 import java.net.SocketException;
 
@@ -92,7 +93,7 @@
      * {@link #tagSocket(Socket)}.
      */
     public static void setThreadStatsTag(int tag) {
-        BlockGuard.setThreadSocketStatsTag(tag);
+        NetworkManagementSocketTagger.setThreadSocketStatsTag(tag);
     }
 
     /**
@@ -104,7 +105,7 @@
     }
 
     public static void clearThreadStatsTag() {
-        BlockGuard.setThreadSocketStatsTag(-1);
+        NetworkManagementSocketTagger.setThreadSocketStatsTag(-1);
     }
 
     /**
@@ -121,12 +122,12 @@
      * {@hide}
      */
     public static void setThreadStatsUid(int uid) {
-        BlockGuard.setThreadSocketStatsUid(uid);
+        NetworkManagementSocketTagger.setThreadSocketStatsUid(uid);
     }
 
     /** {@hide} */
     public static void clearThreadStatsUid() {
-        BlockGuard.setThreadSocketStatsUid(-1);
+        NetworkManagementSocketTagger.setThreadSocketStatsUid(-1);
     }
 
     /**
@@ -139,14 +140,14 @@
      * @see #setThreadStatsUid(int)
      */
     public static void tagSocket(Socket socket) throws SocketException {
-        BlockGuard.tagSocketFd(socket.getFileDescriptor$());
+        SocketTagger.get().tag(socket);
     }
 
     /**
      * Remove any statistics parameters from the given {@link Socket}.
      */
     public static void untagSocket(Socket socket) throws SocketException {
-        BlockGuard.untagSocketFd(socket.getFileDescriptor$());
+        SocketTagger.get().untag(socket);
     }
 
     /**
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 1b09242..047a265 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -210,6 +210,16 @@
     NetworkStats getNetworkStatsUidDetail(int uid);
 
     /**
+     * Set an overall quota for a group of interfaces.
+     */
+    void setInterfaceQuota(in String[] iface, long quota);
+
+    /**
+     * Control network activity of a UID over interfaces with a quota limit.
+     */
+    void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces);
+
+    /**
      * Configures bandwidth throttling on an interface.
      */
     void setInterfaceThrottle(String iface, int rxKbps, int txKbps);
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 0933193..39c6f57 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -57,6 +57,29 @@
                 Uri.parse("content://call_log/calls/filter");
 
         /**
+         * An optional URI parameter which instructs the provider to allow the operation to be
+         * applied to voicemail records as well.
+         * <p>
+         * TYPE: Boolean
+         * <p>
+         * Using this parameter with a value of {@code true} will result in a security error if the
+         * calling package does not have appropriate permissions to access voicemails.
+         *
+         * @hide
+         */
+        public static final String ALLOW_VOICEMAILS_PARAM_KEY = "allow_voicemails";
+
+        /**
+         * Content uri with {@link #ALLOW_VOICEMAILS_PARAM_KEY} set. This can directly be used to
+         * access call log entries that includes voicemail records.
+         *
+         * @hide
+         */
+        public static final Uri CONTENT_URI_WITH_VOICEMAIL = CONTENT_URI.buildUpon()
+                .appendQueryParameter(ALLOW_VOICEMAILS_PARAM_KEY, "true")
+                .build();
+
+        /**
          * The default sort order for this table
          */
         public static final String DEFAULT_SORT_ORDER = "date DESC";
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
old mode 100755
new mode 100644
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 411b714..bf7f359 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2493,6 +2493,84 @@
     private boolean mSendingHoverAccessibilityEvents;
 
     /**
+     * Undefined text direction (used by resolution algorithm).
+     * @hide
+     */
+    public static final int TEXT_DIRECTION_UNDEFINED = -1;
+
+    /**
+     * Text direction is inherited thru {@link ViewGroup}
+     * @hide
+     */
+    public static final int TEXT_DIRECTION_INHERIT = 0;
+
+    /**
+     * Text direction is using "first strong algorithm". The first strong directional character
+     * determines the paragraph direction. If there is no strong directional character, the
+     * paragraph direction is the view’s resolved ayout direction.
+     *
+     * @hide
+     */
+    public static final int TEXT_DIRECTION_FIRST_STRONG = 1;
+
+    /**
+     * Text direction is using "any-RTL" algorithm. The paragraph direction is RTL if it contains
+     * any strong RTL character, otherwise it is LTR if it contains any strong LTR characters.
+     * If there are neither, the paragraph direction is the view’s resolved layout direction.
+     *
+     * @hide
+     */
+    public static final int TEXT_DIRECTION_ANY_RTL = 2;
+
+    /**
+     * Text direction is forced to LTR.
+     *
+     * @hide
+     */
+    public static final int TEXT_DIRECTION_LTR = 3;
+
+    /**
+     * Text direction is forced to RTL.
+     *
+     * @hide
+     */
+    public static final int TEXT_DIRECTION_RTL = 4;
+
+    /**
+     * Default text direction is inherited
+     */
+    protected static int DEFAULT_TEXT_DIRECTION = TEXT_DIRECTION_INHERIT;
+
+    /**
+     * The text direction that has been defined by {@link #setTextDirection(int)}.
+     *
+     * {@hide}
+     */
+    @ViewDebug.ExportedProperty(category = "text", mapping = {
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_UNDEFINED, to = "UNDEFINED"),
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL")
+    })
+    protected int mTextDirection = DEFAULT_TEXT_DIRECTION;
+
+    /**
+     * The resolved text direction. If resolution has not yet been done or has been reset, it will
+     * be equal to {@link #TEXT_DIRECTION_UNDEFINED}. Otherwise it will be either {@link #TEXT_DIRECTION_LTR}
+     * or {@link #TEXT_DIRECTION_RTL}.
+     *
+     * {@hide}
+     */
+    @ViewDebug.ExportedProperty(category = "text", mapping = {
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_UNDEFINED, to = "UNDEFINED"),
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL")
+    })
+    protected int mResolvedTextDirection = TEXT_DIRECTION_UNDEFINED;
+
+    /**
      * Consistency verifier for debugging purposes.
      * @hide
      */
@@ -2865,6 +2943,9 @@
                 case R.styleable.View_layerType:
                     setLayerType(a.getInt(attr, LAYER_TYPE_NONE), null);
                     break;
+                case R.styleable.View_textDirection:
+                    mTextDirection = a.getInt(attr, DEFAULT_TEXT_DIRECTION);
+                    break;
             }
         }
 
@@ -8951,6 +9032,8 @@
         resetLayoutDirectionResolution();
         resolveLayoutDirectionIfNeeded();
         resolvePadding();
+        resetResolvedTextDirection();
+        resolveTextDirection();
         if (isFocused()) {
             InputMethodManager imm = InputMethodManager.peekInstance();
             imm.focusIn(this);
@@ -9051,7 +9134,7 @@
      * @param locale Locale to check
      * @return true if a Locale is corresponding to a RTL script.
      */
-    private static boolean isLayoutDirectionRtl(Locale locale) {
+    protected static boolean isLayoutDirectionRtl(Locale locale) {
         return (LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE ==
                 LocaleUtil.getLayoutDirectionFromLocale(locale));
     }
@@ -12898,6 +12981,89 @@
         return getVerticalScrollFactor();
     }
 
+    /**
+     * Return the value specifying the text direction or policy that was set with
+     * {@link #setTextDirection(int)}.
+     *
+     * @return the defined text direction. It can be one of:
+     *
+     * {@link #TEXT_DIRECTION_INHERIT},
+     * {@link #TEXT_DIRECTION_FIRST_STRONG}
+     * {@link #TEXT_DIRECTION_ANY_RTL},
+     * {@link #TEXT_DIRECTION_LTR},
+     * {@link #TEXT_DIRECTION_RTL},
+     *
+     * @hide
+     */
+    public int getTextDirection() {
+        return mTextDirection;
+    }
+
+    /**
+     * Set the text direction.
+     *
+     * @param textDirection the direction to set. Should be one of:
+     *
+     * {@link #TEXT_DIRECTION_INHERIT},
+     * {@link #TEXT_DIRECTION_FIRST_STRONG}
+     * {@link #TEXT_DIRECTION_ANY_RTL},
+     * {@link #TEXT_DIRECTION_LTR},
+     * {@link #TEXT_DIRECTION_RTL},
+     *
+     * @hide
+     */
+    public void setTextDirection(int textDirection) {
+        if (textDirection != mTextDirection) {
+            mTextDirection = textDirection;
+            resetResolvedTextDirection();
+            requestLayout();
+        }
+    }
+
+    /**
+     * Return the resolved text direction.
+     *
+     * @return the resolved text direction. Return one of:
+     *
+     * {@link #TEXT_DIRECTION_LTR},
+     * {@link #TEXT_DIRECTION_RTL},
+     *
+     * @hide
+     */
+    public int getResolvedTextDirection() {
+        if (!isResolvedTextDirection()) {
+            resolveTextDirection();
+        }
+        return mResolvedTextDirection;
+    }
+
+    /**
+     * Resolve the text direction. Classes that extend View and want to do a specific text direction
+     * resolution will need to implement this method and set the mResolvedTextDirection to
+     * either TEXT_DIRECTION_LTR if direction is LTR or TEXT_DIRECTION_RTL if
+     * direction is RTL.
+     */
+    protected void resolveTextDirection() {
+    }
+
+    /**
+     * Return if the text direction has been resolved or not.
+     *
+     * @return true, if resolved and false if not resolved
+     *
+     * @hide
+     */
+    public boolean isResolvedTextDirection() {
+        return (mResolvedTextDirection != TEXT_DIRECTION_UNDEFINED);
+    }
+
+    /**
+     * Reset resolved text direction. Will be resolved during a call to getResolvedLayoutDirection().
+     */
+    protected void resetResolvedTextDirection() {
+        mResolvedTextDirection = TEXT_DIRECTION_UNDEFINED;
+    }
+
     //
     // Properties
     //
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 6405398..2a90dde 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -46,6 +46,7 @@
 
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.Locale;
 
 /**
  * <p>
@@ -5016,6 +5017,51 @@
     }
 
     /**
+     * This method will be called during text direction resolution (text direction resolution
+     * inheritance)
+     */
+    @Override
+    protected void resolveTextDirection() {
+        int resolvedTextDirection = TEXT_DIRECTION_UNDEFINED;
+        switch(mTextDirection) {
+            default:
+            case TEXT_DIRECTION_INHERIT:
+                // Try to the text direction from the parent layout
+                if (mParent != null && mParent instanceof ViewGroup) {
+                    resolvedTextDirection = ((ViewGroup) mParent).getResolvedTextDirection();
+                } else {
+                    // We reached the top of the View hierarchy, so get the direction from
+                    // the Locale
+                    resolvedTextDirection = isLayoutDirectionRtl(Locale.getDefault()) ?
+                            TEXT_DIRECTION_RTL : TEXT_DIRECTION_LTR;
+                }
+                break;
+            // Pass down the hierarchy the following text direction values
+            case TEXT_DIRECTION_FIRST_STRONG:
+            case TEXT_DIRECTION_ANY_RTL:
+            case TEXT_DIRECTION_LTR:
+            case TEXT_DIRECTION_RTL:
+                resolvedTextDirection = mTextDirection;
+                break;
+        }
+        mResolvedTextDirection = resolvedTextDirection;
+    }
+
+    @Override
+    protected void resetResolvedTextDirection() {
+        super.resetResolvedTextDirection();
+
+        // Take care of resetting the children resolution too
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getTextDirection() == TEXT_DIRECTION_INHERIT) {
+                child.resetResolvedTextDirection();
+            }
+        }
+    }
+
+    /**
      * Return true if the pressed state should be delayed for children or descendants of this
      * ViewGroup. Generally, this should be done for containers that can scroll, such as a List.
      * This prevents the pressed state from appearing when the user is actually trying to scroll
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 47f5e4c..a1a7281 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1126,7 +1126,7 @@
         if (mServedView == mNextServedView && !mNextServedNeedsStart) {
             return;
         }
-        
+
         InputConnection ic = null;
         synchronized (mH) {
             if (mServedView == mNextServedView && !mNextServedNeedsStart) {
@@ -1242,6 +1242,27 @@
     }
 
     /**
+     * Notify the event when the user tapped or clicked the text view.
+     */
+    public void viewClicked(View view) {
+        final boolean focusChanged = mServedView != mNextServedView;
+        checkFocus();
+        synchronized (mH) {
+            if ((mServedView != view && (mServedView == null
+                    || !mServedView.checkInputConnectionProxy(view)))
+                    || mCurrentTextBoxAttribute == null || mCurMethod == null) {
+                return;
+            }
+            try {
+                if (DEBUG) Log.v(TAG, "onViewClicked: " + focusChanged);
+                mCurMethod.viewClicked(focusChanged);
+            } catch (RemoteException e) {
+                Log.w(TAG, "IME died: " + mCurId, e);
+            }
+        }
+    }
+
+    /**
      * Returns true if the current input method wants to watch the location
      * of the input editor's cursor in its window.
      */
diff --git a/core/java/android/view/inputmethod/InputMethodSession.java b/core/java/android/view/inputmethod/InputMethodSession.java
index bb03afa..ea6f5ee 100644
--- a/core/java/android/view/inputmethod/InputMethodSession.java
+++ b/core/java/android/view/inputmethod/InputMethodSession.java
@@ -63,6 +63,15 @@
             int candidatesStart, int candidatesEnd);
 
     /**
+     * This method is called when the user tapped a text view.
+     * IMEs can't rely on this method being called because this was not part of the original IME
+     * protocol, so applications with custom text editing written before this method appeared will
+     * not call to inform the IME of this interaction.
+     * @param focusChanged true if the user changed the focused view by this click.
+     */
+    public void viewClicked(boolean focusChanged);
+
+    /**
      * This method is called when cursor location of the target input field
      * has changed within its window.  This is not normally called, but will
      * only be reported if requested by the input method.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 85e7eec..2a70ac8 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4948,7 +4948,10 @@
                         if (mMovement != null && mText instanceof Editable
                                 && mLayout != null && onCheckIsTextEditor()) {
                             InputMethodManager imm = InputMethodManager.peekInstance();
-                            if (imm != null) imm.showSoftInput(this, 0);
+                            if (imm != null) {
+                                imm.viewClicked(this);
+                                imm.showSoftInput(this, 0);
+                            }
                         }
                     }
                 }
@@ -7398,8 +7401,11 @@
 
             if ((isTextEditable() || mTextIsSelectable) && touchIsFinished) {
                 // Show the IME, except when selecting in read-only text.
+                final InputMethodManager imm = InputMethodManager.peekInstance();
+                if (imm != null) {
+                    imm.viewClicked(this);
+                }
                 if (!mTextIsSelectable) {
-                    final InputMethodManager imm = InputMethodManager.peekInstance();
                     handled |= imm != null && imm.showSoftInput(this, 0);
                 }
 
@@ -10010,6 +10016,127 @@
         return mInBatchEditControllers;
     }
 
+    /**
+     * Resolve the text direction.
+     *
+     * Text direction of paragraphs in a TextView is determined using a heuristic. If the correct
+     * text direction cannot be determined by the heuristic, the view’s resolved layout direction
+     * determines the direction.
+     *
+     * This heuristic and result is applied individually to each paragraph in a TextView, based on
+     * the text and style content of that paragraph. Paragraph text styles can also be used to force
+     * a particular direction.
+     */
+    @Override
+    protected void resolveTextDirection() {
+        int resolvedTextDirection = TEXT_DIRECTION_UNDEFINED;
+        switch(mTextDirection) {
+            default:
+            case TEXT_DIRECTION_INHERIT:
+                // Try to the text direction from the parent layout. If not possible, then we will
+                // use the default layout direction to decide later
+                if (mParent != null && mParent instanceof ViewGroup) {
+                    resolvedTextDirection = ((ViewGroup) mParent).getResolvedTextDirection();
+                }
+                break;
+            case TEXT_DIRECTION_FIRST_STRONG:
+                resolvedTextDirection = getTextDirectionFromFirstStrong(mText);
+                break;
+            case TEXT_DIRECTION_ANY_RTL:
+                resolvedTextDirection = getTextDirectionFromAnyRtl(mText);
+                break;
+            case TEXT_DIRECTION_LTR:
+                resolvedTextDirection = TEXT_DIRECTION_LTR;
+                break;
+            case TEXT_DIRECTION_RTL:
+                resolvedTextDirection = TEXT_DIRECTION_RTL;
+                break;
+        }
+        // if we have been so far unable to get the text direction from the heuristics, then we are
+        // falling back using the layout direction
+        if (resolvedTextDirection == TEXT_DIRECTION_UNDEFINED) {
+            switch(getResolvedLayoutDirection()) {
+                default:
+                case LAYOUT_DIRECTION_LTR:
+                    resolvedTextDirection = TEXT_DIRECTION_LTR;
+                    break;
+                case LAYOUT_DIRECTION_RTL:
+                    resolvedTextDirection = TEXT_DIRECTION_RTL;
+                    break;
+            }
+        }
+        mResolvedTextDirection = resolvedTextDirection;
+    }
+
+    /**
+     * Get text direction following the "first strong" heuristic.
+     *
+     * @param cs the CharSequence used to get the text direction.
+     *
+     * @return {@link #TEXT_DIRECTION_RTL} if direction it RTL, {@link #TEXT_DIRECTION_LTR} if
+     * direction it LTR or {@link #TEXT_DIRECTION_UNDEFINED} if direction cannot be found.
+     */
+    private static int getTextDirectionFromFirstStrong(final CharSequence cs) {
+        final int length = cs.length();
+        for(int i = 0; i < length; i++) {
+            final char c = cs.charAt(i);
+            final byte dir = Character.getDirectionality(c);
+            if (isStrongLtrChar(dir)) {
+                return TEXT_DIRECTION_LTR;
+            } else if (isStrongRtlChar(dir)) {
+                return TEXT_DIRECTION_RTL;
+            }
+        }
+        return TEXT_DIRECTION_UNDEFINED;
+    }
+
+    /**
+     * Get text direction following the "any RTL" heuristic.
+     *
+     * @param cs the CharSequence used to get the text direction.
+     *
+     * @return {@link #TEXT_DIRECTION_RTL} if direction it RTL, {@link #TEXT_DIRECTION_LTR} if
+     * direction it LTR or {@link #TEXT_DIRECTION_UNDEFINED} if direction cannot be found.
+     */
+    private static int getTextDirectionFromAnyRtl(final CharSequence cs) {
+        final int length = cs.length();
+        boolean foundStrongLtr = false;
+        boolean foundStrongRtl = false;
+        for(int i = 0; i < length; i++) {
+            final char c = cs.charAt(i);
+            final byte dir = Character.getDirectionality(c);
+            if (isStrongLtrChar(dir)) {
+                foundStrongLtr = true;
+            } else if (isStrongRtlChar(dir)) {
+                foundStrongRtl = true;
+            }
+        }
+        if (foundStrongRtl) {
+            return TEXT_DIRECTION_RTL;
+        }
+        if (foundStrongLtr) {
+            return TEXT_DIRECTION_LTR;
+        }
+        return TEXT_DIRECTION_UNDEFINED;
+    }
+
+    /**
+     * Return true if the char direction is corresponding to a "strong RTL char" following the
+     * Unicode Bidirectional Algorithm (UBA).
+     */
+    private static boolean isStrongRtlChar(final byte dir) {
+        return (dir == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
+                dir == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC);
+    }
+
+    /**
+     * Return true if the char direction is corresponding to a "strong LTR char" following the
+     * Unicode Bidirectional Algorithm (UBA).
+     */
+    private static boolean isStrongLtrChar(final byte dir) {
+        return (dir == Character.DIRECTIONALITY_LEFT_TO_RIGHT);
+    }
+
     @ViewDebug.ExportedProperty(category = "text")
     private CharSequence            mText;
     private CharSequence            mTransformed;
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 5e9cd23..f13e770 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -25,16 +25,13 @@
 import android.os.SystemProperties;
 import android.util.Log;
 import android.util.Slog;
-
 import com.android.internal.logging.AndroidConfig;
-
+import com.android.server.NetworkManagementSocketTagger;
 import dalvik.system.VMRuntime;
-
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.util.logging.LogManager;
 import java.util.TimeZone;
-
+import java.util.logging.LogManager;
 import org.apache.harmony.luni.internal.util.TimezoneGetter;
 
 /**
@@ -129,6 +126,11 @@
         System.setProperty("http.agent", userAgent);
 
         /*
+         * Wire socket tagging to traffic stats.
+         */
+        NetworkManagementSocketTagger.install();
+
+        /*
          * If we're running in an emulator launched with "-trace", put the
          * VM into emulator trace profiling mode so that the user can hit
          * F9/F10 at any time to capture traces.  This has performance
diff --git a/core/java/com/android/internal/view/IInputMethodSession.aidl b/core/java/com/android/internal/view/IInputMethodSession.aidl
index 338dcaa..f875cbd 100644
--- a/core/java/com/android/internal/view/IInputMethodSession.aidl
+++ b/core/java/com/android/internal/view/IInputMethodSession.aidl
@@ -36,7 +36,9 @@
     void updateSelection(int oldSelStart, int oldSelEnd,
             int newSelStart, int newSelEnd,
             int candidatesStart, int candidatesEnd);
-    
+
+    void viewClicked(boolean focusChanged);
+
     void updateCursor(in Rect newCursor);
     
     void displayCompletions(in CompletionInfo[] completions);
diff --git a/core/java/com/android/server/NetworkManagementSocketTagger.java b/core/java/com/android/server/NetworkManagementSocketTagger.java
new file mode 100644
index 0000000..306d223
--- /dev/null
+++ b/core/java/com/android/server/NetworkManagementSocketTagger.java
@@ -0,0 +1,165 @@
+/*
+ * 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.server;
+
+import dalvik.system.SocketTagger;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.SocketException;
+import java.nio.charset.Charsets;
+
+/**
+ * Assigns tags to sockets for traffic stats.
+ */
+public final class NetworkManagementSocketTagger extends SocketTagger {
+
+    private static final boolean LOGI = false;
+
+    private static ThreadLocal<SocketTags> threadSocketTags = new ThreadLocal<SocketTags>() {
+        @Override protected SocketTags initialValue() {
+            return new SocketTags();
+        }
+    };
+
+    public static void install() {
+        SocketTagger.set(new NetworkManagementSocketTagger());
+    }
+
+    public static void setThreadSocketStatsTag(int tag) {
+        threadSocketTags.get().statsTag = tag;
+    }
+
+    public static void setThreadSocketStatsUid(int uid) {
+        threadSocketTags.get().statsUid = uid;
+    }
+
+    @Override public void tag(FileDescriptor fd) throws SocketException {
+        final SocketTags options = threadSocketTags.get();
+        if (LOGI) {
+            System.logI("tagSocket(" + fd.getInt$() + ") with statsTag="
+                    + options.statsTag + ", statsUid=" + options.statsUid);
+        }
+        try {
+            // TODO: skip tagging when options would be no-op
+            tagSocketFd(fd, options.statsTag, options.statsUid);
+        } catch (IOException e) {
+            throw new SocketException("Problem tagging socket", e);
+        }
+    }
+
+    private void tagSocketFd(FileDescriptor fd, int tag, int uid) throws IOException {
+        final int fdNum = fd.getInt$();
+        if (fdNum == -1 || (tag == -1 && uid == -1)) return;
+
+        String cmd = "t " + fdNum;
+        if (tag == -1) {
+            // Case where just the uid needs adjusting. But probably the caller
+            // will want to track his own name here, just in case.
+            cmd += " 0";
+        } else {
+            cmd += " " + tagToKernel(tag);
+        }
+        if (uid != -1) {
+            cmd += " " + uid;
+        }
+        internalModuleCtrl(cmd);
+    }
+
+    @Override public void untag(FileDescriptor fd) throws SocketException {
+        if (LOGI) {
+            System.logI("untagSocket(" + fd.getInt$() + ")");
+        }
+        try {
+            unTagSocketFd(fd);
+        } catch (IOException e) {
+            throw new SocketException("Problem untagging socket", e);
+        }
+    }
+
+    private void unTagSocketFd(FileDescriptor fd) throws IOException {
+        int fdNum = fd.getInt$();
+        if (fdNum == -1) return;
+        String cmd = "u " + fdNum;
+        internalModuleCtrl(cmd);
+    }
+
+    public static class SocketTags {
+        public int statsTag = -1;
+        public int statsUid = -1;
+    }
+
+    /**
+     * Sends commands to the kernel netfilter module.
+     *
+     * @param cmd command string for the qtaguid netfilter module. May not be null.
+     *   <p>Supports:
+     *     <ul><li>tag a socket:<br>
+     *        <code>t <i>sock_fd</i> <i>acct_tag</i> [<i>uid_in_case_caller_is_acting_on_behalf_of</i>]</code><br>
+     *     <code>*_tag</code> defaults to default_policy_tag_from_uid(uid_of_caller)<br>
+     *     <code>acct_tag</code> is either 0 or greater that 2^32.<br>
+     *     <code>uid_*</code> is only settable by privileged UIDs (DownloadManager,...)
+     *     </li>
+     *     <li>untag a socket, preserving counters:<br>
+     *       <code>u <i>sock_fd</i></code>
+     *     </li></ul>
+     *   <p>Notes:<br>
+     *   <ul><li><i>sock_fd</i> is withing the callers process space.</li>
+     *   <li><i>*_tag</i> are 64bit values</li></ul>
+     *
+     */
+    private void internalModuleCtrl(String cmd) throws IOException {
+        final FileOutputStream procOut;
+        // TODO: Use something like
+        //  android.os.SystemProperties.getInt("persist.bandwidth.enable", 0)
+        // to see if tagging should happen or not.
+        try {
+            procOut = new FileOutputStream("/proc/net/xt_qtaguid/ctrl");
+        } catch (FileNotFoundException e) {
+            if (LOGI) {
+                System.logI("Can't talk to kernel module:" + e);
+            }
+            return;
+        }
+        try {
+            procOut.write(cmd.getBytes(Charsets.US_ASCII));
+        } finally {
+            procOut.close();
+        }
+    }
+
+    /**
+     * Convert {@link Integer} tag to {@code /proc/} format. Assumes unsigned
+     * base-10 format like {@code 2147483647}. Currently strips signed bit to
+     * avoid using {@link java.math.BigInteger}.
+     */
+    public static String tagToKernel(int tag) {
+        // TODO: eventually write in hex, since that's what proc exports
+        // TODO: migrate to direct integer instead of odd shifting
+        return Long.toString((((long) tag) << 32) & 0x7FFFFFFF00000000L);
+    }
+
+    /**
+     * Convert {@code /proc/} tag format to {@link Integer}. Assumes incoming
+     * format like {@code 0x7fffffff00000000}.
+     */
+    public static int kernelToTag(String string) {
+        // TODO: migrate to direct integer instead of odd shifting
+        return (int) (Long.decode(string) >> 32);
+    }
+}
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 37e6027..fd61cfd 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1972,6 +1972,24 @@
             <!-- Locale -->
             <enum name="locale" value="3" />
         </attr>
+        <!-- Direction of the text. A heuristic is used to determine the resolved text direction
+             of paragraphs. -->
+        <attr name="textDirection" format="integer">
+            <!-- Default -->
+            <enum name="inherit" value="0" />
+            <!-- Default for the root view. The first strong directional character determines the
+                 paragraph direction.  If there is o strong directional character, the paragraph
+                 direction is the view’s resolved layout direction. -->
+            <enum name="firstStrong" value="1" />
+            <!-- The paragraph direction is RTL if it contains any strong RTL character, otherwise
+                 it is LTR if it contains any strong LTR characters.  If there are neither, the
+                 paragraph direction is the view’s resolved layout direction. -->
+            <enum name="anyRtl" value="2" />
+            <!-- The text direction is left to right. -->
+            <enum name="ltr" value="3" />
+            <!-- The text direction is right to left. -->
+            <enum name="rtl" value="4" />
+        </attr>
     </declare-styleable>
 
     <!-- Attributes that can be used with a {@link android.view.ViewGroup} or any
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 7bbfa9c..db6f98f 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1782,4 +1782,5 @@
   <public type="integer" name="status_bar_notification_info_maxnum" />
   <public type="string" name="status_bar_notification_info_overflow" />
 
+  <public type="attr" name="textDirection"/>
 </resources>
diff --git a/core/tests/coretests/src/android/widget/TextViewTest.java b/core/tests/coretests/src/android/widget/TextViewTest.java
index d8d145c..a37f1a3 100644
--- a/core/tests/coretests/src/android/widget/TextViewTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewTest.java
@@ -22,6 +22,7 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.GetChars;
+import android.view.View;
 import android.widget.TextView;
 
 /**
@@ -58,4 +59,122 @@
         assertEquals('o', c2[4]);
         assertEquals('\0', c2[5]);
     }
+
+    @SmallTest
+    public void testTextDirectionDefault() {
+        TextView tv = new TextView(mContext);
+        assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getTextDirection());
+    }
+
+    @SmallTest
+    public void testSetGetTextDirection() {
+        TextView tv = new TextView(mContext);
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
+    }
+
+    @SmallTest
+    public void testGetResolvedTextDirectionLtr() {
+        TextView tv = new TextView(mContext);
+        tv.setText("this is a test");
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+    }
+
+    @SmallTest
+    public void testGetResolvedTextDirectionLtrWithInheritance() {
+        LinearLayout ll = new LinearLayout(mContext);
+        ll.setTextDirection(View.TEXT_DIRECTION_RTL);
+
+        TextView tv = new TextView(mContext);
+        tv.setText("this is a test");
+        ll.addView(tv);
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+    }
+
+    @SmallTest
+    public void testGetResolvedTextDirectionRtl() {
+        TextView tv = new TextView(mContext);
+        tv.setText("\u05DD\u05DE"); // hebrew
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+    }
+
+    @SmallTest
+    public void testGetResolvedTextDirectionRtlWithInheritance() {
+        LinearLayout ll = new LinearLayout(mContext);
+        ll.setTextDirection(View.TEXT_DIRECTION_RTL);
+
+        TextView tv = new TextView(mContext);
+        tv.setText("\u05DD\u05DE"); // hebrew
+        ll.addView(tv);
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+    }
 }
diff --git a/location/java/android/location/Country.java b/location/java/android/location/Country.java
index 3c05403..939bd4a 100755
--- a/location/java/android/location/Country.java
+++ b/location/java/android/location/Country.java
@@ -19,6 +19,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.Locale;
+
 /**
  * This class wraps the country information.
  *
@@ -74,7 +76,7 @@
                 || source > COUNTRY_SOURCE_LOCALE) {
             throw new IllegalArgumentException();
         }
-        mCountryIso = countryIso.toLowerCase();
+        mCountryIso = countryIso.toUpperCase(Locale.US);
         mSource = source;
     }
 
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 6f42596..e3cbd57 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -720,8 +720,9 @@
      *
      * <p>Since API level 13, if applications set a camera via
      * {@link #setCamera(Camera)}, the apps can use the camera after this method
-     * call. The apps do not need to lock the camera again. The apps should not
-     * start another recording session during recording.
+     * call. The apps do not need to lock the camera again. However, if this
+     * method fails, the apps should still lock the camera back. The apps should
+     * not start another recording session during recording.
      *
      * @throws IllegalStateException if it is called before
      * prepare().
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index bdffce9..ed8149a 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -158,9 +158,12 @@
     mVideoSize.width  = -1;
     mVideoSize.height = -1;
 
+    int64_t token = IPCThreadState::self()->clearCallingIdentity();
     mInitCheck = init(camera, proxy, cameraId,
                     videoSize, frameRate,
                     storeMetaDataInVideoBuffers);
+    if (mInitCheck != OK) releaseCamera();
+    IPCThreadState::self()->restoreCallingIdentity(token);
 }
 
 status_t CameraSource::initCheck() const {
@@ -295,7 +298,6 @@
     if (width != -1 && height != -1) {
         if (!isVideoSizeSupported(width, height, sizes)) {
             LOGE("Video dimension (%dx%d) is unsupported", width, height);
-            releaseCamera();
             return BAD_VALUE;
         }
         if (isSetVideoSizeSupportedByCamera) {
@@ -309,7 +311,6 @@
         // If one and only one of the width and height is -1
         // we reject such a request.
         LOGE("Requested video size (%dx%d) is not supported", width, height);
-        releaseCamera();
         return BAD_VALUE;
     } else {  // width == -1 && height == -1
         // Do not configure the camera.
@@ -327,7 +328,6 @@
         if (strstr(supportedFrameRates, buf) == NULL) {
             LOGE("Requested frame rate (%d) is not supported: %s",
                 frameRate, supportedFrameRates);
-            releaseCamera();
             return BAD_VALUE;
         }
 
@@ -463,7 +463,6 @@
         bool storeMetaDataInVideoBuffers) {
 
     status_t err = OK;
-    int64_t token = IPCThreadState::self()->clearCallingIdentity();
 
     if ((err = isCameraAvailable(camera, proxy, cameraId)) != OK) {
         LOGE("Camera connection could not be established.");
@@ -505,8 +504,6 @@
         }
     }
 
-    IPCThreadState::self()->restoreCallingIdentity(token);
-
     int64_t glitchDurationUs = (1000000LL / mVideoFrameRate);
     if (glitchDurationUs > mGlitchDurationThresholdUs) {
         mGlitchDurationThresholdUs = glitchDurationUs;
@@ -573,13 +570,21 @@
 
 void CameraSource::releaseCamera() {
     LOGV("releaseCamera");
-    if ((mCameraFlags & FLAGS_HOT_CAMERA) == 0) {
-        LOGV("Camera was cold when we started, stopping preview");
-        mCamera->stopPreview();
+    if (mCamera != 0) {
+        if ((mCameraFlags & FLAGS_HOT_CAMERA) == 0) {
+            LOGV("Camera was cold when we started, stopping preview");
+            mCamera->stopPreview();
+            mCamera->disconnect();
+        } else {
+            // Unlock the camera so the application can lock it back.
+            mCamera->unlock();
+        }
+        mCamera.clear();
     }
-    mCamera.clear();
-    mCameraRecordingProxy->asBinder()->unlinkToDeath(mDeathNotifier);
-    mCameraRecordingProxy.clear();
+    if (mCameraRecordingProxy != 0) {
+        mCameraRecordingProxy->asBinder()->unlinkToDeath(mDeathNotifier);
+        mCameraRecordingProxy.clear();
+    }
     mCameraFlags = 0;
 }
 
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index cd97302..e36b01f 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1838,7 +1838,7 @@
         }
     }
 
-    LOGV("native_window_set_usage usage=0x%x", usage);
+    LOGV("native_window_set_usage usage=0x%lx", usage);
     err = native_window_set_usage(
             mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
     if (err != 0) {
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
index ed6846c..967f126 100644
--- a/media/libstagefright/chromium_http/support.cpp
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -41,6 +41,7 @@
 static Mutex gNetworkThreadLock;
 static base::Thread *gNetworkThread = NULL;
 static scoped_refptr<net::URLRequestContext> gReqContext;
+static scoped_ptr<net::NetworkChangeNotifier> gNetworkChangeNotifier;
 
 static void InitializeNetworkThreadIfNecessary() {
     Mutex::Autolock autoLock(gNetworkThreadLock);
@@ -52,6 +53,8 @@
 
         gReqContext = new SfRequestContext;
 
+        gNetworkChangeNotifier.reset(net::NetworkChangeNotifier::Create());
+
         net::AndroidNetworkLibrary::RegisterSharedInstance(
                 new SfNetworkLibrary);
     }
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index b03bd4d..14abf80 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1641,7 +1641,7 @@
             final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
             if (imi == null) return false;
             final int N = subtypes.length;
-            mFileManager.addInputMethodSubtypes(mCurMethodId, subtypes);
+            mFileManager.addInputMethodSubtypes(imi, subtypes);
             buildInputMethodListLocked(mMethodList, mMethodMap);
             return true;
         }
@@ -2023,25 +2023,26 @@
                 final CharSequence label = imi.loadLabel(pm);
                 if (showSubtypes && enabledSubtypeSet.size() > 0) {
                     final int subtypeCount = imi.getSubtypeCount();
+                    if (DEBUG) {
+                        Slog.v(TAG, "Add subtypes: " + subtypeCount + ", " + imi.getId());
+                    }
                     for (int j = 0; j < subtypeCount; ++j) {
-                        InputMethodSubtype subtype = imi.getSubtypeAt(j);
-                        if (enabledSubtypeSet.contains(String.valueOf(subtype.hashCode()))
-                                && !subtype.isAuxiliary()) {
+                        final InputMethodSubtype subtype = imi.getSubtypeAt(j);
+                        final String subtypeHashCode = String.valueOf(subtype.hashCode());
+                        // We show all enabled IMEs and subtypes when an IME is shown.
+                        if (enabledSubtypeSet.contains(subtypeHashCode)
+                                && (mInputShown || !subtype.isAuxiliary())) {
                             final CharSequence title;
-                            int nameResId = subtype.getNameResId();
-                            String mode = subtype.getMode();
-                            if (nameResId != 0) {
-                                title = TextUtils.concat(subtype.getDisplayName(context,
-                                        imi.getPackageName(), imi.getServiceInfo().applicationInfo),
-                                        (TextUtils.isEmpty(label) ? "" : " (" + label + ")"));
-                            } else {
-                                CharSequence language = subtype.getLocale();
-                                // TODO: Use more friendly Title and UI
-                                title = label + "," + (mode == null ? "" : mode) + ","
-                                        + (language == null ? "" : language);
-                            }
+                            final String mode = subtype.getMode();
+                            title = TextUtils.concat(subtype.getDisplayName(context,
+                                    imi.getPackageName(), imi.getServiceInfo().applicationInfo),
+                                    (TextUtils.isEmpty(label) ? "" : " (" + label + ")"));
                             imList.add(new Pair<CharSequence, Pair<InputMethodInfo, Integer>>(
                                     title, new Pair<InputMethodInfo, Integer>(imi, j)));
+                            // Removing this subtype from enabledSubtypeSet because we no longer
+                            // need to add an entry of this subtype to imList to avoid duplicated
+                            // entries.
+                            enabledSubtypeSet.remove(subtypeHashCode);
                         }
                     }
                 } else {
@@ -2338,7 +2339,7 @@
                 }
             }
         }
-        ArrayList<InputMethodSubtype> applicableSubtypes = new ArrayList<InputMethodSubtype>(
+        final ArrayList<InputMethodSubtype> applicableSubtypes = new ArrayList<InputMethodSubtype>(
                 applicableModeAndSubtypesMap.values());
         if (!containsKeyboardSubtype) {
             InputMethodSubtype lastResortKeyboardSubtype = findLastResortApplicableSubtypeLocked(
@@ -3016,17 +3017,23 @@
         }
 
         public void addInputMethodSubtypes(
-                String imiId, InputMethodSubtype[] additionalSubtypes) {
+                InputMethodInfo imi, InputMethodSubtype[] additionalSubtypes) {
             synchronized (mMethodMap) {
+                final HashSet<InputMethodSubtype> existingSubtypes =
+                        new HashSet<InputMethodSubtype>();
+                for (int i = 0; i < imi.getSubtypeCount(); ++i) {
+                    existingSubtypes.add(imi.getSubtypeAt(i));
+                }
+
                 final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
                 final int N = additionalSubtypes.length;
                 for (int i = 0; i < N; ++i) {
                     final InputMethodSubtype subtype = additionalSubtypes[i];
-                    if (!subtypes.contains(subtype)) {
+                    if (!subtypes.contains(subtype) && !existingSubtypes.contains(subtype)) {
                         subtypes.add(subtype);
                     }
                 }
-                mSubtypesMap.put(imiId, subtypes);
+                mSubtypesMap.put(imi.getId(), subtypes);
                 writeAdditionalInputMethodSubtypes(mSubtypesMap, mAdditionalInputMethodSubtypeFile,
                         mMethodMap);
             }
@@ -3133,8 +3140,8 @@
                                 parser.getAttributeValue(null, ATTR_IME_SUBTYPE_MODE);
                         final String imeSubtypeExtraValue =
                                 parser.getAttributeValue(null, ATTR_IME_SUBTYPE_EXTRA_VALUE);
-                        final boolean isAuxiliary =
-                                Boolean.valueOf(parser.getAttributeValue(null, ATTR_IS_AUXILIARY));
+                        final boolean isAuxiliary = "1".equals(String.valueOf(
+                                parser.getAttributeValue(null, ATTR_IS_AUXILIARY)));
                         final InputMethodSubtype subtype =
                                 new InputMethodSubtype(label, icon, imeSubtypeLocale,
                                         imeSubtypeMode, imeSubtypeExtraValue, isAuxiliary);
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 630aaf9..8d92a39 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -41,8 +41,6 @@
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
-import dalvik.system.BlockGuard;
-
 import java.io.BufferedReader;
 import java.io.DataInputStream;
 import java.io.File;
@@ -921,6 +919,38 @@
     }
 
     @Override
+    public void setInterfaceQuota(String[] iface, long quota)
+            throws IllegalStateException {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.MANAGE_NETWORK_POLICY, "NetworkManagementService");
+        try {
+            // TODO: Add support for clubbing together multiple interfaces under
+            // one quota. Will need support from the kernel and
+            // BandwidthController to do this.
+            mConnector.doCommand(
+                    String.format("bandwidth setquota %s %d", iface[0], quota));
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Error communicating to native daemon to set Interface quota",
+                    e);
+        }
+    }
+
+    @Override
+    public void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces)
+            throws IllegalStateException {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.MANAGE_NETWORK_POLICY, "NetworkManagementService");
+        try {
+            // TODO: Connect with BandwidthController
+            // mConnector.doCommand("");
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Error communicating to native daemon to set Interface quota",
+                    e);
+        }
+    }
+
     public NetworkStats getNetworkStatsUidDetail(int uid) {
         if (Binder.getCallingUid() != uid) {
             mContext.enforceCallingOrSelfPermission(
@@ -958,7 +988,8 @@
 
                 try {
                     final String iface = parsed.get(KEY_IFACE);
-                    final int tag = BlockGuard.kernelToTag(parsed.get(KEY_TAG_HEX));
+                    final int tag = NetworkManagementSocketTagger.kernelToTag(
+                            parsed.get(KEY_TAG_HEX));
                     final int uid = Integer.parseInt(parsed.get(KEY_UID));
                     final long rx = Long.parseLong(parsed.get(KEY_RX));
                     final long tx = Long.parseLong(parsed.get(KEY_TX));
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index cd68c68..dbfd145 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -283,7 +283,8 @@
             try {
                 Slog.i(TAG, "NetworkPolicy Service");
                 networkPolicy = new NetworkPolicyManagerService(
-                        context, ActivityManagerService.self(), power, networkStats);
+                        context, ActivityManagerService.self(), power,
+                        networkStats, networkManagement);
                 ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
             } catch (Throwable e) {
                 Slog.e(TAG, "Failure starting NetworkPolicy Service", e);
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 12d3ed8..8a93f43 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -71,6 +71,7 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.INetworkManagementService;
 import android.os.IPowerManager;
 import android.os.Message;
 import android.os.RemoteCallbackList;
@@ -156,6 +157,7 @@
     private final IActivityManager mActivityManager;
     private final IPowerManager mPowerManager;
     private final INetworkStatsService mNetworkStats;
+    private final INetworkManagementService mNetworkManagement;
     private final TrustedTime mTime;
 
     private IConnectivityManager mConnManager;
@@ -193,9 +195,11 @@
     // rules enforced, such as system, phone, and radio UIDs.
 
     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
-            IPowerManager powerManager, INetworkStatsService networkStats) {
+            IPowerManager powerManager, INetworkStatsService networkStats,
+            INetworkManagementService networkManagement) {
         // TODO: move to using cached NtpTrustedTime
-        this(context, activityManager, powerManager, networkStats, new NtpTrustedTime(),
+        this(context, activityManager, powerManager, networkStats,
+                networkManagement, new NtpTrustedTime(),
                 getSystemDir());
     }
 
@@ -204,12 +208,14 @@
     }
 
     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
-            IPowerManager powerManager, INetworkStatsService networkStats, TrustedTime time,
-            File systemDir) {
+            IPowerManager powerManager, INetworkStatsService networkStats,
+            INetworkManagementService networkManagement,
+            TrustedTime time, File systemDir) {
         mContext = checkNotNull(context, "missing context");
         mActivityManager = checkNotNull(activityManager, "missing activityManager");
         mPowerManager = checkNotNull(powerManager, "missing powerManager");
         mNetworkStats = checkNotNull(networkStats, "missing networkStats");
+        mNetworkManagement = checkNotNull(networkManagement, "missing networkManagementService");
         mTime = checkNotNull(time, "missing TrustedTime");
 
         mHandlerThread = new HandlerThread(TAG);
@@ -589,7 +595,13 @@
             if (policy.limitBytes != NetworkPolicy.LIMIT_DISABLED) {
                 // remaining "quota" is based on usage in current cycle
                 final long quota = Math.max(0, policy.limitBytes - total);
-                //kernelSetIfacesQuota(ifaces, quota);
+                if (LOGD) {
+                    Slog.d(TAG, "Applying quota rules for ifaces=" + Arrays.toString(ifaces)
+                            + " LIMIT=" + policy.limitBytes + "  TOTAL="
+                            + total + "  QUOTA=" + quota);
+                }
+
+                setQuotaOnIfaceList(ifaces, quota);
 
                 for (String iface : ifaces) {
                     mMeteredIfaces.add(iface);
@@ -601,6 +613,32 @@
         mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget();
     }
 
+    private void setQuotaOnIfaceList(String[] ifaces, long quota) {
+        try {
+            mNetworkManagement.setInterfaceQuota(ifaces, quota);
+        } catch (IllegalStateException e) {
+            Slog.e(TAG, "IllegalStateException in setQuotaOnIfaceList " + e);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Remote Exception in setQuotaOnIfaceList " + e);
+        }
+    }
+
+    private void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
+        // TODO: connect over to NMS
+        // ndc bandwidth app <uid> naughty
+        try {
+            if (LOGD) {
+                Slog.d(TAG, "setUidNetworkRules() with uid=" + uid
+                        + ", rejectOnQuotaInterfaces=" + rejectOnQuotaInterfaces);
+            }
+            mNetworkManagement.setUidNetworkRules(uid, rejectOnQuotaInterfaces);
+        } catch (IllegalStateException e) {
+            Slog.e(TAG, "IllegalStateException in setUidNetworkRules " + e);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Remote Exception in setUidNetworkRules " + e);
+        }
+    }
+
     /**
      * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
      * have at least a default mobile policy defined.
@@ -955,7 +993,7 @@
         mUidRules.put(uid, uidRules);
 
         final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0;
-        //kernelSetUidRejectPaid(uid, rejectPaid);
+        setUidNetworkRules(uid, rejectMetered);
 
         // dispatch changed rule to existing listeners
         mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules).sendToTarget();
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
index 8b752ee..ac7cb5a 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -16,8 +16,8 @@
 
 package com.android.server;
 
-import static dalvik.system.BlockGuard.kernelToTag;
-import static dalvik.system.BlockGuard.tagToKernel;
+import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
+import static com.android.server.NetworkManagementSocketTagger.tagToKernel;
 
 import android.content.res.Resources;
 import android.net.NetworkStats;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 324e896..af2e01c 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -56,6 +56,7 @@
 import android.net.NetworkStats;
 import android.net.NetworkTemplate;
 import android.os.Binder;
+import android.os.INetworkManagementService;
 import android.os.IPowerManager;
 import android.test.AndroidTestCase;
 import android.test.mock.MockPackageManager;
@@ -95,6 +96,7 @@
     private IActivityManager mActivityManager;
     private IPowerManager mPowerManager;
     private INetworkStatsService mStatsService;
+    private INetworkManagementService mNetworkManagement;
     private INetworkPolicyListener mPolicyListener;
     private TrustedTime mTime;
     private IConnectivityManager mConnManager;
@@ -150,13 +152,15 @@
         mActivityManager = createMock(IActivityManager.class);
         mPowerManager = createMock(IPowerManager.class);
         mStatsService = createMock(INetworkStatsService.class);
+        mNetworkManagement = createMock(INetworkManagementService.class);
         mPolicyListener = createMock(INetworkPolicyListener.class);
         mTime = createMock(TrustedTime.class);
         mConnManager = createMock(IConnectivityManager.class);
         mNotifManager = createMock(INotificationManager.class);
 
         mService = new NetworkPolicyManagerService(
-                mServiceContext, mActivityManager, mPowerManager, mStatsService, mTime, mPolicyDir);
+                mServiceContext, mActivityManager, mPowerManager, mStatsService,
+                mNetworkManagement, mTime, mPolicyDir);
         mService.bindConnectivityManager(mConnManager);
         mService.bindNotificationManager(mNotifManager);
 
@@ -526,14 +530,14 @@
     }
 
     private void replay() {
-        EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime,
-                mConnManager, mNotifManager);
+        EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
+                mNetworkManagement, mTime, mConnManager, mNotifManager);
     }
 
     private void verifyAndReset() {
-        EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime,
-                mConnManager, mNotifManager);
-        EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime,
-                mConnManager, mNotifManager);
+        EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
+                mNetworkManagement, mTime, mConnManager, mNotifManager);
+        EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
+                mNetworkManagement, mTime, mConnManager, mNotifManager);
     }
 }
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
index c4a6f53..6e9d0f9d 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -502,16 +502,17 @@
 
     @SmallTest
     public void testFormatNumberToE164() {
-        assertEquals("+16502910000", PhoneNumberUtils.formatNumberToE164("650 2910000", "us"));
-        assertNull(PhoneNumberUtils.formatNumberToE164("1234567", "us"));
-        assertEquals("+18004664114", PhoneNumberUtils.formatNumberToE164("800-GOOG-114", "us"));
+        // Note: ISO 3166-1 only allows upper case country codes.
+        assertEquals("+16502910000", PhoneNumberUtils.formatNumberToE164("650 2910000", "US"));
+        assertNull(PhoneNumberUtils.formatNumberToE164("1234567", "US"));
+        assertEquals("+18004664114", PhoneNumberUtils.formatNumberToE164("800-GOOG-114", "US"));
     }
 
     @SmallTest
     public void testFormatNumber() {
-        assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("650 2910000", "us"));
-        assertEquals("123-4567", PhoneNumberUtils.formatNumber("1234567", "us"));
-        assertEquals("(800) 466-4114", PhoneNumberUtils.formatNumber("800-GOOG-114", "us"));
+        assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("650 2910000", "US"));
+        assertEquals("123-4567", PhoneNumberUtils.formatNumber("1234567", "US"));
+        assertEquals("(800) 466-4114", PhoneNumberUtils.formatNumber("800-GOOG-114", "US"));
 
     }
 
diff --git a/tests/BiDiTests/res/layout/textview_direction_ltr.xml b/tests/BiDiTests/res/layout/textview_direction_ltr.xml
new file mode 100644
index 0000000..f7b7b8e
--- /dev/null
+++ b/tests/BiDiTests/res/layout/textview_direction_ltr.xml
@@ -0,0 +1,112 @@
+<?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_direction_ltr"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layoutDirection="ltr">
+
+    <LinearLayout android:orientation="vertical"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:textDirection="ltr">
+
+        <LinearLayout android:orientation="vertical"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content">
+
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_text"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_text"
+                      android:textDirection="inherit"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_text"
+                      android:textDirection="firstStrong"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_text"
+                      android:textDirection="anyRtl"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_text"
+                      android:textDirection="ltr"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_text"
+                      android:textDirection="rtl"
+                    />
+        </LinearLayout>
+
+        <LinearLayout android:orientation="vertical"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content">
+
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_hebrew_text"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_hebrew_text"
+                      android:textDirection="inherit"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_hebrew_text"
+                      android:textDirection="firstStrong"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_hebrew_text"
+                      android:textDirection="anyRtl"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_hebrew_text"
+                      android:textDirection="ltr"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_hebrew_text"
+                      android:textDirection="rtl"
+                    />
+        </LinearLayout>
+
+    </LinearLayout>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/tests/BiDiTests/res/layout/textview_direction_rtl.xml b/tests/BiDiTests/res/layout/textview_direction_rtl.xml
new file mode 100644
index 0000000..81c5411
--- /dev/null
+++ b/tests/BiDiTests/res/layout/textview_direction_rtl.xml
@@ -0,0 +1,112 @@
+<?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_direction_rtl"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layoutDirection="rtl">
+
+    <LinearLayout android:orientation="vertical"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:textDirection="rtl">
+
+        <LinearLayout android:orientation="vertical"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content">
+
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_text"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_text"
+                      android:textDirection="inherit"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_text"
+                      android:textDirection="firstStrong"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_text"
+                      android:textDirection="anyRtl"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_text"
+                      android:textDirection="ltr"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_text"
+                      android:textDirection="rtl"
+                    />
+        </LinearLayout>
+
+        <LinearLayout android:orientation="vertical"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content">
+
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_hebrew_text"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_hebrew_text"
+                      android:textDirection="inherit"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_hebrew_text"
+                      android:textDirection="firstStrong"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_hebrew_text"
+                      android:textDirection="anyRtl"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_hebrew_text"
+                      android:textDirection="ltr"
+                    />
+            <TextView android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="24dip"
+                      android:text="@string/textview_hebrew_text"
+                      android:textDirection="rtl"
+                    />
+        </LinearLayout>
+
+    </LinearLayout>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
index b1e494a..c033879 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
@@ -122,9 +122,6 @@
         addItem(result, "Table RTL", BiDiTestTableLayoutRtl.class, R.id.table_layout_rtl);
         addItem(result, "Table LOC", BiDiTestTableLayoutLocale.class, R.id.table_layout_locale);
 
-        addItem(result, "ViewPadding", BiDiTestViewPadding.class, R.id.view_padding);
-        addItem(result, "ViewPadding MIXED", BiDiTestViewPaddingMixed.class, R.id.view_padding_mixed);
-
         addItem(result, "Padding", BiDiTestViewPadding.class, R.id.view_padding);
         addItem(result, "Padding MIXED", BiDiTestViewPaddingMixed.class, R.id.view_padding_mixed);
 
@@ -134,6 +131,9 @@
         addItem(result, "TextView RTL", BiDiTestTextViewRtl.class, R.id.textview_rtl);
         addItem(result, "TextView LOC", BiDiTestTextViewLocale.class, R.id.textview_locale);
 
+        addItem(result, "TextDirection LTR", BiDiTestTextViewDirectionLtr.class, R.id.textview_direction_ltr);
+        addItem(result, "TextDirection RTL", BiDiTestTextViewDirectionRtl.class, R.id.textview_direction_rtl);
+
         return result;
     }
 
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewDirectionLtr.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewDirectionLtr.java
new file mode 100644
index 0000000..882ed1f
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewDirectionLtr.java
@@ -0,0 +1,31 @@
+/*
+ * 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 BiDiTestTextViewDirectionLtr extends Fragment {
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.textview_direction_ltr, container, false);
+    }
+}
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewDirectionRtl.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewDirectionRtl.java
new file mode 100644
index 0000000..e63ee35
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewDirectionRtl.java
@@ -0,0 +1,31 @@
+/*
+ * 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 BiDiTestTextViewDirectionRtl extends Fragment {
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.textview_direction_rtl, container, false);
+    }
+}