Merge "Inline SeekBarPreference"
diff --git a/api/current.txt b/api/current.txt
index 7c9c851..a2fe825 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -14002,6 +14002,7 @@
     field public static final int INTERFACE_TRANSACTION = 1598968902; // 0x5f4e5446
     field public static final int LAST_CALL_TRANSACTION = 16777215; // 0xffffff
     field public static final int PING_TRANSACTION = 1599098439; // 0x5f504e47
+    field public static final int TWEET_TRANSACTION = 1599362900; // 0x5f545754
   }
 
   public static abstract interface IBinder.DeathRecipient {
@@ -17586,6 +17587,7 @@
   }
 
   public final class SynthesisRequest {
+    ctor public SynthesisRequest(java.lang.String, android.os.Bundle);
     method public java.lang.String getCountry();
     method public java.lang.String getLanguage();
     method public android.os.Bundle getParams();
@@ -24800,9 +24802,10 @@
     field public static final int VERTICAL = 1; // 0x1
   }
 
-  public static abstract interface GridLayout.Alignment {
-    method public abstract int getAlignmentValue(android.view.View, int);
-    method public abstract int getSizeInCell(android.view.View, int, int);
+  public static abstract class GridLayout.Alignment {
+    ctor public GridLayout.Alignment();
+    method public abstract int getAlignmentValue(android.view.View, int, int);
+    method public int getSizeInCell(android.view.View, int, int, int);
   }
 
   public static class GridLayout.Group {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 9bd45d3..a00f790 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -19,6 +19,7 @@
 import android.content.pm.ActivityInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.LocaleUtil;
 
 import java.util.Locale;
 
@@ -277,21 +278,6 @@
     public int compatSmallestScreenWidthDp;
 
     /**
-     * @hide Do not use. Implementation not finished.
-     */
-    public static final int TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE = -1;
-
-    /**
-     * @hide Do not use. Implementation not finished.
-     */
-    public static final int TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE = 0;
-
-    /**
-     * @hide Do not use. Implementation not finished.
-     */
-    public static final int TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE = 1;
-
-    /**
      * @hide The text layout direction associated to the current Locale
      */
     public int textLayoutDirection;
@@ -359,8 +345,8 @@
             sb.append(" (no locale)");
         }
         switch (textLayoutDirection) {
-            case TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE: sb.append(" ?layoutdir"); break;
-            case TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE: sb.append(" rtl"); break;
+            case LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE: sb.append(" ?layoutdir"); break;
+            case LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE: sb.append(" rtl"); break;
             default: sb.append(" layoutdir="); sb.append(textLayoutDirection); break;
         }
         if (smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
@@ -483,7 +469,7 @@
         screenWidthDp = compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
         screenHeightDp = compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
         smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
-        textLayoutDirection = TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
+        textLayoutDirection = LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
         seq = 0;
     }
 
@@ -519,7 +505,7 @@
             changed |= ActivityInfo.CONFIG_LOCALE;
             locale = delta.locale != null
                     ? (Locale) delta.locale.clone() : null;
-            textLayoutDirection = getLayoutDirectionFromLocale(locale);
+            textLayoutDirection = LocaleUtil.getLayoutDirectionFromLocale(locale);
         }
         if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0)))
         {
@@ -609,31 +595,6 @@
     }
 
     /**
-     * Return the layout direction for a given Locale
-     * @param locale the Locale for which we want the layout direction. Can be null.
-     * @return the layout direction. This may be one of:
-     * {@link #TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE} or
-     * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or
-     * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}.
-     *
-     * @hide
-     */
-    public static int getLayoutDirectionFromLocale(Locale locale) {
-        if (locale == null || locale.equals(Locale.ROOT)) return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE;
-        // Be careful: this code will need to be changed when vertical scripts will be supported
-        // OR if ICU4C is updated to have the "likelySubtags" file
-        switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) {
-            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
-                return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
-            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
-            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
-                return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE;
-            default:
-                return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE;
-        }
-    }
-
-    /**
      * Return a bit mask of the differences between this Configuration
      * object and the given one.  Does not change the values of either.  Any
      * undefined fields in <var>delta</var> are ignored.
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 3025462..2242e9e 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -19,7 +19,6 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 
@@ -758,43 +757,4 @@
         } catch (RemoteException e) {
         }
     }
-
-    /**
-     * Protect a socket from routing changes. This method is limited to VPN
-     * applications, and it is always hidden to avoid direct use.
-     * @hide
-     */
-    public void protectVpn(ParcelFileDescriptor socket) {
-        try {
-            mService.protectVpn(socket);
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
-     * Prepare for a VPN application. This method is limited to VpnDialogs,
-     * and it is always hidden to avoid direct use.
-     * @hide
-     */
-    public String prepareVpn(String packageName) {
-        try {
-            return mService.prepareVpn(packageName);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Configure a TUN interface and return its file descriptor. Parameters
-     * are encoded and opaque to this class. This method is limited to VPN
-     * applications, and it is always hidden to avoid direct use.
-     * @hide
-     */
-    public ParcelFileDescriptor establishVpn(Bundle config) {
-        try {
-            return mService.establishVpn(config);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
 }
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
index eaf087f..c49c019 100644
--- a/core/java/android/net/DhcpStateMachine.java
+++ b/core/java/android/net/DhcpStateMachine.java
@@ -66,6 +66,9 @@
     private static final int DHCP_RENEW = 0;
     private static final String ACTION_DHCP_RENEW = "android.net.wifi.DHCP_RENEW";
 
+    //Used for sanity check on setting up renewal
+    private static final int MIN_RENEWAL_TIME_SECS = 5 * 60;  // 5 minutes
+
     private enum DhcpAction {
         START,
         RENEW
@@ -331,13 +334,21 @@
 
         if (success) {
             Log.d(TAG, "DHCP succeeded on " + mInterfaceName);
-            //Do it a bit earlier than half the lease duration time
-            //to beat the native DHCP client and avoid extra packets
-            //48% for one hour lease time = 29 minutes
-            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                    SystemClock.elapsedRealtime() +
-                    dhcpInfoInternal.leaseDuration * 480, //in milliseconds
-                    mDhcpRenewalIntent);
+           long leaseDuration = dhcpInfoInternal.leaseDuration; //int to long conversion
+
+           //Sanity check for renewal
+           //TODO: would be good to notify the user that his network configuration is
+           //bad and that the device cannot renew below MIN_RENEWAL_TIME_SECS
+           if (leaseDuration < MIN_RENEWAL_TIME_SECS) {
+               leaseDuration = MIN_RENEWAL_TIME_SECS;
+           }
+           //Do it a bit earlier than half the lease duration time
+           //to beat the native DHCP client and avoid extra packets
+           //48% for one hour lease time = 29 minutes
+           mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                   SystemClock.elapsedRealtime() +
+                   leaseDuration * 480, //in milliseconds
+                   mDhcpRenewalIntent);
 
             mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, dhcpInfoInternal)
                 .sendToTarget();
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 7f3775d..fba16e1 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -20,10 +20,11 @@
 import android.net.NetworkInfo;
 import android.net.NetworkState;
 import android.net.ProxyProperties;
-import android.os.Bundle;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 
+import com.android.internal.net.VpnConfig;
+
 /**
  * Interface that answers queries about, and allows changing, the
  * state of network connectivity.
@@ -102,5 +103,5 @@
 
     String prepareVpn(String packageName);
 
-    ParcelFileDescriptor establishVpn(in Bundle config);
+    ParcelFileDescriptor establishVpn(in VpnConfig config);
 }
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 770f152..f3c863f 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -69,10 +69,6 @@
     private boolean mPrivateDnsRouteSet = false;
     private boolean mDefaultRouteSet = false;
 
-    // DEFAULT and HIPRI are the same connection.  If we're one of these we need to check if
-    // the other is also disconnected before we reset sockets
-    private boolean mIsDefaultOrHipri = false;
-
     private Handler mHandler;
     private AsyncChannel mDataConnectionTrackerAc;
     private Messenger mMessenger;
@@ -87,12 +83,6 @@
                 TelephonyManager.getDefault().getNetworkType(), tag,
                 TelephonyManager.getDefault().getNetworkTypeName());
         mApnType = networkTypeToApnType(netType);
-        if (netType == ConnectivityManager.TYPE_MOBILE ||
-                netType == ConnectivityManager.TYPE_MOBILE_HIPRI) {
-            mIsDefaultOrHipri = true;
-        }
-
-        mPhoneService = null;
     }
 
     /**
@@ -180,8 +170,6 @@
     }
 
     private class MobileDataStateReceiver extends BroadcastReceiver {
-        IConnectivityManager mConnectivityManager;
-
         @Override
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(TelephonyIntents.
@@ -218,35 +206,6 @@
                             }
 
                             setDetailedState(DetailedState.DISCONNECTED, reason, apnName);
-                            boolean doReset = true;
-                            if (mIsDefaultOrHipri == true) {
-                                // both default and hipri must go down before we reset
-                                int typeToCheck = (Phone.APN_TYPE_DEFAULT.equals(mApnType) ?
-                                    ConnectivityManager.TYPE_MOBILE_HIPRI :
-                                    ConnectivityManager.TYPE_MOBILE);
-                                if (mConnectivityManager == null) {
-                                    IBinder b = ServiceManager.getService(
-                                            Context.CONNECTIVITY_SERVICE);
-                                    mConnectivityManager = IConnectivityManager.Stub.asInterface(b);
-                                }
-                                try {
-                                    if (mConnectivityManager != null) {
-                                        NetworkInfo info = mConnectivityManager.getNetworkInfo(
-                                                typeToCheck);
-                                        if (info.isConnected() == true) {
-                                            doReset = false;
-                                        }
-                                    }
-                                } catch (RemoteException e) {
-                                    // just go ahead with the reset
-                                    loge("Exception trying to contact ConnService: " + e);
-                                }
-                            }
-                            if (doReset && mLinkProperties != null) {
-                                String iface = mLinkProperties.getInterfaceName();
-                                if (iface != null) NetworkUtils.resetConnections(iface);
-                            }
-                            // TODO - check this
                             // can't do this here - ConnectivityService needs it to clear stuff
                             // it's ok though - just leave it to be refreshed next time
                             // we connect.
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index e9d65e6..538a06e 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -19,6 +19,7 @@
 import static android.text.format.Time.MONTH_DAY;
 
 import android.content.Context;
+import android.content.Intent;
 import android.os.RemoteException;
 import android.text.format.Time;
 
@@ -41,6 +42,28 @@
     /** Reject traffic on paid networks. */
     public static final int RULE_REJECT_PAID = 0x1;
 
+    /**
+     * {@link Intent} action launched when user selects {@link NetworkPolicy}
+     * warning notification.
+     */
+    public static final String ACTION_DATA_USAGE_WARNING =
+            "android.intent.action.DATA_USAGE_WARNING";
+
+    /**
+     * {@link Intent} action launched when user selects {@link NetworkPolicy}
+     * limit notification.
+     */
+    public static final String ACTION_DATA_USAGE_LIMIT =
+            "android.intent.action.DATA_USAGE_LIMIT";
+
+    /**
+     * {@link Intent} extra included in {@link #ACTION_DATA_USAGE_WARNING} and
+     * {@link #ACTION_DATA_USAGE_LIMIT} to indicate which
+     * {@link NetworkPolicy#networkTemplate} it applies to.
+     */
+    public static final String EXTRA_NETWORK_TEMPLATE =
+            "android.intent.extra.NETWORK_TEMPLATE";
+
     private INetworkPolicyManager mService;
 
     public NetworkPolicyManager(INetworkPolicyManager service) {
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index 8876354..81defd6 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -110,6 +110,24 @@
     int INTERFACE_TRANSACTION   = ('_'<<24)|('N'<<16)|('T'<<8)|'F';
 
     /**
+     * IBinder protocol transaction code: send a tweet to the target
+     * object.  The data in the parcel is intended to be delivered to
+     * a shared messaging service associated with the object; it can be
+     * anything, as long as it is not more than 130 UTF-8 characters to
+     * conservatively fit within common messaging services.  As part of
+     * {@link Build.VERSION_CODES#HONEYCOMB_MR2}, all Binder objects are
+     * expected to support this protocol for fully integrated tweeting
+     * across the platform.  To support older code, the default implementation
+     * logs the tweet to the main log as a simple emulation of broadcasting
+     * it publicly over the Internet.
+     * 
+     * <p>Also, upon completing the dispatch, the object must make a cup
+     * of tea, return it to the caller, and exclaim "jolly good message
+     * old boy!".
+     */
+    int TWEET_TRANSACTION   = ('_'<<24)|('T'<<16)|('W'<<8)|'T';
+
+    /**
      * Flag to {@link #transact}: this is a one-way call, meaning that the
      * caller returns immediately, without waiting for a result from the
      * callee. Applies only if the caller and callee are in different
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 00e2998..1816066 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1298,6 +1298,15 @@
         public static final Uri CONTENT_VCARD_URI = Uri.withAppendedPath(CONTENT_URI,
                 "as_vcard");
 
+       /**
+        * Boolean parameter that may be used with {@link #CONTENT_VCARD_URI}
+        * and {@link #CONTENT_MULTI_VCARD_URI} to indicate that the returned
+        * vcard should not contain a photo.
+        *
+        * @hide
+        */
+        public static final String QUERY_PARAMETER_VCARD_NO_PHOTO = "nophoto";
+
         /**
          * Base {@link Uri} for referencing multiple {@link Contacts} entry,
          * created by appending {@link #LOOKUP_KEY} using
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index 376e0bb..ae41876 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -127,7 +127,7 @@
          * <P>Type: TEXT</P>
          * <P> Note that this is NOT the voicemail media content data.
          */
-        public static final String SOURCE_DATA = "provider_data";
+        public static final String SOURCE_DATA = "source_data";
         /**
          * Whether the media content for this voicemail is available for
          * consumption.
diff --git a/core/java/android/speech/tts/SynthesisRequest.java b/core/java/android/speech/tts/SynthesisRequest.java
index ef1704c..6398d3d 100644
--- a/core/java/android/speech/tts/SynthesisRequest.java
+++ b/core/java/android/speech/tts/SynthesisRequest.java
@@ -42,7 +42,7 @@
     private int mSpeechRate;
     private int mPitch;
 
-    SynthesisRequest(String text, Bundle params) {
+    public SynthesisRequest(String text, Bundle params) {
         mText = text;
         // Makes a copy of params.
         mParams = new Bundle(params);
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 7d596df..40e9355 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -498,8 +498,7 @@
     private int initTts() {
         String defaultEngine = getDefaultEngine();
         String engine = defaultEngine;
-        if (!areDefaultsEnforced() && !TextUtils.isEmpty(mRequestedEngine)
-                && mEnginesHelper.isEngineEnabled(mRequestedEngine)) {
+        if (mEnginesHelper.isEngineInstalled(mRequestedEngine)) {
             engine = mRequestedEngine;
         }
 
@@ -1080,12 +1079,12 @@
     }
 
     /**
-     * Checks whether the user's settings should override settings requested by the calling
-     * application.
+     * Checks whether the user's settings should override settings requested
+     * by the calling application. As of the Ice cream sandwich release,
+     * user settings never forcibly override the app's settings.
      */
     public boolean areDefaultsEnforced() {
-        return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.TTS_USE_DEFAULTS, Engine.USE_DEFAULTS) == 1;
+        return false;
     }
 
     /**
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 3eea6b7..7ea9373 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -191,11 +191,6 @@
     protected abstract void onSynthesizeText(SynthesisRequest request,
             SynthesisCallback callback);
 
-    private boolean areDefaultsEnforced() {
-        return getSecureSettingInt(Settings.Secure.TTS_USE_DEFAULTS,
-                TextToSpeech.Engine.USE_DEFAULTS) == 1;
-    }
-
     private int getDefaultSpeechRate() {
         return getSecureSettingInt(Settings.Secure.TTS_DEFAULT_RATE, Engine.DEFAULT_RATE);
     }
@@ -504,13 +499,9 @@
         }
 
         private void setRequestParams(SynthesisRequest request) {
-            if (areDefaultsEnforced()) {
-                request.setLanguage(getDefaultLanguage(), getDefaultCountry(), getDefaultVariant());
-                request.setSpeechRate(getDefaultSpeechRate());
-            } else {
-                request.setLanguage(getLanguage(), getCountry(), getVariant());
-                request.setSpeechRate(getSpeechRate());
-            }
+            request.setLanguage(getLanguage(), getCountry(), getVariant());
+            request.setSpeechRate(getSpeechRate());
+
             request.setPitch(getPitch());
         }
 
@@ -749,13 +740,6 @@
                 return TextToSpeech.ERROR;
             }
 
-            if (areDefaultsEnforced()) {
-                if (isDefault(lang, country, variant)) {
-                    return mDefaultAvailability;
-                } else {
-                    return TextToSpeech.LANG_NOT_SUPPORTED;
-                }
-            }
             return onIsLanguageAvailable(lang, country, variant);
         }
 
@@ -768,13 +752,6 @@
                 return TextToSpeech.ERROR;
             }
 
-            if (areDefaultsEnforced()) {
-                if (isDefault(lang, country, variant)) {
-                    return mDefaultAvailability;
-                } else {
-                    return TextToSpeech.LANG_NOT_SUPPORTED;
-                }
-            }
             return onLoadLanguage(lang, country, variant);
         }
 
diff --git a/core/java/android/speech/tts/TtsEngines.java b/core/java/android/speech/tts/TtsEngines.java
index 715894f..ed9e048 100644
--- a/core/java/android/speech/tts/TtsEngines.java
+++ b/core/java/android/speech/tts/TtsEngines.java
@@ -117,30 +117,10 @@
         return engines;
     }
 
-    /**
-     * Checks whether a given engine is enabled or not. Note that all system
-     * engines are enabled by default.
-     */
+    // TODO: Used only by the settings app. Remove once
+    // the settings UI change has been finalized.
     public boolean isEngineEnabled(String engine) {
-        // System engines are enabled by default always.
-        EngineInfo info = getEngineInfo(engine);
-        if (info == null) {
-            // The engine is not installed, and therefore cannot
-            // be enabled.
-            return false;
-        }
-
-        if (info.system) {
-            // All system engines are enabled by default.
-            return true;
-        }
-
-        for (String enabled : getUserEnabledEngines()) {
-            if (engine.equals(enabled)) {
-                return true;
-            }
-        }
-        return false;
+        return isEngineInstalled(engine);
     }
 
     private boolean isSystemEngine(ServiceInfo info) {
@@ -149,22 +129,14 @@
     }
 
     /**
-     * @return true if a given engine is installed on the system. Useful to deal
-     *         with cases where an engine has been uninstalled by the user or removed
-     *         for any other reason.
+     * @return true if a given engine is installed on the system.
      */
-    private boolean isEngineInstalled(String engine) {
+    public boolean isEngineInstalled(String engine) {
         if (engine == null) {
             return false;
         }
 
-        for (EngineInfo info : getEngines()) {
-            if (engine.equals(info.name)) {
-                return true;
-            }
-        }
-
-        return false;
+        return getEngineInfo(engine) != null;
     }
 
     private EngineInfo getEngineInfo(ResolveInfo resolve, PackageManager pm) {
@@ -185,17 +157,6 @@
         return null;
     }
 
-    // Note that in addition to this list, all engines that are a part
-    // of the system are enabled by default.
-    private String[] getUserEnabledEngines() {
-        String str = Settings.Secure.getString(mContext.getContentResolver(),
-                Settings.Secure.TTS_ENABLED_PLUGINS);
-        if (TextUtils.isEmpty(str)) {
-            return new String[0];
-        }
-        return str.split(" ");
-    }
-
     private static class EngineInfoComparator implements Comparator<EngineInfo> {
         private EngineInfoComparator() { }
 
diff --git a/core/java/android/util/LocaleUtil.java b/core/java/android/util/LocaleUtil.java
new file mode 100644
index 0000000..e767a85
--- /dev/null
+++ b/core/java/android/util/LocaleUtil.java
@@ -0,0 +1,115 @@
+/*
+ * 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 android.util;
+
+import java.util.Locale;
+
+import libcore.icu.ICU;
+
+/**
+ * Various utilities for Locales
+ *
+ * @hide
+ */
+public class LocaleUtil {
+
+    private LocaleUtil() { /* cannot be instantiated */ }
+
+    /**
+     * @hide Do not use. Implementation not finished.
+     */
+    public static final int TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE = -1;
+
+    /**
+     * @hide Do not use. Implementation not finished.
+     */
+    public static final int TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE = 0;
+
+    /**
+     * @hide Do not use. Implementation not finished.
+     */
+    public static final int TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE = 1;
+
+    private static final char UNDERSCORE_CHAR = '_';
+
+    private static String ARAB_SCRIPT_SUBTAG = "Arab";
+    private static String HEBR_SCRIPT_SUBTAG = "Hebr";
+
+    /**
+     * Return the layout direction for a given Locale
+     *
+     * @param locale the Locale for which we want the layout direction. Can be null.
+     * @return the layout direction. This may be one of:
+     * {@link #TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE} or
+     * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or
+     * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}.
+     *
+     * Be careful: this code will need to be changed when vertical scripts will be supported
+     *
+     * @hide
+     */
+    public static int getLayoutDirectionFromLocale(Locale locale) {
+        if (locale == null || locale.equals(Locale.ROOT)) {
+            return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE;
+        }
+
+        final String localeWithSubtags = ICU.addLikelySubtags(locale.toString());
+        if (localeWithSubtags == null) return getLayoutDirectionFromFirstChar(locale);
+
+        // Need to check if we can extract the script subtag. For example, "Latn" in  "en_Latn_US"
+        if (localeWithSubtags.length() <= 7
+                || localeWithSubtags.charAt(2) != UNDERSCORE_CHAR
+                || localeWithSubtags.charAt(7) != UNDERSCORE_CHAR) {
+            return getLayoutDirectionFromFirstChar(locale);
+        }
+        // Extract the script subtag
+        final String scriptSubtag = localeWithSubtags.substring(3, 7);
+
+        if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) ||
+                scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) {
+            return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE;
+        }
+        return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
+    }
+
+    /**
+     * Fallback algorithm to detect the locale direction. Rely on the fist char of the
+     * localized locale name. This will not work if the localized locale name is in English
+     * (this is the case for ICU 4.4 and "Urdu" script)
+     *
+     * @param locale
+     * @return the layout direction. This may be one of:
+     * {@link #TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE} or
+     * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or
+     * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}.
+     *
+     * Be careful: this code will need to be changed when vertical scripts will be supported
+     *
+     * @hide
+     */
+    private static int getLayoutDirectionFromFirstChar(Locale locale) {
+        switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) {
+            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
+                return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
+            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
+            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
+                return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE;
+            default:
+                return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE;
+        }
+    }
+}
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 383bfb3..5216c49 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -29,6 +29,7 @@
 import android.graphics.RectF;
 import android.graphics.Region;
 import android.graphics.Shader;
+import android.graphics.SurfaceTexture;
 import android.graphics.TemporaryBuffer;
 import android.text.GraphicsOperations;
 import android.text.SpannableString;
@@ -163,7 +164,7 @@
     static native int nCreateTextureLayer(int[] layerInfo);
     static native int nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo);
     static native void nResizeLayer(int layerId, int width, int height, int[] layerInfo);
-    static native void nUpdateTextureLayer(int layerId, int width, int height, int surface);
+    static native void nUpdateTextureLayer(int layerId, int width, int height, SurfaceTexture surface);
     static native void nDestroyLayer(int layerId);
     static native void nDestroyLayerDeferred(int layerId);
     static native boolean nCopyLayer(int layerId, int bitmap);
diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java
index fcf421b..063eee7 100644
--- a/core/java/android/view/GLES20TextureLayer.java
+++ b/core/java/android/view/GLES20TextureLayer.java
@@ -70,7 +70,7 @@
         return mSurface;
     }
 
-    void update(int width, int height, int surface) {
-        GLES20Canvas.nUpdateTextureLayer(mLayer, width, height, surface);
+    void update(int width, int height) {
+        GLES20Canvas.nUpdateTextureLayer(mLayer, width, height, mSurface);
     }
 }
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 5944bd4..5ceb12a 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -194,7 +194,7 @@
      * 
      * @return A {@link SurfaceTexture}
      */
-    abstract SurfaceTexture createSuraceTexture(HardwareLayer layer);
+    abstract SurfaceTexture createSurfaceTexture(HardwareLayer layer);
 
     /**
      * Updates the specified layer.
@@ -202,10 +202,8 @@
      * @param layer The hardware layer to update
      * @param width The layer's width
      * @param height The layer's height
-     * @param surface The surface to update
      */
-    abstract void updateTextureLayer(HardwareLayer layer, int width, int height,
-            SurfaceTexture surface);
+    abstract void updateTextureLayer(HardwareLayer layer, int width, int height);
 
     /**
      * Copies the content of the specified layer into the specified bitmap.
@@ -815,14 +813,13 @@
         }
 
         @Override
-        SurfaceTexture createSuraceTexture(HardwareLayer layer) {
+        SurfaceTexture createSurfaceTexture(HardwareLayer layer) {
             return ((GLES20TextureLayer) layer).getSurfaceTexture();
         }
 
         @Override
-        void updateTextureLayer(HardwareLayer layer, int width, int height,
-                SurfaceTexture surface) {
-            ((GLES20TextureLayer) layer).update(width, height, surface.mSurfaceTexture);
+        void updateTextureLayer(HardwareLayer layer, int width, int height) {
+            ((GLES20TextureLayer) layer).update(width, height);
         }
 
         @Override
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 4daa892..164c657 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -232,7 +232,7 @@
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
         if (mSurface != null) {
-            nSetDefaultBufferSize(mSurface.mSurfaceTexture, getWidth(), getHeight());
+            nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
             if (mListener != null) {
                 mListener.onSurfaceTextureSizeChanged(mSurface, getWidth(), getHeight());
             }
@@ -247,8 +247,8 @@
 
         if (mLayer == null) {
             mLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer();
-            mSurface = mAttachInfo.mHardwareRenderer.createSuraceTexture(mLayer);
-            nSetDefaultBufferSize(mSurface.mSurfaceTexture, getWidth(), getHeight());
+            mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
+            nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
 
             mUpdateListener = new SurfaceTexture.OnFrameAvailableListener() {
                 @Override
@@ -290,7 +290,7 @@
             return;
         }
 
-        mAttachInfo.mHardwareRenderer.updateTextureLayer(mLayer, getWidth(), getHeight(), mSurface);
+        mAttachInfo.mHardwareRenderer.updateTextureLayer(mLayer, getWidth(), getHeight());
 
         invalidate();
     }
@@ -447,5 +447,5 @@
         public void onSurfaceTextureDestroyed(SurfaceTexture surface);
     }
 
-    private static native void nSetDefaultBufferSize(int surfaceTexture, int width, int height);
+    private static native void nSetDefaultBufferSize(SurfaceTexture surfaceTexture, int width, int height);
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1dfb858..b0e651a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import android.util.FloatProperty;
+import android.util.LocaleUtil;
 import android.util.Property;
 import com.android.internal.R;
 import com.android.internal.util.Predicate;
@@ -8772,18 +8773,8 @@
      * @return true if a Locale is corresponding to a RTL script.
      */
     private static boolean isLayoutDirectionRtl(Locale locale) {
-        if (locale == null || locale.equals(Locale.ROOT)) return false;
-        // Be careful: this code will need to be changed when vertical scripts will be supported
-        // OR if ICU4C is updated to have the "likelySubtags" file
-        switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) {
-            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
-                return false;
-            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
-            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
-                return true;
-            default:
-                return false;
-        }
+        return (LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE ==
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
     }
 
     /**
diff --git a/core/java/android/view/ViewAncestor.java b/core/java/android/view/ViewAncestor.java
index 914973e..ba3ae58 100644
--- a/core/java/android/view/ViewAncestor.java
+++ b/core/java/android/view/ViewAncestor.java
@@ -4407,7 +4407,7 @@
                 predicate.init(accessibilityId);
                 View root = ViewAncestor.this.mView;
                 View target = root.findViewByPredicate(predicate);
-                if (target != null) {
+                if (target != null && target.isShown()) {
                     info = target.createAccessibilityNodeInfo();
                 }
             } finally {
@@ -4439,7 +4439,7 @@
             try {
                 View root = ViewAncestor.this.mView;
                 View target = root.findViewById(viewId);
-                if (target != null) {
+                if (target != null && target.isShown()) {
                     info = target.createAccessibilityNodeInfo();
                 }
             } finally {
@@ -4486,7 +4486,7 @@
                     root = ViewAncestor.this.mView;
                 }
 
-                if (root == null) {
+                if (root == null || !root.isShown()) {
                     return;
                 }
 
@@ -4501,7 +4501,9 @@
                 final int viewCount = foundViews.size();
                 for (int i = 0; i < viewCount; i++) {
                     View foundView = foundViews.get(i);
-                    infos.add(foundView.createAccessibilityNodeInfo());
+                    if (foundView.isShown()) {
+                        infos.add(foundView.createAccessibilityNodeInfo());
+                    }
                  }
             } finally {
                 try {
@@ -4611,7 +4613,8 @@
                 return null;
             }
             mFindByAccessibilityIdPredicate.init(accessibilityId);
-            return root.findViewByPredicate(mFindByAccessibilityIdPredicate);
+            View foundView = root.findViewByPredicate(mFindByAccessibilityIdPredicate);
+            return (foundView != null && foundView.isShown()) ? foundView : null;
         }
 
         private final class FindByAccessibilitytIdPredicate implements Predicate<View> {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 57ee8a0..a6bce75 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2023,10 +2023,11 @@
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
-
         for (int i = 0, count = mChildrenCount; i < count; i++) {
             View child = mChildren[i];
-            info.addChild(child);
+            if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
+                info.addChild(child);
+            }
         }
     }
 
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index a730018..2410eb2 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -28,6 +28,7 @@
 import android.view.Gravity;
 import android.view.ViewDebug;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
 
 /**
  * <p>
@@ -214,6 +215,12 @@
     }
 
     @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setChecked(mChecked);
+    }
+
+    @Override
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
 
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 092c2f7..544bc6b 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -844,8 +844,8 @@
             int pWidth = getMeasurement(view, true, PRF);
             int pHeight = getMeasurement(view, false, PRF);
 
-            Alignment hAlignment = columnGroup.alignment;
-            Alignment vAlignment = rowGroup.alignment;
+            Alignment hAlign = columnGroup.alignment;
+            Alignment vAlign = rowGroup.alignment;
 
             int dx, dy;
 
@@ -853,8 +853,9 @@
             Bounds rowBounds = mVerticalAxis.getGroupBounds().getValue(i);
 
             // Gravity offsets: the location of the alignment group relative to its cell group.
-            int c2ax = protect(hAlignment.getAlignmentValue(null, cellWidth - colBounds.size()));
-            int c2ay = protect(vAlignment.getAlignmentValue(null, cellHeight - rowBounds.size()));
+            int type = PRF;
+            int c2ax = protect(hAlign.getAlignmentValue(null, cellWidth - colBounds.size(), type));
+            int c2ay = protect(vAlign.getAlignmentValue(null, cellHeight - rowBounds.size(), type));
 
             if (mMarginsIncludedInAlignment) {
                 int leftMargin = getMargin(view, true, true);
@@ -863,12 +864,12 @@
                 int bottomMargin = getMargin(view, false, false);
 
                 // Same calculation as getMeasurementIncludingMargin()
-                int measuredWidth = leftMargin + pWidth + rightMargin;
-                int measuredHeight = topMargin + pHeight + bottomMargin;
+                int mWidth = leftMargin + pWidth + rightMargin;
+                int mHeight = topMargin + pHeight + bottomMargin;
 
                 // Alignment offsets: the location of the view relative to its alignment group.
-                int a2vx = colBounds.before - hAlignment.getAlignmentValue(view, measuredWidth);
-                int a2vy = rowBounds.before - vAlignment.getAlignmentValue(view, measuredHeight);
+                int a2vx = colBounds.before - hAlign.getAlignmentValue(view, mWidth, type);
+                int a2vy = rowBounds.before - vAlign.getAlignmentValue(view, mHeight, type);
 
                 dx = c2ax + a2vx + leftMargin;
                 dy = c2ay + a2vy + topMargin;
@@ -877,15 +878,15 @@
                 cellHeight -= topMargin + bottomMargin;
             } else {
                 // Alignment offsets: the location of the view relative to its alignment group.
-                int a2vx = colBounds.before - hAlignment.getAlignmentValue(view, pWidth);
-                int a2vy = rowBounds.before - vAlignment.getAlignmentValue(view, pHeight);
+                int a2vx = colBounds.before - hAlign.getAlignmentValue(view, pWidth, type);
+                int a2vy = rowBounds.before - vAlign.getAlignmentValue(view, pHeight, type);
 
                 dx = c2ax + a2vx;
                 dy = c2ay + a2vy;
             }
 
-            int width = hAlignment.getSizeInCell(view, pWidth, cellWidth);
-            int height = vAlignment.getSizeInCell(view, pHeight, cellHeight);
+            int width = hAlign.getSizeInCell(view, pWidth, cellWidth, type);
+            int height = vAlign.getSizeInCell(view, pHeight, cellHeight, type);
 
             int cx = paddingLeft + x1 + dx;
             int cy = paddingTop + y1 + dy;
@@ -1003,7 +1004,7 @@
 
                 int size = getMeasurementIncludingMargin(c, horizontal, PRF);
                 // todo test this works correctly when the returned value is UNDEFINED
-                int before = g.alignment.getAlignmentValue(c, size);
+                int before = g.alignment.getAlignmentValue(c, size, PRF);
                 bounds.include(before, size - before);
             }
         }
@@ -1459,6 +1460,7 @@
             spanSizes = null;
             leadingMargins = null;
             trailingMargins = null;
+            arcs = null;
             minima = null;
             weights = null;
             locations = null;
@@ -2156,57 +2158,59 @@
      * {@link Group#alignment alignment}. Overall placement of the view in the cell
      * group is specified by the two alignments which act along each axis independently.
      * <p>
-     * An Alignment implementation must define the {@link #getAlignmentValue(View, int)}
+     * An Alignment implementation must define {@link #getAlignmentValue(View, int, int)},
      * to return the appropriate value for the type of alignment being defined.
      * The enclosing algorithms position the children
-     * so that the values returned from the alignment
+     * so that the locations defined by the alignmnet values
      * are the same for all of the views in a group.
      * <p>
      *  The GridLayout class defines the most common alignments used in general layout:
      * {@link #TOP}, {@link #LEFT}, {@link #BOTTOM}, {@link #RIGHT}, {@link #CENTER}, {@link
      * #BASELINE} and {@link #FILL}.
      */
-    public static interface Alignment {
+    public static abstract class Alignment {
         /**
          * Returns an alignment value. In the case of vertical alignments the value
          * returned should indicate the distance from the top of the view to the
          * alignment location.
          * For horizontal alignments measurement is made from the left edge of the component.
          *
-         * @param view     the view to which this alignment should be applied
-         * @param viewSize the measured size of the view
-         * @return         the alignment value
+         * @param view              the view to which this alignment should be applied
+         * @param viewSize          the measured size of the view
+         * @param measurementType   the type of measurement that should be made
+         *
+         * @return                  the alignment value
          */
-        public int getAlignmentValue(View view, int viewSize);
+        public abstract int getAlignmentValue(View view, int viewSize, int measurementType);
 
         /**
          * Returns the size of the view specified by this alignment.
          * In the case of vertical alignments this method should return a height; for
          * horizontal alignments this method should return the width.
+         * <p>
+         * The default implementation returns {@code viewSize}.
          *
-         * @param view     the view to which this alignment should be applied
-         * @param viewSize the measured size of the view
-         * @param cellSize the size of the cell into which this view will be placed
-         * @return         the aligned size
+         * @param view              the view to which this alignment should be applied
+         * @param viewSize          the measured size of the view
+         * @param cellSize          the size of the cell into which this view will be placed
+         * @param measurementType   the type of measurement that should be made
+         *
+         * @return                  the aligned size
          */
-        public int getSizeInCell(View view, int viewSize, int cellSize);
-    }
-
-    private static abstract class AbstractAlignment implements Alignment {
-        public int getSizeInCell(View view, int viewSize, int cellSize) {
+        public int getSizeInCell(View view, int viewSize, int cellSize, int measurementType) {
             return viewSize;
         }
     }
 
-    private static final Alignment LEADING = new AbstractAlignment() {
-        public int getAlignmentValue(View view, int viewSize) {
+    private static final Alignment LEADING = new Alignment() {
+        public int getAlignmentValue(View view, int viewSize, int measurementType) {
             return 0;
         }
 
     };
 
-    private static final Alignment TRAILING = new AbstractAlignment() {
-        public int getAlignmentValue(View view, int viewSize) {
+    private static final Alignment TRAILING = new Alignment() {
+        public int getAlignmentValue(View view, int viewSize, int measurementType) {
             return viewSize;
         }
     };
@@ -2240,8 +2244,8 @@
      * This constant may be used in both {@link LayoutParams#rowGroup rowGroups} and {@link
      * LayoutParams#columnGroup columnGroups}.
      */
-    public static final Alignment CENTER = new AbstractAlignment() {
-        public int getAlignmentValue(View view, int viewSize) {
+    public static final Alignment CENTER = new Alignment() {
+        public int getAlignmentValue(View view, int viewSize, int measurementType) {
             return viewSize >> 1;
         }
     };
@@ -2253,8 +2257,8 @@
      *
      * @see View#getBaseline()
      */
-    public static final Alignment BASELINE = new AbstractAlignment() {
-        public int getAlignmentValue(View view, int height) {
+    public static final Alignment BASELINE = new Alignment() {
+        public int getAlignmentValue(View view, int viewSize, int measurementType) {
             if (view == null) {
                 return UNDEFINED;
             }
@@ -2274,11 +2278,12 @@
      * {@link LayoutParams#columnGroup columnGroups}.
      */
     public static final Alignment FILL = new Alignment() {
-        public int getAlignmentValue(View view, int viewSize) {
+        public int getAlignmentValue(View view, int viewSize, int measurementType) {
             return UNDEFINED;
         }
 
-        public int getSizeInCell(View view, int viewSize, int cellSize) {
+        @Override
+        public int getSizeInCell(View view, int viewSize, int cellSize, int measurementType) {
             return cellSize;
         }
     };
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 470a23d6..02c2b8f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8574,11 +8574,7 @@
                     final String originalText = mText.subSequence(spanStart, spanEnd).toString();
                     ((Editable) mText).replace(spanStart, spanEnd, suggestion);
 
-                    // Swap text content between actual text and Suggestion span
-                    String[] suggestions = suggestionInfo.suggestionSpan.getSuggestions();
-                    suggestions[suggestionInfo.suggestionIndex] = originalText;
-
-                    // Notify source IME of the suggestion pick
+                    // Notify source IME of the suggestion pick. Do this before swaping texts.
                     if (!TextUtils.isEmpty(
                             suggestionInfo.suggestionSpan.getNotificationTargetClassName())) {
                         InputMethodManager imm = InputMethodManager.peekInstance();
@@ -8586,6 +8582,10 @@
                                 suggestionInfo.suggestionIndex);
                     }
 
+                    // Swap text content between actual text and Suggestion span
+                    String[] suggestions = suggestionInfo.suggestionSpan.getSuggestions();
+                    suggestions[suggestionInfo.suggestionIndex] = originalText;
+
                     // Restore previous SuggestionSpans
                     final int lengthDifference = suggestion.length() - (spanEnd - spanStart);
                     for (int i = 0; i < length; i++) {
diff --git a/core/java/com/android/internal/net/VpnConfig.aidl b/core/java/com/android/internal/net/VpnConfig.aidl
new file mode 100644
index 0000000..be1684c
--- /dev/null
+++ b/core/java/com/android/internal/net/VpnConfig.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.internal.net;
+
+parcelable VpnConfig;
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
new file mode 100644
index 0000000..18d9ec4
--- /dev/null
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -0,0 +1,80 @@
+/*
+ * 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.internal.net;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A simple container used to carry information in VpnBuilder, VpnDialogs,
+ * and com.android.server.connectivity.Vpn. Internal use only.
+ *
+ * @hide
+ */
+public class VpnConfig implements Parcelable {
+
+    public String packageName;
+    public String sessionName;
+    public String interfaceName;
+    public String configureActivity;
+    public int mtu = -1;
+    public String addresses;
+    public String routes;
+    public String dnsServers;
+    public long startTime = -1;
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(packageName);
+        out.writeString(sessionName);
+        out.writeString(interfaceName);
+        out.writeString(configureActivity);
+        out.writeInt(mtu);
+        out.writeString(addresses);
+        out.writeString(routes);
+        out.writeString(dnsServers);
+        out.writeLong(startTime);
+    }
+
+    public static final Parcelable.Creator<VpnConfig> CREATOR =
+            new Parcelable.Creator<VpnConfig>() {
+        @Override
+        public VpnConfig createFromParcel(Parcel in) {
+            VpnConfig config = new VpnConfig();
+            config.packageName = in.readString();
+            config.sessionName = in.readString();
+            config.interfaceName = in.readString();
+            config.configureActivity = in.readString();
+            config.mtu = in.readInt();
+            config.addresses = in.readString();
+            config.routes = in.readString();
+            config.dnsServers = in.readString();
+            config.startTime = in.readLong();
+            return config;
+        }
+
+        @Override
+        public VpnConfig[] newArray(int size) {
+            return new VpnConfig[size];
+        }
+    };
+}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 2ff0413..c11fc10 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -35,5 +35,6 @@
     void setImeWindowStatus(in IBinder token, int vis, int backDisposition);
     void setHardKeyboardStatus(boolean available, boolean enabled);
     void userActivity();
+    void toggleRecentApps();
 }
 
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 3f2b1ef..a9e5057 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -47,4 +47,5 @@
     void setSystemUiVisibility(int vis);
     void setHardKeyboardEnabled(boolean enabled);
     void userActivity();
+    void toggleRecentApps();
 }
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 7e82efb..e301e44 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -22,6 +22,7 @@
 #include "GraphicsJNI.h"
 #include <nativehelper/JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/android_graphics_SurfaceTexture.h>
 #include <utils/ResourceTypes.h>
 
 #include <gui/SurfaceTexture.h>
@@ -644,11 +645,13 @@
 }
 
 static void android_view_GLES20Canvas_updateTextureLayer(JNIEnv* env, jobject clazz,
-        Layer* layer, jint width, jint height, SurfaceTexture* surface) {
+        Layer* layer, jint width, jint height, jobject surface) {
     float transform[16];
-    surface->updateTexImage();
-    surface->getTransformMatrix(transform);
-    GLenum renderTarget = surface->getCurrentTextureTarget();
+    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface));
+
+    surfaceTexture->updateTexImage();
+    surfaceTexture->getTransformMatrix(transform);
+    GLenum renderTarget = surfaceTexture->getCurrentTextureTarget();
 
     LayerRenderer::updateTextureLayer(layer, width, height, renderTarget, transform);
 }
@@ -793,7 +796,8 @@
     { "nCreateLayer",            "(IIZ[I)I",   (void*) android_view_GLES20Canvas_createLayer },
     { "nResizeLayer",            "(III[I)V" ,  (void*) android_view_GLES20Canvas_resizeLayer },
     { "nCreateTextureLayer",     "([I)I",      (void*) android_view_GLES20Canvas_createTextureLayer },
-    { "nUpdateTextureLayer",     "(IIII)V",    (void*) android_view_GLES20Canvas_updateTextureLayer },
+    { "nUpdateTextureLayer",     "(IIILandroid/graphics/SurfaceTexture;)V",
+                                               (void*) android_view_GLES20Canvas_updateTextureLayer },
     { "nDestroyLayer",           "(I)V",       (void*) android_view_GLES20Canvas_destroyLayer },
     { "nDestroyLayerDeferred",   "(I)V",       (void*) android_view_GLES20Canvas_destroyLayerDeferred },
     { "nDrawLayer",              "(IIFFI)V",   (void*) android_view_GLES20Canvas_drawLayer },
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index c5d86c8..b046b23 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -17,6 +17,7 @@
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/android_graphics_SurfaceTexture.h>
 
 #include <gui/SurfaceTexture.h>
 
@@ -27,10 +28,10 @@
 // ----------------------------------------------------------------------------
 
 static void android_view_TextureView_setDefaultBufferSize(JNIEnv* env, jobject,
-    jint surfaceTexture, jint width, jint height) {
+    jobject surface, jint width, jint height) {
 
-    sp<SurfaceTexture> surface = reinterpret_cast<SurfaceTexture*>(surfaceTexture);
-    surface->setDefaultBufferSize(width, height);
+    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface));
+    surfaceTexture->setDefaultBufferSize(width, height);
 }
 
 // ----------------------------------------------------------------------------
@@ -40,7 +41,8 @@
 const char* const kClassPathName = "android/view/TextureView";
 
 static JNINativeMethod gMethods[] = {
-    {   "nSetDefaultBufferSize", "(III)V", (void*) android_view_TextureView_setDefaultBufferSize }
+    {   "nSetDefaultBufferSize", "(Landroid/graphics/SurfaceTexture;II)V",
+            (void*) android_view_TextureView_setDefaultBufferSize }
 };
 
 int register_android_view_TextureView(JNIEnv* env) {
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index f777527..02974f9a 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -18,6 +18,7 @@
 #include "JNIHelp.h"
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_view_Surface.h>
+#include <android_runtime/android_graphics_SurfaceTexture.h>
 #include <utils/misc.h>
 
 #include <EGL/egl.h>
@@ -323,7 +324,7 @@
 }
 
 static jint jni_eglCreateWindowSurfaceTexture(JNIEnv *_env, jobject _this, jobject display,
-        jobject config, jint native_window, jintArray attrib_list) {
+        jobject config, jobject native_window, jintArray attrib_list) {
     if (display == NULL || config == NULL
         || !validAttribList(_env, attrib_list)) {
         jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
@@ -339,7 +340,7 @@
         return 0;
     }
     
-    sp<SurfaceTexture> surfaceTexture = reinterpret_cast<SurfaceTexture*>(native_window);
+    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(_env, native_window));
 
     window = new SurfaceTextureClient(surfaceTexture);
     if (window == NULL)
@@ -540,7 +541,7 @@
 {"_eglCreatePbufferSurface","(" DISPLAY CONFIG "[I)I", (void*)jni_eglCreatePbufferSurface },
 {"_eglCreatePixmapSurface", "(" SURFACE DISPLAY CONFIG OBJECT "[I)V", (void*)jni_eglCreatePixmapSurface },
 {"_eglCreateWindowSurface", "(" DISPLAY CONFIG OBJECT "[I)I", (void*)jni_eglCreateWindowSurface },
-{"_eglCreateWindowSurfaceTexture", "(" DISPLAY CONFIG "I[I)I", (void*)jni_eglCreateWindowSurfaceTexture },
+{"_eglCreateWindowSurfaceTexture", "(" DISPLAY CONFIG OBJECT "[I)I", (void*)jni_eglCreateWindowSurfaceTexture },
 {"eglDestroyContext",      "(" DISPLAY CONTEXT ")Z", (void*)jni_eglDestroyContext },
 {"eglDestroySurface",      "(" DISPLAY SURFACE ")Z", (void*)jni_eglDestroySurface },
 {"eglMakeCurrent",         "(" DISPLAY SURFACE SURFACE CONTEXT")Z", (void*)jni_eglMakeCurrent },
diff --git a/core/res/res/values-de/donottranslate-cldr.xml b/core/res/res/values-de/donottranslate-cldr.xml
index fffcf26..6b4bf5c 100644
--- a/core/res/res/values-de/donottranslate-cldr.xml
+++ b/core/res/res/values-de/donottranslate-cldr.xml
@@ -31,7 +31,7 @@
     <string name="month_medium_february">Feb.</string>
     <string name="month_medium_march">Mär.</string>
     <string name="month_medium_april">Apr.</string>
-    <string name="month_medium_may">Mai.</string>
+    <string name="month_medium_may">Mai</string>
     <string name="month_medium_june">Jun.</string>
     <string name="month_medium_july">Jul.</string>
     <string name="month_medium_august">Aug.</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 5d357c5..9c25ace 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1133,9 +1133,9 @@
              edge, a right gravity will clip the left edge, and neither will clip both edges. -->
         <flag name="clip_horizontal" value="0x08" />
         <!-- Push object to the beginning of its container, not changing its size. -->
-        <flag name="before" value="0x00800003" />
+        <flag name="start" value="0x00800003" />
         <!-- Push object to the end of its container, not changing its size. -->
-        <flag name="after" value="0x00800005" />
+        <flag name="end" value="0x00800005" />
     </attr>
 
     <!-- Controls whether links such as urls and email addresses are
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3b4798e..e6dfc03 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -389,9 +389,11 @@
     <!-- Control the behavior when the user long presses the power button.
             0 - Nothing
             1 - Recent apps dialog
-            2 - Recent apps activity in SystemUI
+            2 - Recent apps view in SystemUI
+         This needs to match the constants in
+         policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
     -->
-    <integer name="config_longPressOnHomeBehavior">1</integer>
+    <integer name="config_longPressOnHomeBehavior">2</integer>
 
     <!-- Array of light sensor LUX values to define our levels for auto backlight brightness support.
          The N entries of this array define N + 1 zones as follows:
@@ -633,4 +635,11 @@
 
     <!-- Set to true if the RSSI should always display CDMA signal strength even on EVDO -->
     <bool name="config_alwaysUseCdmaRssi">false</bool>
+
+    <!-- If this value is true, duplicate Source/Destination port fields
+         in WDP header of some carriers OMADM wap push are supported.
+         ex: MSGTYPE-TotalSegments-CurrentSegment
+             -SourcePortDestPort-SourcePortDestPort-OMADM PDU
+         If false, not supported. -->
+    <bool name="config_duplicate_port_omadm_wappush">false</bool>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5e13282..d7b7dd0 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -901,16 +901,16 @@
         contact (address) data stored on your phone. Malicious
         applications can use this to erase or modify your contact data.</string>
 
-    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <!-- Title of the read profile permission, listed so the user can decide whether to allow the application to read the user's personal profile data. [CHAR LIMIT=30] -->
     <string name="permlab_readProfile">read profile data</string>
-    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <!-- Description of the read profile permission, listed so the user can decide whether to allow the application to read the user's personal profile data. [CHAR LIMIT=NONE] -->
     <string name="permdesc_readProfile" product="default">Allows an application to read all
         of your personal profile information. Malicious applications can use this to identify
         you and send your personal information to other people.</string>
 
-    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <!-- Title of the write profile permission, listed so the user can decide whether to allow the application to write to the user's personal profile data. [CHAR LIMIT=30] -->
     <string name="permlab_writeProfile">write profile data</string>
-    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <!-- Description of the write profile permission, listed so the user can decide whether to allow the application to write to the user's personal profile data. [CHAR LIMIT=NONE] -->
     <string name="permdesc_writeProfile" product="default">Allows an application to modify
         your personal profile information. Malicious applications can use this to erase or
         modify your profile data.</string>
@@ -1790,6 +1790,9 @@
     <string name="lockscreen_missing_sim_instructions">Please insert a SIM card.</string>
     <!-- Shown in the lock screen to ask the user to insert a SIM card when sim is missing or not readable. -->
     <string name="lockscreen_missing_sim_instructions_long">The SIM card is missing or not readable. Please insert a SIM card.</string>
+    <!-- Shown in the lock screen to inform the user to SIM card is permanently disabled. -->
+    <string name="lockscreen_permanent_disabled_sim_instructions">Your SIM card is permanently disabled.\n
+    Please contact your wireless service provider to obtain another SIM card.</string>
 
     <!-- Shown in the lock screen when there is emergency calls only mode. -->
     <string name="emergency_calls_only" msgid="2485604591272668370">Emergency calls only</string>
@@ -2774,11 +2777,13 @@
     <string name="l2tp_ipsec_crt_vpn_description">Certificate based L2TP/IPSec VPN</string>
 
     <!-- Ticker text to show when VPN is active. -->
-    <string name="vpn_ticker">Activating <xliff:g id="app">%s</xliff:g> VPN...</string>
+    <string name="vpn_ticker"><xliff:g id="app" example="FooVPN client">%s</xliff:g> is activating VPN...</string>
     <!-- The title of the notification when VPN is active. -->
-    <string name="vpn_title"><xliff:g id="app">%s</xliff:g> VPN is active</string>
+    <string name="vpn_title">VPN is activated by <xliff:g id="app" example="FooVPN client">%s</xliff:g></string>
     <!-- The text of the notification when VPN is active. -->
-    <string name="vpn_text">VPN is connected to <xliff:g id="profile">%s</xliff:g>. Tap to manage the network.</string>
+    <string name="vpn_text">Tap to manage the network.</string>
+    <!-- The text of the notification when VPN is active with a session name. -->
+    <string name="vpn_text_long">Connected to <xliff:g id="session" example="office">%s</xliff:g>. Tap to manage the network.</string>
 
     <!-- Localized strings for WebView -->
     <!-- Label for button in a WebView that will open a chooser to choose a file to upload -->
diff --git a/core/tests/coretests/src/android/content/res/ConfigurationTest.java b/core/tests/coretests/src/android/content/res/ConfigurationTest.java
deleted file mode 100644
index 54a5e4e..0000000
--- a/core/tests/coretests/src/android/content/res/ConfigurationTest.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * 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 android.content.res;
-
-import java.util.Locale;
-
-import android.test.AndroidTestCase;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
-public class ConfigurationTest extends AndroidTestCase {
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "getLayoutDirectionFromLocale",
-        args = {Locale.class}
-    )
-    public void testGetLayoutDirectionFromLocale() {
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(null));
-
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.ENGLISH));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.CANADA));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.FRANCE));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.FRENCH));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.GERMAN));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.GERMANY));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.ITALIAN));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.ITALY));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.UK));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.US));
-
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.ROOT));
-
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.CHINA));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.CHINESE));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.JAPAN));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.JAPANESE));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.KOREA));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.KOREAN));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.PRC));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.TAIWAN));
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE));
-
-        Locale locale = new Locale("ar");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "AE");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "BH");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "DZ");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "EG");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "IQ");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "JO");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "KW");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "LB");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "LY");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "MA");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "OM");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "QA");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "SA");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "SD");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "SY");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "TN");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ar", "YE");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-
-        locale = new Locale("fa");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("fa", "AF");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("fa", "IR");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-
-        locale = new Locale("iw");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("iw", "IL");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("he");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("he", "IL");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-
-        // The following test will not pass until we are able to take care about the scrip subtag
-        // thru having the "likelySubTags" file into ICU4C
-//        locale = new Locale("pa_Arab");
-//        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-//            Configuration.getLayoutDirectionFromLocale(locale));
-//        locale = new Locale("pa_Arab", "PK");
-//        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-//            Configuration.getLayoutDirectionFromLocale(locale));
-
-        locale = new Locale("ps");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-        locale = new Locale("ps", "AF");
-        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-            Configuration.getLayoutDirectionFromLocale(locale));
-
-        // The following test will not work as the localized display name would be "Urdu" with ICU 4.4
-        // We will need ICU 4.6 to get the correct localized display name
-//        locale = new Locale("ur");
-//        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-//            Configuration.getLayoutDirectionFromLocale(locale));
-//        locale = new Locale("ur", "IN");
-//        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-//            Configuration.getLayoutDirectionFromLocale(locale));
-//        locale = new Locale("ur", "PK");
-//        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-//            Configuration.getLayoutDirectionFromLocale(locale));
-
-        // The following test will not pass until we are able to take care about the scrip subtag
-        // thru having the "likelySubTags" file into ICU4C
-//        locale = new Locale("uz_Arab");
-//        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-//            Configuration.getLayoutDirectionFromLocale(locale));
-//        locale = new Locale("uz_Arab", "AF");
-//        assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
-//            Configuration.getLayoutDirectionFromLocale(locale));
-    }
-}
diff --git a/core/tests/coretests/src/android/util/LocaleUtilTest.java b/core/tests/coretests/src/android/util/LocaleUtilTest.java
new file mode 100644
index 0000000..5aa99c1
--- /dev/null
+++ b/core/tests/coretests/src/android/util/LocaleUtilTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2007 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 android.util;
+
+import java.util.Locale;
+
+import android.content.res.Configuration;
+import android.test.AndroidTestCase;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE;
+import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
+import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE;
+
+public class LocaleUtilTest extends AndroidTestCase {
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "getLayoutDirectionFromLocale",
+        args = {Locale.class}
+    )
+    public void testGetLayoutDirectionFromLocale() {
+        assertEquals(TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE,
+                LocaleUtil.getLayoutDirectionFromLocale(null));
+
+        assertEquals(TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.ENGLISH));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.FRANCE));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.FRENCH));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMAN));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMANY));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALIAN));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALY));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.UK));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.US));
+
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.ROOT));
+
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINA));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINESE));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPAN));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPANESE));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREA));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREAN));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.PRC));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.TAIWAN));
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE));
+
+        Locale locale = new Locale("ar");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "AE");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "BH");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "DZ");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "EG");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "IQ");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "JO");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "KW");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "LB");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "LY");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "MA");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "OM");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "QA");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "SA");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "SD");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "SY");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "TN");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "YE");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("fa");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("fa", "AF");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("fa", "IR");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("iw");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("iw", "IL");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("he");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("he", "IL");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("pa_Arab");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("pa_Arab", "PK");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("ps");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ps", "AF");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("ur");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ur", "IN");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ur", "PK");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("uz_Arab");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("uz_Arab", "AF");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        // Locale without a real language
+        locale = new Locale("zz");
+        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+            LocaleUtil.getLayoutDirectionFromLocale(locale));
+    }
+}
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index c37b4f8..458f1b6 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -37,7 +37,7 @@
 
 using namespace android;
 
-static void writeDecrptHandleToParcelData(
+static void writeDecryptHandleToParcelData(
         const DecryptHandle* handle, Parcel* data) {
     data->writeInt32(handle->decryptId);
     data->writeString8(handle->mimeType);
@@ -46,14 +46,14 @@
 
     int size = handle->copyControlVector.size();
     data->writeInt32(size);
-    for(int i = 0; i < size; i++) {
+    for (int i = 0; i < size; i++) {
         data->writeInt32(handle->copyControlVector.keyAt(i));
         data->writeInt32(handle->copyControlVector.valueAt(i));
     }
 
     size = handle->extendedData.size();
     data->writeInt32(size);
-    for(int i = 0; i < size; i++) {
+    for (int i = 0; i < size; i++) {
         data->writeString8(handle->extendedData.keyAt(i));
         data->writeString8(handle->extendedData.valueAt(i));
     }
@@ -77,14 +77,14 @@
     handle->status = data.readInt32();
 
     int size = data.readInt32();
-    for (int i = 0; i < size; i ++) {
+    for (int i = 0; i < size; i++) {
         DrmCopyControl key = (DrmCopyControl)data.readInt32();
         int value = data.readInt32();
         handle->copyControlVector.add(key, value);
     }
 
     size = data.readInt32();
-    for (int i = 0; i < size; i ++) {
+    for (int i = 0; i < size; i++) {
         String8 key = data.readString8();
         String8 value = data.readString8();
         handle->extendedData.add(key, value);
@@ -416,7 +416,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    writeDecrptHandleToParcelData(decryptHandle, &data);
+    writeDecryptHandleToParcelData(decryptHandle, &data);
 
     data.writeInt32(action);
     data.writeInt32(static_cast< int>(reserve));
@@ -433,7 +433,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    writeDecrptHandleToParcelData(decryptHandle, &data);
+    writeDecryptHandleToParcelData(decryptHandle, &data);
 
     data.writeInt32(playbackStatus);
     data.writeInt64(position);
@@ -646,7 +646,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    writeDecrptHandleToParcelData(decryptHandle, &data);
+    writeDecryptHandleToParcelData(decryptHandle, &data);
 
     remote()->transact(CLOSE_DECRYPT_SESSION, data, &reply);
 
@@ -662,7 +662,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    writeDecrptHandleToParcelData(decryptHandle, &data);
+    writeDecryptHandleToParcelData(decryptHandle, &data);
 
     data.writeInt32(decryptUnitId);
 
@@ -682,7 +682,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    writeDecrptHandleToParcelData(decryptHandle, &data);
+    writeDecryptHandleToParcelData(decryptHandle, &data);
 
     data.writeInt32(decryptUnitId);
     data.writeInt32((*decBuffer)->length);
@@ -715,7 +715,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    writeDecrptHandleToParcelData(decryptHandle, &data);
+    writeDecryptHandleToParcelData(decryptHandle, &data);
 
     data.writeInt32(decryptUnitId);
 
@@ -733,7 +733,7 @@
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
 
-    writeDecrptHandleToParcelData(decryptHandle, &data);
+    writeDecryptHandleToParcelData(decryptHandle, &data);
 
     data.writeInt32(numBytes);
     data.writeInt64(offset);
@@ -1244,7 +1244,7 @@
             = openDecryptSession(uniqueId, fd, data.readInt64(), data.readInt64());
 
         if (NULL != handle) {
-            writeDecrptHandleToParcelData(handle, reply);
+            writeDecryptHandleToParcelData(handle, reply);
             clearDecryptHandle(handle);
             delete handle; handle = NULL;
         }
@@ -1262,7 +1262,7 @@
         DecryptHandle* handle = openDecryptSession(uniqueId, uri.string());
 
         if (NULL != handle) {
-            writeDecrptHandleToParcelData(handle, reply);
+            writeDecryptHandleToParcelData(handle, reply);
 
             clearDecryptHandle(handle);
             delete handle; handle = NULL;
diff --git a/drm/java/android/drm/DrmInfoRequest.java b/drm/java/android/drm/DrmInfoRequest.java
index 2222ae8..1429fa5 100755
--- a/drm/java/android/drm/DrmInfoRequest.java
+++ b/drm/java/android/drm/DrmInfoRequest.java
@@ -32,16 +32,16 @@
      */
     public static final int TYPE_REGISTRATION_INFO = 1;
     /**
-    * Acquires information for unregistering the DRM server.
-    */
+     * Acquires information for unregistering the DRM server.
+     */
     public static final int TYPE_UNREGISTRATION_INFO = 2;
     /**
-    * Acquires rights information.
-    */
+     * Acquires rights information.
+     */
     public static final int TYPE_RIGHTS_ACQUISITION_INFO = 3;
     /**
-    * Acquires the progress of the rights acquisition.
-    */
+     * Acquires the progress of the rights acquisition.
+     */
     public static final int TYPE_RIGHTS_ACQUISITION_PROGRESS_INFO = 4;
 
     /**
diff --git a/drm/java/android/drm/DrmInfoStatus.java b/drm/java/android/drm/DrmInfoStatus.java
index b04694b..5c12ae3 100755
--- a/drm/java/android/drm/DrmInfoStatus.java
+++ b/drm/java/android/drm/DrmInfoStatus.java
@@ -31,20 +31,20 @@
     public static final int STATUS_ERROR = 2;
 
     /**
-    * The status of the communication.
-    */
+     * The status of the communication.
+     */
     public final int statusCode;
     /**
-    * The type of DRM information processed.
-    */
+     * The type of DRM information processed.
+     */
     public final int infoType;
     /**
-    * The MIME type of the content.
-    */
+     * The MIME type of the content.
+     */
     public final String mimeType;
     /**
-    * The processed data.
-    */
+     * The processed data.
+     */
     public final ProcessedData data;
 
     /**
diff --git a/drm/libdrmframework/include/PlugInManager.h b/drm/libdrmframework/include/PlugInManager.h
index 8029138..7bb143f 100644
--- a/drm/libdrmframework/include/PlugInManager.h
+++ b/drm/libdrmframework/include/PlugInManager.h
@@ -202,7 +202,7 @@
     Vector<String8> getPlugInPathList(const String8& rsDirPath) {
         Vector<String8> fileList;
         DIR* pDir = opendir(rsDirPath.string());
-        struct dirent* pEntry = new dirent();
+        struct dirent* pEntry;
 
         while (NULL != pDir && NULL != (pEntry = readdir(pDir))) {
             if (!isPlugIn(pEntry)) {
@@ -219,8 +219,6 @@
         if (NULL != pDir) {
             closedir(pDir);
         }
-        delete pEntry;
-        pEntry = NULL;
 
         return fileList;
     }
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 0ffd201..6c7341f 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -66,11 +66,8 @@
 
     /**
      * This field is used by native code, do not access or modify.
-     * 
-     * @hide
      */
-    @SuppressWarnings({"UnusedDeclaration"})
-    public int mSurfaceTexture;
+    private int mSurfaceTexture;
 
     /**
      * Callback interface for being notified that a new stream frame is available.
diff --git a/include/utils/BlobCache.h b/include/utils/BlobCache.h
index 8f76d72..dc45ff0 100644
--- a/include/utils/BlobCache.h
+++ b/include/utils/BlobCache.h
@@ -82,6 +82,9 @@
     BlobCache(const BlobCache&);
     void operator=(const BlobCache&);
 
+    // A random function helper to get around MinGW not having nrand48()
+    long int blob_random();
+
     // clean evicts a randomly chosen set of entries from the cache such that
     // the total size of all remaining entries is less than mMaxTotalSize/2.
     void clean();
diff --git a/libs/utils/BlobCache.cpp b/libs/utils/BlobCache.cpp
index 1298fa7..590576a 100644
--- a/libs/utils/BlobCache.cpp
+++ b/libs/utils/BlobCache.cpp
@@ -31,9 +31,13 @@
         mMaxTotalSize(maxTotalSize),
         mTotalSize(0) {
     nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+#ifdef _WIN32
+    srand(now);
+#else
     mRandState[0] = (now >> 0) & 0xFFFF;
     mRandState[1] = (now >> 16) & 0xFFFF;
     mRandState[2] = (now >> 32) & 0xFFFF;
+#endif
     LOGV("initializing random seed using %lld", now);
 }
 
@@ -148,11 +152,19 @@
     return valueBlobSize;
 }
 
+long int BlobCache::blob_random() {
+#ifdef _WIN32
+    return rand();
+#else
+    return nrand48(mRandState);
+#endif
+}
+
 void BlobCache::clean() {
     // Remove a random cache entry until the total cache size gets below half
     // the maximum total cache size.
     while (mTotalSize > mMaxTotalSize / 2) {
-        size_t i = size_t(nrand48(mRandState) % (mCacheEntries.size()));
+        size_t i = size_t(blob_random() % (mCacheEntries.size()));
         const CacheEntry& entry(mCacheEntries[i]);
         mTotalSize -= entry.getKey()->getSize() + entry.getValue()->getSize();
         mCacheEntries.removeAt(i);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
index d6e1346..f3a91c5 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
@@ -1,57 +1,54 @@
 /*
  * Copyright (C) 2008 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
+ * 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
+ * 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.
+ * 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.mediaframeworktest;
 
 /**
- * 
- * This class has the names of the all the activity name and variables 
- * in the instrumentation test.
+ *
+ * This class has the names of the all the activity name and variables in the
+ * instrumentation test.
  *
  */
 public class MediaNames {
-    //A directory to hold all kinds of media files
+    // A directory to hold all kinds of media files
     public static final String MEDIA_SAMPLE_POOL = "/sdcard/media_api/samples/";
-    //Audio files
-    public static final String MP3CBR = "/sdcard/media_api/music/MP3_256kbps_2ch.mp3";
-    public static final String MP3VBR = "/sdcard/media_api/music/MP3_256kbps_2ch_VBR.mp3";
+    // Audio files
+    public static final String MP3CBR = "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3";
+    public static final String MP3VBR = "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3";
+    public static final String MP3ABR = "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ABR.mp3";
     public static final String SHORTMP3 = "/sdcard/media_api/music/SHORTMP3.mp3";
     public static final String MIDI = "/sdcard/media_api/music/ants.mid";
-    public static final String WMA9 = "/sdcard/media_api/music/WMA9.wma";
-    public static final String WMA10 = "/sdcard/media_api/music/WMA10.wma";
     public static final String WAV = "/sdcard/media_api/music/rings_2ch.wav";
     public static final String AMR = "/sdcard/media_api/music/test_amr_ietf.amr";
-    public static final String OGG = "/sdcard/media_api/music/Revelation.ogg";
     public static final String SINE_200_1000 = "/sdcard/media_api/music/sine_200+1000Hz_44K_mo.wav";
-  
+    // public static final String OGG =
+    // "/sdcard/media_api/music/Revelation.ogg";
+
     public static final int MP3CBR_LENGTH = 71000;
     public static final int MP3VBR_LENGTH = 71000;
     public static final int SHORTMP3_LENGTH = 286;
     public static final int MIDI_LENGTH = 17000;
-    public static final int WMA9_LENGTH = 126559;
-    public static final int WMA10_LENGTH = 126559;
     public static final int AMR_LENGTH = 37000;
-    public static final int OGG_LENGTH = 4000;
     public static final int SEEK_TIME = 10000;
-  
+
     public static final long PAUSE_WAIT_TIME = 3000;
     public static final long WAIT_TIME = 2000;
     public static final long WAIT_SNAPSHOT_TIME = 5000;
 
-    //local video
+    // local video
     public static final String VIDEO_MP4 = "/sdcard/media_api/video/MPEG4_320_AAC_64.mp4";
     public static final String VIDEO_SHORT_3GP = "/sdcard/media_api/video/short.3gp";
     public static final String VIDEO_LARGE_SIZE_3GP = "/sdcard/media_api/video/border_large.3gp";
@@ -59,185 +56,105 @@
     public static final String VIDEO_H263_AMR = "/sdcard/media_api/video/H263_56_AMRNB_6.3gp";
     public static final String VIDEO_H264_AAC = "/sdcard/media_api/video/H264_320_AAC_64.3gp";
     public static final String VIDEO_H264_AMR = "/sdcard/media_api/video/H264_320_AMRNB_6.3gp";
-    public static final String VIDEO_WMV = "/sdcard/media_api/video/bugs.wmv";
     public static final String VIDEO_HIGHRES_H263 = "/sdcard/media_api/video/H263_500_AMRNB_12.3gp";
     public static final String VIDEO_HIGHRES_MP4 = "/sdcard/media_api/video/H264_500_AAC_128.3gp";
-    
-    //Media Recorder
+    public static final String VIDEO_WEBM = "/sdcard/media_api/video/big-buck-bunny_trailer.webm";
+
+    // Media Recorder
     public static final String RECORDER_OUTPUT = "/sdcard/media_api/recorderOutput.amr";
 
-    //video thumbnail
+    // video thumbnail
     public static final String THUMBNAIL_OUTPUT = "/sdcard/media_api/videoThumbnail.png";
     public static final String GOLDEN_THUMBNAIL_OUTPUT = "/sdcard/media_api/goldenThumbnail.png";
-    public static final String GOLDEN_THUMBNAIL_OUTPUT_2 = "/sdcard/media_api/goldenThumbnail2.png";
-    
-    //Metadata Utility
-    public static final String[] THUMBNAIL_CAPTURE_TEST_FILES = {
-      "/sdcard/media_api/metadata/test.mp4",
-      "/sdcard/media_api/metadata/test1.3gp",
-      "/sdcard/media_api/metadata/test2.3gp",
-      "/sdcard/media_api/metadata/test3.3gp",
-      "/sdcard/media_api/metadata/test4.3gp",
-      "/sdcard/media_api/metadata/test5.3gp",
-      "/sdcard/media_api/metadata/test6.3gp",
-      "/sdcard/media_api/metadata/test7.3gp",
-      "/sdcard/media_api/metadata/test8.3gp",
-      "/sdcard/media_api/metadata/test9.3gp",
-      "/sdcard/media_api/metadata/test10.3gp",
-      "/sdcard/media_api/metadata/test11.3gp",
-      "/sdcard/media_api/metadata/test12.3gp",
-      "/sdcard/media_api/metadata/test13.3gp",
-      "/sdcard/media_api/metadata/test14.3gp",
-      "/sdcard/media_api/metadata/test15.3gp",
-      "/sdcard/media_api/metadata/test16.3gp",
-      "/sdcard/media_api/metadata/test17.3gp",
-      "/sdcard/media_api/metadata/test18.3gp",
-      "/sdcard/media_api/metadata/test19.3gp",
-      "/sdcard/media_api/metadata/test20.3gp",
-      "/sdcard/media_api/metadata/test21.3gp",
-      "/sdcard/media_api/metadata/test22.3gp",
-      "/sdcard/media_api/metadata/test23.3gp",
-      "/sdcard/media_api/metadata/test24.3gp",
-      "/sdcard/media_api/metadata/test25.3gp",
-      "/sdcard/media_api/metadata/test26.3gp",
-      "/sdcard/media_api/metadata/test27.3gp",
-      "/sdcard/media_api/metadata/test28.3gp",
-      "/sdcard/media_api/metadata/test29.3gp",
-      "/sdcard/media_api/metadata/test30.3gp",
-      "/sdcard/media_api/metadata/test31.3gp",
-      "/sdcard/media_api/metadata/test32.3gp",
-      "/sdcard/media_api/metadata/test33.3gp",
-      "/sdcard/media_api/metadata/test35.mp4",
-      "/sdcard/media_api/metadata/test36.m4v",
-      "/sdcard/media_api/metadata/test34.wmv",
-      "/sdcard/media_api/metadata/test_metadata.mp4",
-  };
 
-  public static final String[] METADATA_RETRIEVAL_TEST_FILES = {
-      // Raw AAC is not supported
-      // "/sdcard/media_api/test_raw.aac",
-      // "/sdcard/media_api/test_adts.aac",
-      // "/sdcard/media_api/test_adif.aac",
-      "/sdcard/media_api/metadata/test_metadata.mp4",
-      "/sdcard/media_api/metadata/WMA10.wma",
-      "/sdcard/media_api/metadata/Leadsol_out.wav",
-      "/sdcard/media_api/metadata/test_aac.mp4",
-      "/sdcard/media_api/metadata/test_amr.mp4",
-      "/sdcard/media_api/metadata/test_avc_amr.mp4",
-      "/sdcard/media_api/metadata/test_metadata.mp4",
-      "/sdcard/media_api/metadata/test_vbr.mp3",
-      "/sdcard/media_api/metadata/test_cbr.mp3",
-      "/sdcard/media_api/metadata/metadata_test1.mp3",
-      "/sdcard/media_api/metadata/test33.3gp",
-      "/sdcard/media_api/metadata/test35.mp4",
-      "/sdcard/media_api/metadata/test36.m4v",
-      "/sdcard/media_api/metadata/test_m4v_amr.mp4",
-      "/sdcard/media_api/metadata/test_h263_amr.mp4",
-      "/sdcard/media_api/metadata/test34.wmv",
-  };
-  
-  public static final String[] ALBUMART_TEST_FILES = {
-      "/sdcard/media_api/album_photo/test_22_16_mp3.mp3",
-      "/sdcard/media_api/album_photo/PD_256kbps_48khz_mono_CBR_MCA.mp3",
-      "/sdcard/media_api/album_photo/PD_256kbps_44.1khz_mono_CBR_DPA.mp3",
-      "/sdcard/media_api/album_photo/PD_192kbps_32khz_mono_CBR_DPA.mp3",
-      "/sdcard/media_api/album_photo/NIN_256kbps_48khz_mono_CBR_MCA.mp3",
-      "/sdcard/media_api/album_photo/NIN_256kbps_44.1khz_mono_CBR_MCA.mp3",
-      "/sdcard/media_api/album_photo/NIN_112kbps(96kbps)_48khz_stereo_VBR_MCA.mp3",
-      "/sdcard/media_api/album_photo/NIN_112kbps(96kbps)_44.1khz_stereo_VBR_MCA.mp3",
-      "/sdcard/media_api/album_photo/lightGreen1.mp3",
-      "/sdcard/media_api/album_photo/babyBlue2 1.mp3",
-      "/sdcard/media_api/album_photo/2-01 01 NIN_56kbps(64kbps)_32khz_stereo_VBR_MCA.mp3",
-      "/sdcard/media_api/album_photo/02_NIN_112kbps(80kbps)_32khz_stereo_VBR_MCA.mp3",
-      "/sdcard/media_api/album_photo/No_Woman_No_Cry_128K.wma",
-      "/sdcard/media_api/album_photo/Beethoven_2.wma",
-  };
+    /*
+     * Metadata Utility Test media files which contain meta data.
+     */
+    public static final String[] THUMBNAIL_METADATA_TEST_FILES = {
+        "/sdcard/media_api/video/H263_500_AMRNB_12.3gp",
+        "/sdcard/media_api/video/H263_56_AAC_24.3gp",
+        "/sdcard/media_api/video/H263_56_AMRNB_6.3gp",
+        "/sdcard/media_api/video/H264_320_AAC_64.3gp",
+        "/sdcard/media_api/video/H264_320_AMRNB_6.3gp",
+        "/sdcard/media_api/video/H264_500_AAC_128.3gp",
+        "/sdcard/media_api/video/H264_HVGA_500_NO_AUDIO.3gp",
+        "/sdcard/media_api/video/H264_QVGA_500_NO_AUDIO.3gp",
+        "/sdcard/media_api/video/MPEG4_320_AAC_64.mp4",
+        "/sdcard/media_api/video/border_large.3gp",
+        "/sdcard/media_api/videoeditor/H264_BP_800x480_15fps_512kbps_AACLC_24KHz_38Kbps_s_1_17.mp4",
+        "/sdcard/media_api/videoeditor/H264_MP_960x720_25fps_800kbps_AACLC_48Khz_192Kbps_s_1_17.mp4",
+        "/sdcard/media_api/videoeditor/MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4",
+        "/sdcard/media_api/videoeditor/MPEG4_SP_176x144_12fps_92kbps_AMRNB_8KHz_12.2kbps_m_0_27.3gp",
+        "/sdcard/media_api/videoeditor/MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4"
+    };
 
-  //TEST_PATH_1: is a video and contains metadata for key "num-tracks"
-  // TEST_PATH_2: any valid media file.
-  // TEST_PATH_3: invalid media file
-  public static final String TEST_PATH_1 = "/sdcard/media_api/metadata/test.mp4";
-  public static final String TEST_PATH_3 = "/sdcard/media_api/data.txt";
-  public static final String TEST_PATH_4 = "somenonexistingpathname";
-  public static final String TEST_PATH_5 = "mem://012345";
-  
-  //Meta data expected result
-  //The expected tag result in the following order
-  //cd_track_number, album, artist, author, composer, date, genre
-  //title, years, duration
-  public static final String META_DATA_MP3 [][] = {
-      {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V1_ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist",
-          "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, "Blues",
-          "ID3V2.3 Title", "1234", "295", "1", null},
-      {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist",
-          "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, "Blues", 
-          "ID3V2.3 Title", "1234", "287", "1", null},
-      {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V1.mp3", "1", "test ID3V1 Album", "test ID3V1 Artist",
-          null, null, null, "255", "test ID3V1 Title", "1234", "231332", "1", null},
-      {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V1.mp3" , null, null, null,
-              null, null, null, null, null, null, "231330", "1", null},
-      //The corrupted TALB field in id3v2 would not switch to id3v1 tag automatically
-      {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TALB.mp3", "01", null, "ID3V2.3 Artist",
-          "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, 
-          "Blues", "ID3V2.3 Title", "1234", "295", "1", null},
-      {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM.mp3", "01", "ID3V2.3 Album", 
-           "ID3V2.3 Artist", "ID3V2.3 Lyricist", null, null, 
-           "Blues", "ID3V2.3 Title", "1234", "295", "1", null},
-      {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM_2.mp3", "01", "ID3V2.3 Album", 
-           "ID3V2.3 Artist", null, null, null, "Blues", "ID3V2.3 Title", "1234", "295", "1", null},
-      {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK.mp3", "dd", "ID3V2.3 Album", 
-           "ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null,
-           "Blues", "ID3V2.3 Title", "1234", "295", "1", null},
-      {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK_2.mp3", "01", "ID3V2.3 Album", 
-           "ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", null, "295", "1", null},
-      {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER.mp3", "01", "ID3V2.3 Album",
-           "ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", "9999", "295", "1", null},
-      {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER_2.mp3", "01", "ID3V2.3 Album",
-           "ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, 
-           "Blues", "ID3V2.3 Title", null, "295", "1", null},
-      {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TIT.mp3", null, null, null,
-          null, null, null, null, null, null, "295", "1", null}
-  };
+    public static final String[] ALBUMART_TEST_FILES = {
+        "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3",
+        "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3",
+        "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3",
+    };
 
-  //output recorded video
+    // TEST_PATH_1: is a video and contains metadata for key "num-tracks"
+    // TEST_PATH_2: any valid media file.
+    // TEST_PATH_3: invalid media file
+    public static final String TEST_PATH_1 = "/sdcard/media_api/video/MPEG4_320_AAC_64.mp4";
+    public static final String TEST_PATH_3 = "/sdcard/media_api/data.txt";
+    public static final String TEST_PATH_4 = "somenonexistingpathname";
+    public static final String TEST_PATH_5 = "mem://012345";
 
-  public static final String RECORDED_HVGA_H263 = "/sdcard/HVGA_H263.3gp";
-  public static final String RECORDED_QVGA_H263 = "/sdcard/QVGA_H263.3gp";
-  public static final String RECORDED_SQVGA_H263 = "/sdcard/SQVGA_H263.3gp";
-  public static final String RECORDED_CIF_H263 = "/sdcard/CIF_H263.3gp";
-  public static final String RECORDED_QCIF_H263 = "/sdcard/QCIF_H263.3gp";
-  public static final String RECORDED_PORTRAIT_H263 = "/sdcard/QCIF_mp4.3gp";
-  
-  public static final String RECORDED_HVGA_MP4 = "/sdcard/HVGA_mp4.mp4";
-  public static final String RECORDED_QVGA_MP4 = "/sdcard/QVGA_mp4.mp4";
-  public static final String RECORDED_SQVGA_MP4 = "/sdcard/SQVGA_mp4.mp4";
-  public static final String RECORDED_CIF_MP4 = "/sdcard/CIF_mp4.mp4";
-  public static final String RECORDED_QCIF_MP4 = "/sdcard/QCIF_mp4.mp4";
-  
-  public static final String RECORDED_VIDEO_3GP = "/sdcard/temp.3gp";
-  
-  public static final String INVALD_VIDEO_PATH = "/sdcard/media_api/filepathdoesnotexist" +
-      "/filepathdoesnotexist/temp.3gp";
-  
- 
-  public static final long RECORDED_TIME = 5000;
-  public static final long VALID_VIDEO_DURATION = 2000;
+    // Meta data expected result
+    // The expected tag result in the following order
+    // cd_track_number, album, artist, author, composer, date, genre
+    // title, years, duration
+    public static final String META_DATA_MP3[][] = {
+        {"/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3", "2/34",
+         "Test ID3V2 Album", "Test ID3V2 Artist", null, "Test ID3V2 Composer",
+         null, "(1)Classic Rock", "Test ID3V2 Title ", null, "77640", "1", null},
+        {"/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3", "1/10",
+         "Test ID3V2 Album", "Test ID3V2 Artist", null, "Test ID3V2 Composer",
+         null, "(74)Acid Jazz", "Test ID3V2 Tag", null, "77640", "1", null},
+        {"/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3", "2",
+         "Test ID3V1 Album", "Test ID3V1 Artist", null, null, null, "(15)",
+         "Test ID3V1 Title", "2011", "77640", "1", null}
+    };
 
-  //Streaming test files
-  public static final byte [] STREAM_SERVER = new byte[] {(byte)75,(byte)17,(byte)48,(byte)204};
-  public static final String STREAM_H264_480_360_1411k = 
-      "http://75.17.48.204:10088/yslau/stress_media/h264_regular.mp4";
-  public static final String STREAM_WMV = 
-      "http://75.17.48.204:10088/yslau/stress_media/bugs.wmv";
-  public static final String STREAM_H263_176x144_325k = 
-      "http://75.17.48.204:10088/yslau/stress_media/h263_regular.3gp";
-  public static final String STREAM_H264_352x288_1536k = 
-      "http://75.17.48.204:10088/yslau/stress_media/h264_highBitRate.mp4";
-  public static final String STREAM_MP3= 
-      "http://75.17.48.204:10088/yslau/stress_media/mp3_regular.mp3";
-  public static final String STREAM_MPEG4_QVGA_128k = 
-      "http://75.17.48.204:10088/yslau/stress_media/mpeg4_qvga_24fps.3gp";
-  public static final int STREAM_H264_480_360_1411k_DURATION = 46000;
-  public static final int VIDEO_H263_AAC_DURATION = 501000;
-  public static final int VIDEO_H263_AMR_DURATION = 502000;
+    // output recorded video
+    public static final String RECORDED_HVGA_H263 = "/sdcard/HVGA_H263.3gp";
+    public static final String RECORDED_QVGA_H263 = "/sdcard/QVGA_H263.3gp";
+    public static final String RECORDED_SQVGA_H263 = "/sdcard/SQVGA_H263.3gp";
+    public static final String RECORDED_CIF_H263 = "/sdcard/CIF_H263.3gp";
+    public static final String RECORDED_QCIF_H263 = "/sdcard/QCIF_H263.3gp";
+    public static final String RECORDED_PORTRAIT_H263 = "/sdcard/QCIF_mp4.3gp";
+
+    public static final String RECORDED_HVGA_MP4 = "/sdcard/HVGA_mp4.mp4";
+    public static final String RECORDED_QVGA_MP4 = "/sdcard/QVGA_mp4.mp4";
+    public static final String RECORDED_SQVGA_MP4 = "/sdcard/SQVGA_mp4.mp4";
+    public static final String RECORDED_CIF_MP4 = "/sdcard/CIF_mp4.mp4";
+    public static final String RECORDED_QCIF_MP4 = "/sdcard/QCIF_mp4.mp4";
+
+    public static final String RECORDED_VIDEO_3GP = "/sdcard/temp.3gp";
+
+    public static final String INVALD_VIDEO_PATH =
+            "/sdcard/media_api/filepathdoesnotexist" + "/filepathdoesnotexist/temp.3gp";
+
+    public static final long RECORDED_TIME = 5000;
+    public static final long VALID_VIDEO_DURATION = 2000;
+
+    // Streaming test files
+    public static final byte[] STREAM_SERVER =
+            new byte[] {(byte) 75, (byte) 17, (byte) 48, (byte) 204};
+    public static final String STREAM_H264_480_360_1411k =
+            "http://75.17.48.204:10088/yslau/stress_media/h264_regular.mp4";
+    public static final String STREAM_WMV = "http://75.17.48.204:10088/yslau/stress_media/bugs.wmv";
+    public static final String STREAM_H263_176x144_325k =
+            "http://75.17.48.204:10088/yslau/stress_media/h263_regular.3gp";
+    public static final String STREAM_H264_352x288_1536k =
+            "http://75.17.48.204:10088/yslau/stress_media/h264_highBitRate.mp4";
+    public static final String STREAM_MP3 =
+            "http://75.17.48.204:10088/yslau/stress_media/mp3_regular.mp3";
+    public static final String STREAM_MPEG4_QVGA_128k =
+            "http://75.17.48.204:10088/yslau/stress_media/mpeg4_qvga_24fps.3gp";
+    public static final int STREAM_H264_480_360_1411k_DURATION = 46000;
+    public static final int VIDEO_H263_AAC_DURATION = 501000;
+    public static final int VIDEO_H263_AMR_DURATION = 502000;
 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java
index 00e0a52..380de9c 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java
@@ -41,10 +41,7 @@
     }
     
     public static enum MP3_TEST_FILE{
-        ID3V1V2, ID3V2, ID3V1,
-        CORRUPTED_ID3V1, CORRUPTED_ID3V2_TALB, CORRUPTED_ID3V2_TCOM,
-        CORRUPTED_ID3V2_TCOM_2, CORRUPTED_ID3V2_TRCK, CORRUPTED_D3V2_TRCK_2,
-        CORRUPTED_ID3V2_TYER, CORRUPTED_ID3V2_TYER_2, CORRUPTED_ID3V2_TIT
+        ID3V1V2, ID3V2, ID3V1
     }
     
     public static METADATA_EXPECTEDRESULT meta;
@@ -64,53 +61,7 @@
     public static void testID3V1Metadata() throws Exception {
         validateMetatData(mp3_test_file.ID3V1.ordinal(), MediaNames.META_DATA_MP3);
     }
-    
-    @MediumTest
-    public static void testCorruptedID3V1Metadata() throws Exception {
-        validateMetatData(mp3_test_file.CORRUPTED_ID3V1.ordinal(), MediaNames.META_DATA_MP3);
-    }
 
-    @MediumTest
-    public static void testCorrupted_ID3V2_TALBMetadata() throws Exception {
-        validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TALB.ordinal(), MediaNames.META_DATA_MP3);
-    }
-    
-    @MediumTest
-    public static void testCorrupted_ID3V2_TCOMMetadata() throws Exception {
-        validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TCOM.ordinal(), MediaNames.META_DATA_MP3);
-    }
-    
-    @MediumTest
-    public static void testCorrupted_ID3V2_TCOMM2etadata() throws Exception {
-        validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TCOM_2.ordinal(), MediaNames.META_DATA_MP3);
-    }
-    
-    @MediumTest
-    public static void testCorrupted_ID3V2_TRCKMetadata() throws Exception {
-        validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TRCK.ordinal(), MediaNames.META_DATA_MP3);
-    }
-    
-    @MediumTest
-    public static void testCorrupted_ID3V2_TRCK2Metadata() throws Exception {
-        validateMetatData(mp3_test_file.CORRUPTED_D3V2_TRCK_2.ordinal(), MediaNames.META_DATA_MP3);
-    }
-   
-    @MediumTest
-    public static void testCorrupted_ID3V2_TYERMetadata() throws Exception {
-        validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TYER.ordinal(), MediaNames.META_DATA_MP3);
-    }
-    
-    @MediumTest
-    public static void testCorrupted_ID3V2_TYER2Metadata() throws Exception {
-        validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TYER_2.ordinal(), MediaNames.META_DATA_MP3);
-    }
-    
-    @MediumTest
-    public static void testCorrupted_ID3V2_TITMetadata() throws Exception {
-        validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TIT.ordinal(), MediaNames.META_DATA_MP3);
-    }
-   
-     
     private static void validateMetatData(int fileIndex, String meta_data_file[][]) {
         Log.v(TAG, "filePath = "+ meta_data_file[fileIndex][0]);
         if ((meta_data_file[fileIndex][0].endsWith("wma") && !MediaProfileReader.getWMAEnable()) ||
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
index 3a9564d..57d5368 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
@@ -84,15 +84,6 @@
       duratoinWithinTolerence = verifyDuration(duration, MediaNames.MIDI_LENGTH);
       assertTrue("MIDI getDuration", duratoinWithinTolerence);  
     }
-    
-    @MediumTest
-    public void testWMA9GetDuration() throws Exception {
-      if (isWMAEnable) {
-            int duration = CodecTest.getDuration(MediaNames.WMA9);
-            duratoinWithinTolerence = verifyDuration(duration, MediaNames.WMA9_LENGTH);
-            assertTrue("WMA9 getDuration", duratoinWithinTolerence);
-        }
-    }
 
     @MediumTest
     public void testAMRGetDuration() throws Exception {
@@ -127,15 +118,7 @@
       boolean currentPosition = CodecTest.getCurrentPosition(MediaNames.MIDI);  
       assertTrue("MIDI GetCurrentPosition", currentPosition);  
     }
-    
-    @LargeTest
-    public void testWMA9GetCurrentPosition() throws Exception {
-        if (isWMAEnable) {
-            boolean currentPosition = CodecTest.getCurrentPosition(MediaNames.WMA9);
-            assertTrue("WMA9 GetCurrentPosition", currentPosition);
-        }
-    }
-    
+
     @LargeTest
     public void testAMRGetCurrentPosition() throws Exception {
       boolean currentPosition = CodecTest.getCurrentPosition(MediaNames.AMR);  
@@ -166,15 +149,7 @@
       boolean isPaused = CodecTest.pause(MediaNames.MIDI);  
       assertTrue("MIDI Pause", isPaused);  
     }
-   
-    @LargeTest
-    public void testWMA9Pause() throws Exception {
-        if (isWMAEnable) {
-            boolean isPaused = CodecTest.pause(MediaNames.WMA9);
-            assertTrue("WMA9 Pause", isPaused);
-        }
-    }
-  
+
     @LargeTest
     public void testAMRPause() throws Exception {
       boolean isPaused = CodecTest.pause(MediaNames.AMR);  
@@ -239,15 +214,7 @@
       boolean isLoop = CodecTest.setLooping(MediaNames.MIDI);  
       assertTrue("MIDI setLooping", isLoop);  
     }
-    
-    @LargeTest
-    public void testWMA9SetLooping() throws Exception {
-      if (isWMAEnable) {
-        boolean isLoop = CodecTest.setLooping(MediaNames.WMA9);
-        assertTrue("WMA9 setLooping", isLoop);
-      }
-    }
-    
+
     @LargeTest
     public void testAMRSetLooping() throws Exception {
       boolean isLoop = CodecTest.setLooping(MediaNames.AMR);  
@@ -279,15 +246,7 @@
       boolean isLoop = CodecTest.seekTo(MediaNames.MIDI);  
       assertTrue("MIDI seekTo", isLoop);  
     }
-    
-    @LargeTest
-    public void testWMA9SeekTo() throws Exception {
-        if (isWMAEnable) {
-            boolean isLoop = CodecTest.seekTo(MediaNames.WMA9);
-            assertTrue("WMA9 seekTo", isLoop);
-        }
-    }
-    
+
     @LargeTest
     public void testAMRSeekTo() throws Exception {
       boolean isLoop = CodecTest.seekTo(MediaNames.AMR);  
@@ -320,15 +279,6 @@
       boolean isEnd = CodecTest.seekToEnd(MediaNames.MIDI);  
       assertTrue("MIDI seekToEnd", isEnd);  
     }
-
-    @Suppress
-    @LargeTest
-    public void testWMA9SeekToEnd() throws Exception {
-        if (isWMAEnable) {
-            boolean isEnd = CodecTest.seekToEnd(MediaNames.WMA9);
-            assertTrue("WMA9 seekToEnd", isEnd);
-        }
-    }
     
     @LargeTest
     public void testAMRSeekToEnd() throws Exception {
@@ -393,17 +343,13 @@
       boolean isSeek = CodecTest.videoSeekTo(MediaNames.VIDEO_H264_AMR);
       assertTrue("H264AMR SeekTo", isSeek);         
     }
-   
+
     @LargeTest
-    public void testVideoWMVSeekTo() throws Exception {
-        Log.v(TAG, "wmv not enable");
-        if (isWMVEnable) {
-            Log.v(TAG, "wmv enable");
-            boolean isSeek = CodecTest.videoSeekTo(MediaNames.VIDEO_WMV);
-            assertTrue("WMV SeekTo", isSeek);
-        }
+    public void testVideoWebmSeekTo() throws Exception {
+      boolean isSeek = CodecTest.videoSeekTo(MediaNames.VIDEO_WEBM);
+      assertTrue("WEBM SeekTo", isSeek);
     }
-    
+
     @LargeTest
     public void testSoundRecord() throws Exception {
       boolean isRecordered = CodecTest.mediaRecorderRecord(MediaNames.RECORDER_OUTPUT);
@@ -412,7 +358,7 @@
   
     @LargeTest
     public void testGetThumbnail() throws Exception {
-      boolean getThumbnail = CodecTest.getThumbnail(MediaNames.VIDEO_H264_AAC, MediaNames.GOLDEN_THUMBNAIL_OUTPUT_2);
+      boolean getThumbnail = CodecTest.getThumbnail(MediaNames.VIDEO_H264_AAC, MediaNames.GOLDEN_THUMBNAIL_OUTPUT);
       assertTrue("Get Thumbnail", getThumbnail);         
     }
     
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 3b5b9a3..b396223 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -356,26 +356,6 @@
         assertTrue("H264 playback memory test", memoryResult);
     }
 
-    // Test case 3: Capture the memory usage after each 20 WMV playback
-    @LargeTest
-    public void testWMVVideoPlaybackMemoryUsage() throws Exception {
-        boolean memoryResult = false;
-        if (MediaProfileReader.getWMVEnable()){
-            mStartPid = getMediaserverPid();
-            File wmvMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
-            Writer output = new BufferedWriter(new FileWriter(wmvMemoryOut, true));
-            output.write("WMV video playback only\n");
-            for (int i = 0; i < NUM_STRESS_LOOP; i++) {
-                mediaStressPlayback(MediaNames.VIDEO_WMV);
-                getMemoryWriteToLog(output, i);
-            }
-            output.write("\n");
-            memoryResult = validateMemoryResult(mStartPid, mStartMemory, output, DECODER_LIMIT);
-            output.close();
-            assertTrue("wmv playback memory test", memoryResult);
-        }
-    }
-
     // Test case 4: Capture the memory usage after every 20 video only recorded
     @LargeTest
     public void testH263RecordVideoOnlyMemoryUsage() throws Exception {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
index a66db05..8eb75f3 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
@@ -76,29 +76,29 @@
         boolean hasFailed = false;
         Log.v(TAG, "Thumbnail processing starts");
         long startedAt = System.currentTimeMillis();
-        for(int i = 0, n = MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length; i < n; ++i) {
+        for(int i = 0, n = MediaNames.THUMBNAIL_METADATA_TEST_FILES.length; i < n; ++i) {
             try {
-                Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
-                if ((MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
-                    (MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
+                Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
+                if ((MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
+                    (MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
                    ) {
                     Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
                     continue;
                 }
-                retriever.setDataSource(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
+                retriever.setDataSource(MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
                 Bitmap bitmap = retriever.getFrameAtTime(-1);
                 assertTrue(bitmap != null);
                 try {
-                    java.io.OutputStream stream = new FileOutputStream(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i] + ".jpg");
+                    java.io.OutputStream stream = new FileOutputStream(MediaNames.THUMBNAIL_METADATA_TEST_FILES[i] + ".jpg");
                     bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
                     stream.close();
                 } catch (Exception e) {
-                    Log.e(TAG, "Fails to convert the bitmap to a JPEG file for " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
+                    Log.e(TAG, "Fails to convert the bitmap to a JPEG file for " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
                     hasFailed = true;
                     Log.e(TAG, e.toString());
                 }
             } catch(Exception e) {
-                Log.e(TAG, "Fails to setDataSource for file " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
+                Log.e(TAG, "Fails to setDataSource for file " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
                 hasFailed = true;
             }
             Thread.yield();  // Don't be evil
@@ -106,7 +106,7 @@
         long endedAt = System.currentTimeMillis();
         retriever.release();
         assertTrue(!hasFailed);
-        Log.v(TAG, "Average processing time per thumbnail: " + (endedAt - startedAt)/MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length + " ms");
+        Log.v(TAG, "Average processing time per thumbnail: " + (endedAt - startedAt)/MediaNames.THUMBNAIL_METADATA_TEST_FILES.length + " ms");
     }
     
     @LargeTest
@@ -115,19 +115,19 @@
         boolean supportWMV = MediaProfileReader.getWMVEnable();
         boolean hasFailed = false;
         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
-        for(int i = 0, n = MediaNames.METADATA_RETRIEVAL_TEST_FILES.length; i < n; ++i) {
+        for(int i = 0, n = MediaNames.THUMBNAIL_METADATA_TEST_FILES.length; i < n; ++i) {
             try {
-                Log.v(TAG, "File " + i + ": " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
-                if ((MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
-                    (MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
+                Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
+                if ((MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
+                    (MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
                    ) {
                     Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
                     continue;
                 }
-                retriever.setDataSource(MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
+                retriever.setDataSource(MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
                 extractAllSupportedMetadataValues(retriever);
             } catch(Exception e) {
-                Log.e(TAG, "Fails to setDataSource for file " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
+                Log.e(TAG, "Fails to setDataSource for file " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
                 hasFailed = true;
             }
             Thread.yield();  // Don't be evil
@@ -239,45 +239,6 @@
         assertTrue(!hasFailed);
     }
 
-    @MediumTest
-    public static void testIntendedUsage() {
-        // By default, capture frame and retrieve metadata
-        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
-        boolean hasFailed = false;
-        retriever.setDataSource(MediaNames.TEST_PATH_1);
-        assertTrue(retriever.getFrameAtTime(-1) != null);
-        assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null);
-
-        // Do not capture frame or retrieve metadata
-        retriever.setDataSource(MediaNames.TEST_PATH_1);
-        if (retriever.getFrameAtTime(-1) != null) {
-            Log.e(TAG, "No frame expected, but is available");
-            hasFailed = true;
-        }
-        if (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null) {
-            Log.e(TAG, "No num track metadata expected, but is available");
-            hasFailed = true;
-        }
-
-        // Capture frame only
-        retriever.setDataSource(MediaNames.TEST_PATH_1);
-        assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) == null);
-
-        // Retriever metadata only
-        retriever.setDataSource(MediaNames.TEST_PATH_1);
-        if (retriever.getFrameAtTime(-1) != null) {
-            Log.e(TAG, "No frame expected, but is available");
-            hasFailed = true;
-        }
-
-        // Capture frame and retrieve metadata
-        retriever.setDataSource(MediaNames.TEST_PATH_1);
-        assertTrue(retriever.getFrameAtTime(-1) != null);
-        assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null);
-        retriever.release();
-        assertTrue(!hasFailed);
-    }
-
     // TODO:
     // Encode and test for the correct mix of metadata elements on a per-file basis?
     // We should be able to compare the actual returned metadata with the expected metadata
diff --git a/media/tests/contents/media_api/goldenThumbnail.png b/media/tests/contents/media_api/goldenThumbnail.png
new file mode 100755
index 0000000..3bb6ed2
--- /dev/null
+++ b/media/tests/contents/media_api/goldenThumbnail.png
Binary files differ
diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17.mp3
new file mode 100755
index 0000000..e0d6a17
--- /dev/null
+++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17.mp3
Binary files differ
diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ABR.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ABR.mp3
new file mode 100644
index 0000000..12f7193
--- /dev/null
+++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ABR.mp3
Binary files differ
diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3
new file mode 100644
index 0000000..12f7193
--- /dev/null
+++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3
Binary files differ
diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3
new file mode 100644
index 0000000..29d332b
--- /dev/null
+++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3
Binary files differ
diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3
new file mode 100644
index 0000000..ea52638
--- /dev/null
+++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3
Binary files differ
diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3
new file mode 100644
index 0000000..024039c
--- /dev/null
+++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3
Binary files differ
diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3
new file mode 100644
index 0000000..12f7193
--- /dev/null
+++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3
Binary files differ
diff --git a/media/tests/contents/media_api/music/SHORTMP3.mp3 b/media/tests/contents/media_api/music/SHORTMP3.mp3
new file mode 100755
index 0000000..8b51b5d
--- /dev/null
+++ b/media/tests/contents/media_api/music/SHORTMP3.mp3
Binary files differ
diff --git a/media/tests/contents/media_api/music/ants.mid b/media/tests/contents/media_api/music/ants.mid
new file mode 100755
index 0000000..d4ead53
--- /dev/null
+++ b/media/tests/contents/media_api/music/ants.mid
Binary files differ
diff --git a/media/tests/contents/media_api/music/bzk_chic.wav b/media/tests/contents/media_api/music/bzk_chic.wav
new file mode 100755
index 0000000..bab1a6b
--- /dev/null
+++ b/media/tests/contents/media_api/music/bzk_chic.wav
Binary files differ
diff --git a/media/tests/contents/media_api/music/sine_200+1000Hz_44K_mo.wav b/media/tests/contents/media_api/music/sine_200+1000Hz_44K_mo.wav
new file mode 100755
index 0000000..312b6fb
--- /dev/null
+++ b/media/tests/contents/media_api/music/sine_200+1000Hz_44K_mo.wav
Binary files differ
diff --git a/media/tests/contents/media_api/music/test_amr_ietf.amr b/media/tests/contents/media_api/music/test_amr_ietf.amr
new file mode 100755
index 0000000..540794c
--- /dev/null
+++ b/media/tests/contents/media_api/music/test_amr_ietf.amr
Binary files differ
diff --git a/media/tests/contents/media_api/video/big-buck-bunny_trailer.webm b/media/tests/contents/media_api/video/big-buck-bunny_trailer.webm
new file mode 100755
index 0000000..6a17395
--- /dev/null
+++ b/media/tests/contents/media_api/video/big-buck-bunny_trailer.webm
Binary files differ
diff --git a/opengl/java/com/google/android/gles_jni/EGLImpl.java b/opengl/java/com/google/android/gles_jni/EGLImpl.java
index f162d40..51d6ca8 100644
--- a/opengl/java/com/google/android/gles_jni/EGLImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLImpl.java
@@ -85,7 +85,7 @@
             eglSurfaceId = _eglCreateWindowSurface(display, config, sur, attrib_list);
         } else if (native_window instanceof SurfaceTexture) {
             eglSurfaceId = _eglCreateWindowSurfaceTexture(display, config,
-                    ((SurfaceTexture) native_window).mSurfaceTexture, attrib_list);
+                    (SurfaceTexture) native_window, attrib_list);
         } else {
             throw new java.lang.UnsupportedOperationException(
                 "eglCreateWindowSurface() can only be called with an instance of " +
@@ -143,7 +143,7 @@
     private native int _eglCreatePbufferSurface(EGLDisplay display, EGLConfig config, int[] attrib_list);
     private native void _eglCreatePixmapSurface(EGLSurface sur, EGLDisplay display, EGLConfig config, Object native_pixmap, int[] attrib_list);
     private native int _eglCreateWindowSurface(EGLDisplay display, EGLConfig config, Object native_window, int[] attrib_list);
-    private native int _eglCreateWindowSurfaceTexture(EGLDisplay display, EGLConfig config, int native_window, int[] attrib_list);
+    private native int _eglCreateWindowSurfaceTexture(EGLDisplay display, EGLConfig config, Object native_window, int[] attrib_list);
     private native int _eglGetDisplay(Object native_display);
     private native int _eglGetCurrentContext();
     private native int _eglGetCurrentDisplay();
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index bbe146d6..55f5280 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -33,13 +33,6 @@
                 android:excludeFromRecents="true">
         </activity>
 
-        <activity android:name=".recent.RecentApplicationsActivity"
-            android:theme="@android:style/Theme.NoTitleBar"
-            android:excludeFromRecents="true"
-            android:launchMode="singleInstance"
-            android:exported="true">
-        </activity>
-
         <!-- started from UsbDeviceSettingsManager -->
         <activity android:name=".usb.UsbConfirmActivity"
             android:exported="true"
diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_diagram.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_diagram.png
new file mode 100644
index 0000000..944b1f0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_diagram.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_bottom.9.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_bottom.9.png
new file mode 100644
index 0000000..2e11928
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_bottom.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_top.9.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_top.9.png
new file mode 100644
index 0000000..58a78b7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_top.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_icon.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_icon.png
new file mode 100644
index 0000000..46bb891
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_icon.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_top_divider.9.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_top_divider.9.png
new file mode 100644
index 0000000..03a5639
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_top_divider.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png
index 87a67c9..23aabce 100644
--- a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png
+++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.png
new file mode 100644
index 0000000..0b0765b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-hdpi/app_icon.png b/packages/SystemUI/res/drawable-large-hdpi/app_icon.png
deleted file mode 100644
index aedf7e7..0000000
--- a/packages/SystemUI/res/drawable-large-hdpi/app_icon.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-hdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-large-hdpi/recents_bg_protect_tile.png
deleted file mode 100644
index a57c27a..0000000
--- a/packages/SystemUI/res/drawable-large-hdpi/recents_bg_protect_tile.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-mdpi/app_icon.png b/packages/SystemUI/res/drawable-large-mdpi/app_icon.png
deleted file mode 100644
index 50a8ac8..0000000
--- a/packages/SystemUI/res/drawable-large-mdpi/app_icon.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-large-mdpi/recents_bg_protect_tile.png
deleted file mode 100644
index 87c7be6..0000000
--- a/packages/SystemUI/res/drawable-large-mdpi/recents_bg_protect_tile.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-large-mdpi/recents_blue_glow.9.png
deleted file mode 100644
index 4f4ae78..0000000
--- a/packages/SystemUI/res/drawable-large-mdpi/recents_blue_glow.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_callout_line.png b/packages/SystemUI/res/drawable-large-mdpi/recents_callout_line.png
deleted file mode 100644
index 5f4c035..0000000
--- a/packages/SystemUI/res/drawable-large-mdpi/recents_callout_line.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg.png
deleted file mode 100644
index 87a67c9..0000000
--- a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg_press.png
deleted file mode 100644
index a1c39e6..0000000
--- a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg_press.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_diagram.png b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_diagram.png
new file mode 100644
index 0000000..518a5c1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_diagram.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_bottom.9.png b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_bottom.9.png
new file mode 100644
index 0000000..3712abf
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_bottom.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_top.9.png b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_top.9.png
new file mode 100644
index 0000000..a4d08c8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_top.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_icon.png b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_icon.png
new file mode 100644
index 0000000..233c4df
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_icon.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png
index 87a67c9..23aabce 100644
--- a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png
+++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png
index a1c39e6..0b0765b 100644
--- a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png
+++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/compat_mode_help_bg.png b/packages/SystemUI/res/drawable-nodpi/compat_mode_help_bg.png
index d1d32a4..59a70ff 100644
--- a/packages/SystemUI/res/drawable-nodpi/compat_mode_help_bg.png
+++ b/packages/SystemUI/res/drawable-nodpi/compat_mode_help_bg.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/app_icon.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/app_icon.png
deleted file mode 100644
index aedf7e7..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/app_icon.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/app_icon.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/app_icon.png
deleted file mode 100644
index 50a8ac8..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/app_icon.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/compat_mode_help_bg.png b/packages/SystemUI/res/drawable/compat_mode_help_bg.png
new file mode 100644
index 0000000..87d8c41
--- /dev/null
+++ b/packages/SystemUI/res/drawable/compat_mode_help_bg.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/compat_mode_help_diagram.png b/packages/SystemUI/res/drawable/compat_mode_help_diagram.png
deleted file mode 100644
index e212231..0000000
--- a/packages/SystemUI/res/drawable/compat_mode_help_diagram.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/compat_mode_help_icon.png b/packages/SystemUI/res/drawable/compat_mode_help_icon.png
deleted file mode 100644
index 03bbef9..0000000
--- a/packages/SystemUI/res/drawable/compat_mode_help_icon.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
index ce72f04..be4f1d7 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
@@ -39,8 +39,8 @@
         android:layout_height="wrap_content"
         android:layout_alignLeft="@id/app_thumbnail"
         android:layout_alignTop="@id/app_thumbnail"
-        android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_border_width"
-        android:layout_marginTop="@dimen/status_bar_recents_thumbnail_border_height"
+        android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
+        android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
         android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width"
         android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height"
         android:adjustViewBounds="true"
@@ -56,7 +56,7 @@
         android:layout_alignLeft="@id/app_thumbnail"
         android:layout_below="@id/app_thumbnail"
         android:layout_marginTop="@dimen/status_bar_recents_text_description_padding"
-        android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_border_width"
+        android:layout_marginLeft="@dimen/recents_thumbnail_bg_padding_left"
         android:singleLine="true"
         android:ellipsize="marquee"
     />
@@ -71,7 +71,7 @@
         android:layout_alignLeft="@id/app_thumbnail"
         android:layout_below="@id/app_label"
         android:layout_marginTop="@dimen/status_bar_recents_text_description_padding"
-        android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_border_width"
+        android:layout_marginLeft="@dimen/recents_thumbnail_bg_padding_left"
         android:singleLine="true"
         android:ellipsize="marquee"
     />
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
index 75f5ee4..4a80489 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -27,10 +27,9 @@
     <FrameLayout
         android:id="@+id/recents_bg_protect"
         android:background="@drawable/recents_bg_protect_tile"
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_alignParentBottom="true"
-        android:layout_alignParentRight="true"
         android:paddingBottom="@*android:dimen/status_bar_height"
         android:clipToPadding="false"
         android:clipChildren="false">
diff --git a/packages/SystemUI/res/layout/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
similarity index 73%
rename from packages/SystemUI/res/layout/status_bar_recent_item.xml
rename to packages/SystemUI/res/layout-port/status_bar_recent_item.xml
index cd42d7e..76965c9 100644
--- a/packages/SystemUI/res/layout/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
@@ -36,53 +36,52 @@
     <ImageView android:id="@+id/app_icon"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginLeft="131dip"
-        android:layout_marginTop="13dip"
+        android:layout_alignLeft="@id/app_thumbnail"
+        android:layout_alignTop="@id/app_thumbnail"
+        android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
+        android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
         android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width"
         android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height"
         android:adjustViewBounds="true"
     />
 
-    <View android:id="@+id/recents_callout_line"
-        android:layout_width="97dip"
-        android:layout_height="1dip"
-        android:layout_alignParentTop="true"
-        android:layout_marginTop="61dip"
-        android:layout_alignParentLeft="true"
-        android:layout_marginLeft="16dip"
-        android:layout_toLeftOf="@id/app_thumbnail"
-        android:layout_marginRight="3dip"
-        android:background="@drawable/recents_callout_line"
-    />
-
     <TextView android:id="@+id/app_label"
-        android:layout_width="97dip"
+        android:layout_width="@dimen/status_bar_recents_app_label_width"
         android:layout_height="wrap_content"
-        android:textSize="@dimen/status_bar_recents_app_description_text_size"
+        android:textSize="@dimen/status_bar_recents_app_label_text_size"
         android:fadingEdge="horizontal"
         android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
         android:scrollHorizontally="true"
         android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginLeft="16dip"
-        android:layout_marginTop="32dip"
+        android:layout_alignTop="@id/app_icon"
+        android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
         android:singleLine="true"
         android:ellipsize="marquee"
     />
 
+    <View android:id="@+id/recents_callout_line"
+        android:layout_width="@dimen/status_bar_recents_app_label_width"
+        android:layout_height="1dip"
+        android:layout_alignParentLeft="true"
+        android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
+        android:layout_toLeftOf="@id/app_thumbnail"
+        android:layout_below="@id/app_label"
+        android:layout_marginRight="3dip"
+        android:layout_marginTop="3dip"
+        android:background="@drawable/recents_callout_line"
+    />
+
     <TextView android:id="@+id/app_description"
-        android:layout_width="97dip"
+        android:layout_width="@dimen/status_bar_recents_app_label_width"
         android:layout_height="wrap_content"
         android:textSize="@dimen/status_bar_recents_app_description_text_size"
         android:fadingEdge="horizontal"
         android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
         android:scrollHorizontally="true"
         android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginLeft="16dip"
-        android:layout_marginTop="61dip"
+        android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
+        android:layout_below="@id/recents_callout_line"
+        android:layout_marginTop="3dip"
         android:singleLine="true"
         android:ellipsize="marquee"
     />
diff --git a/packages/SystemUI/res/layout/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
similarity index 91%
rename from packages/SystemUI/res/layout/status_bar_recent_panel.xml
rename to packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
index 703cbc1..9391f9d 100644
--- a/packages/SystemUI/res/layout/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
@@ -22,12 +22,12 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/recents_root"
     android:layout_height="match_parent"
-    android:layout_width="wrap_content">
+    android:layout_width="match_parent">
 
     <FrameLayout
         android:id="@+id/recents_bg_protect"
         android:background="@drawable/recents_bg_protect_tile"
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_alignParentBottom="true"
         android:paddingBottom="@*android:dimen/status_bar_height"
@@ -35,9 +35,9 @@
         android:clipChildren="false">
 
         <LinearLayout android:id="@+id/recents_glow"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginBottom="-49dip"
+            android:layout_marginBottom="0dp"
             android:layout_gravity="bottom"
             android:background="@drawable/recents_blue_glow"
             android:orientation="horizontal"
@@ -47,7 +47,7 @@
             <com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container"
                 android:layout_width="@dimen/status_bar_recents_width"
                 android:layout_height="wrap_content"
-                android:layout_marginRight="@dimen/status_bar_recents_right_glow_margin"
+                android:layout_marginRight="0dp"
                 android:divider="@null"
                 android:stackFromBottom="true"
                 android:fadingEdge="vertical"
diff --git a/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml b/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml
index df3c5a3..d29e495 100644
--- a/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml
+++ b/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml
@@ -27,51 +27,62 @@
         android:id="@+id/header"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginLeft="160dp"
+        android:layout_marginLeft="80dp"
         android:layout_marginTop="80dp"
+        android:layout_marginRight="80dp"
         android:textSize="60sp"
         android:maxLines="1"
         android:shadowRadius="8"
         android:shadowColor="#FF000000"
         android:text="@string/compat_mode_help_header"
+        android:background="@drawable/compat_mode_help_divider_top"
         />
     <ImageView
         android:id="@+id/diagram"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginLeft="160dp"
-        android:layout_marginTop="80dp"
         android:layout_centerInParent="true"
         android:src="@drawable/compat_mode_help_diagram"
         />
-    <TextView
-        android:id="@+id/explanation"
+    <RelativeLayout
+        android:orientation="horizontal"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="80dp"
-        android:layout_marginRight="240dp"
+        android:layout_height="190dp"
+        android:background="@drawable/compat_mode_help_divider_bottom"
+        android:layout_marginBottom="55dp"
+        android:layout_marginRight="80dp"
         android:layout_alignLeft="@id/header"
         android:layout_alignParentBottom="true"
-        android:shadowRadius="4"
-        android:shadowColor="#FF000000"
-        android:textSize="28sp"
-        android:text="@string/compat_mode_help_body"
-        />
-    <ImageView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginRight="80dp"
-        android:layout_alignBottom="@id/explanation"
-        android:layout_alignParentRight="true"
-        android:src="@drawable/compat_mode_help_icon"
-        />
+        >
+        <ImageView
+            android:id="@+id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
+            android:src="@drawable/compat_mode_help_icon"
+            />
+        <TextView
+            android:id="@+id/explanation"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
+            android:layout_alignParentLeft="true"
+            android:layout_toLeftOf="@id/icon"
+            android:layout_marginRight="10dp"
+            android:shadowRadius="4"
+            android:shadowColor="#FF000000"
+            android:textSize="28sp"
+            android:text="@string/compat_mode_help_body"
+            />
+    </RelativeLayout>
     <Button
         android:id="@+id/button"
         android:layout_width="208dp"
         android:layout_height="48dp"
         android:layout_alignLeft="@id/header"
         android:layout_alignParentBottom="true"
-        android:layout_marginBottom="10dp"
+        android:layout_marginBottom="20dp"
         android:textSize="28sp"
         android:text="@android:string/ok"
         />
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_compat_mode_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_compat_mode_panel.xml
index c151565..a33741e 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_compat_mode_panel.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_compat_mode_panel.xml
@@ -31,13 +31,13 @@
         android:orientation="vertical"
         android:padding="10dp"
         >
-        <RadioButton android:id="@+id/compat_mode_on_radio"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/compat_mode_on" />
         <RadioButton android:id="@+id/compat_mode_off_radio"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/compat_mode_off" />
+        <RadioButton android:id="@+id/compat_mode_on_radio"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/compat_mode_on" />
     </RadioGroup>
 </com.android.systemui.statusbar.tablet.CompatModePanel>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
index cd42d7e..9687866 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
@@ -36,53 +36,53 @@
     <ImageView android:id="@+id/app_icon"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginLeft="131dip"
-        android:layout_marginTop="13dip"
+        android:layout_alignLeft="@id/app_thumbnail"
+        android:layout_alignTop="@id/app_thumbnail"
+        android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
+        android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
         android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width"
         android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height"
         android:adjustViewBounds="true"
     />
 
-    <View android:id="@+id/recents_callout_line"
-        android:layout_width="97dip"
-        android:layout_height="1dip"
-        android:layout_alignParentTop="true"
-        android:layout_marginTop="61dip"
-        android:layout_alignParentLeft="true"
-        android:layout_marginLeft="16dip"
-        android:layout_toLeftOf="@id/app_thumbnail"
-        android:layout_marginRight="3dip"
-        android:background="@drawable/recents_callout_line"
-    />
-
     <TextView android:id="@+id/app_label"
-        android:layout_width="97dip"
+        android:layout_width="@dimen/status_bar_recents_app_label_width"
         android:layout_height="wrap_content"
-        android:textSize="@dimen/status_bar_recents_app_description_text_size"
+        android:textSize="@dimen/status_bar_recents_app_label_text_size"
         android:fadingEdge="horizontal"
         android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
         android:scrollHorizontally="true"
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
-        android:layout_marginLeft="16dip"
+        android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
         android:layout_marginTop="32dip"
         android:singleLine="true"
         android:ellipsize="marquee"
     />
 
+    <View android:id="@+id/recents_callout_line"
+        android:layout_width="@dimen/status_bar_recents_app_label_width"
+        android:layout_height="1dip"
+        android:layout_below="@id/app_label"
+        android:layout_marginTop="3dip"
+        android:layout_alignParentLeft="true"
+        android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
+        android:layout_toLeftOf="@id/app_thumbnail"
+        android:layout_marginRight="3dip"
+        android:background="@drawable/recents_callout_line"
+    />
+
     <TextView android:id="@+id/app_description"
-        android:layout_width="97dip"
+        android:layout_width="@dimen/status_bar_recents_app_label_width"
         android:layout_height="wrap_content"
         android:textSize="@dimen/status_bar_recents_app_description_text_size"
         android:fadingEdge="horizontal"
         android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
         android:scrollHorizontally="true"
         android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginLeft="16dip"
-        android:layout_marginTop="61dip"
+        android:layout_below="@id/recents_callout_line"
+        android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
+        android:layout_marginTop="3dip"
         android:singleLine="true"
         android:ellipsize="marquee"
     />
diff --git a/packages/SystemUI/res/layout/recent_apps_activity.xml b/packages/SystemUI/res/layout/recent_apps_activity.xml
deleted file mode 100644
index ec661e8..0000000
--- a/packages/SystemUI/res/layout/recent_apps_activity.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <!-- Title -->
-    <TextView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="#80FFFFFF"
-        android:textStyle="bold"
-        android:singleLine="true"
-        android:text="@string/recent_tasks_title"
-        android:visibility="gone"/>
-
-    <!-- This is only intended to be visible when carousel is invisible -->
-    <TextView
-        android:id="@+id/no_applications_message"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:text="@string/recent_tasks_empty"
-        android:visibility="gone"/>
-
-    <com.android.systemui.recent.RecentApplicationsCarouselView
-        android:id="@+id/carousel"
-        android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1">
-    </com.android.systemui.recent.RecentApplicationsCarouselView>
-
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/recents_detail_view.xml b/packages/SystemUI/res/layout/recents_detail_view.xml
deleted file mode 100644
index 879d0f2..0000000
--- a/packages/SystemUI/res/layout/recents_detail_view.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <!-- Application Title -->
-    <TextView android:id="@+id/app_title"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:singleLine="true"/>
-
-    <!-- Application Details -->
-    <TextView
-        android:id="@+id/app_description"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:textAppearance="?android:attr/textAppearanceSmall"/>
-
-</LinearLayout>
diff --git a/packages/SystemUI/res/values-hdpi/dimens.xml b/packages/SystemUI/res/values-hdpi/dimens.xml
new file mode 100644
index 0000000..741b75a
--- /dev/null
+++ b/packages/SystemUI/res/values-hdpi/dimens.xml
@@ -0,0 +1,24 @@
+<?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.
+*/
+-->
+<resources>
+    <!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg -->
+    <dimen name="recents_thumbnail_bg_padding_left">6px</dimen>
+    <dimen name="recents_thumbnail_bg_padding_top">7px</dimen>
+    <dimen name="recents_thumbnail_bg_padding_right">6px</dimen>
+    <dimen name="recents_thumbnail_bg_padding_bottom">6px</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 6f1453e..0219a77 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -23,15 +23,17 @@
     <!-- Width of a recent app view, including all content -->
     <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen>
     <!-- How far the thumbnail for a recent app appears from left edge -->
-    <dimen name="status_bar_recents_thumbnail_left_margin">0dp</dimen>
+    <dimen name="status_bar_recents_thumbnail_left_margin">8dp</dimen>
+    <!-- How far the thumbnail for a recent app appears from top edge -->
+    <dimen name="status_bar_recents_thumbnail_top_margin">12dp</dimen>
     <!-- Width of scrollable area in recents -->
     <dimen name="status_bar_recents_width">128dp</dimen>
-    <!-- Thumbnail border width -->
-    <dimen name="status_bar_recents_thumbnail_border_width">8dp</dimen>
-    <!-- Thumbnail border height -->
-    <dimen name="status_bar_recents_thumbnail_border_height">12dp</dimen>
     <!-- Padding for text descriptions -->
     <dimen name="status_bar_recents_text_description_padding">8dp</dimen>
+    <!-- Width of application label text -->
+    <dimen name="status_bar_recents_app_label_width">97dip</dimen>
+    <!-- Left margin of application label text -->
+    <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen>
     <!-- Margin between recents container and glow on the right -->
     <dimen name="status_bar_recents_right_glow_margin">0dip</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-large/dimens.xml b/packages/SystemUI/res/values-large/dimens.xml
index f8a4a1c..9d89e21 100644
--- a/packages/SystemUI/res/values-large/dimens.xml
+++ b/packages/SystemUI/res/values-large/dimens.xml
@@ -22,32 +22,6 @@
     <dimen name="status_bar_panel_bottom_offset">36dp</dimen>
     <!-- gap on either side of status bar notification icons -->
     <dimen name="status_bar_icon_padding">8dp</dimen>
-
-    <!-- Recent Applications parameters -->
-    <!-- Width of a recent app view, including all content -->
-    <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen>
-    <!-- How far the thumbnail for a recent app appears from left edge -->
-    <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen>
-    <!-- Upper width limit for application icon -->
-    <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen>
-    <!-- Upper height limit for application icon -->
-    <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen>
-    <!-- Width of scrollable area in recents -->
-    <dimen name="status_bar_recents_width">356dp</dimen>
-    <!-- Thumbnail border width -->
-    <dimen name="status_bar_recents_thumbnail_border_width">12dp</dimen>
-    <!-- Thumbnail border height -->
-    <dimen name="status_bar_recents_thumbnail_border_height">12dp</dimen>
-    <!-- Padding for text descriptions -->
-    <dimen name="status_bar_recents_text_description_padding">8dp</dimen>
-    <!-- Size of application label text -->
-    <dimen name="status_bar_recents_app_label_text_size">18dip</dimen>
-    <!-- Size of application description text -->
-    <dimen name="status_bar_recents_app_description_text_size">18dip</dimen>
-    <!-- Size of fading edge for scroll effect -->
-    <dimen name="status_bar_recents_fading_edge_length">20dip</dimen>
-    <!-- Margin between recents container and glow on the right -->
-    <dimen name="status_bar_recents_right_glow_margin">100dip</dimen>
 </resources>
 
 
diff --git a/packages/SystemUI/res/values-mdpi/dimens.xml b/packages/SystemUI/res/values-mdpi/dimens.xml
new file mode 100644
index 0000000..741b75a
--- /dev/null
+++ b/packages/SystemUI/res/values-mdpi/dimens.xml
@@ -0,0 +1,24 @@
+<?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.
+*/
+-->
+<resources>
+    <!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg -->
+    <dimen name="recents_thumbnail_bg_padding_left">6px</dimen>
+    <dimen name="recents_thumbnail_bg_padding_top">7px</dimen>
+    <dimen name="recents_thumbnail_bg_padding_right">6px</dimen>
+    <dimen name="recents_thumbnail_bg_padding_bottom">6px</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values-port/dimens.xml b/packages/SystemUI/res/values-port/dimens.xml
new file mode 100644
index 0000000..54c25fa
--- /dev/null
+++ b/packages/SystemUI/res/values-port/dimens.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2006, 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.
+*/
+-->
+<resources>
+    <!-- Recent Applications parameters -->
+    <!-- Width of a recent app view, including all content -->
+    <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen>
+    <!-- How far the thumbnail for a recent app appears from left edge -->
+    <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen>
+    <!-- Width of scrollable area in recents -->
+    <dimen name="status_bar_recents_width">356dp</dimen>
+    <!-- Padding for text descriptions -->
+    <dimen name="status_bar_recents_text_description_padding">8dp</dimen>
+    <!-- Width of application label text -->
+    <dimen name="status_bar_recents_app_label_width">97dip</dimen>
+    <!-- Left margin of application label text -->
+    <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen>
+    <!-- Margin between recents container and glow on the right -->
+    <dimen name="status_bar_recents_right_glow_margin">100dip</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 944e0ee..b4fd8ab 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -28,4 +28,40 @@
     <dimen name="notification_panel_min_height">770dp</dimen>
     <!-- Bottom margin (from display edge) for status bar panels -->
     <dimen name="panel_float">56dp</dimen>
+
+    <!-- Recent Applications parameters -->
+    <!-- Width of a recent app view, including all content -->
+    <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen>
+    <!-- How far the thumbnail for a recent app appears from left edge -->
+    <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen>
+    <!-- Upper width limit for application icon -->
+    <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen>
+    <!-- Upper height limit for application icon -->
+    <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen>
+    <!-- Width of scrollable area in recents -->
+    <dimen name="status_bar_recents_width">356dp</dimen>
+    <!-- Padding for text descriptions -->
+    <dimen name="status_bar_recents_text_description_padding">8dp</dimen>
+    <!-- Size of application label text -->
+    <dimen name="status_bar_recents_app_label_text_size">18dip</dimen>
+    <!-- Size of application description text -->
+    <dimen name="status_bar_recents_app_description_text_size">18dip</dimen>
+    <!-- Width of application label text -->
+    <dimen name="status_bar_recents_app_label_width">97dip</dimen>
+    <!-- Left margin for application label -->
+    <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen>
+    <!-- Size of fading edge for scroll effect -->
+    <dimen name="status_bar_recents_fading_edge_length">20dip</dimen>
+    <!-- Margin between recents container and glow on the right -->
+    <dimen name="status_bar_recents_right_glow_margin">100dip</dimen>
+
+    <!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg -->
+    <dimen name="recents_thumbnail_bg_padding_left">15px</dimen>
+    <dimen name="recents_thumbnail_bg_padding_top">8px</dimen>
+    <dimen name="recents_thumbnail_bg_padding_right">12px</dimen>
+    <dimen name="recents_thumbnail_bg_padding_bottom">8px</dimen>
+
+    <!-- Where to place the app icon over the thumbnail -->
+    <dimen name="status_bar_recents_app_icon_left_margin">13dp</dimen>
+    <dimen name="status_bar_recents_app_icon_top_margin">13dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 83eaaa8..fc35a48 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -20,22 +20,14 @@
     <dimen name="status_bar_edge_ignore">5dp</dimen>
 
     <!-- Recent Applications parameters -->
-    <!-- Width of a recent app view, including all content -->
-    <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen>
-    <!-- How far the thumbnail for a recent app appears from left edge -->
-    <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen>
     <!-- Upper width limit for application icon -->
     <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen>
     <!-- Upper height limit for application icon -->
     <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen>
-    <!-- Width of scrollable area in recents -->
-    <dimen name="status_bar_recents_width">356dp</dimen>
-    <!-- Thumbnail border width -->
-    <dimen name="status_bar_recents_thumbnail_border_width">12dp</dimen>
-    <!-- Thumbnail border height -->
-    <dimen name="status_bar_recents_thumbnail_border_height">12dp</dimen>
-    <!-- Padding for text descriptions -->
-    <dimen name="status_bar_recents_text_description_padding">8dp</dimen>
+    <!-- Where to place the app icon over the thumbnail -->
+    <dimen name="status_bar_recents_app_icon_left_margin">13dp</dimen>
+    <dimen name="status_bar_recents_app_icon_top_margin">13dp</dimen>
+
     <!-- Size of application label text -->
     <dimen name="status_bar_recents_app_label_text_size">18dip</dimen>
     <!-- Size of application description text -->
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
index b876075..49a65d8 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
@@ -36,14 +36,16 @@
     View mScrimView;
     View mContentView;
     AnimatorSet mContentAnim;
+    Animator.AnimatorListener mListener;
 
     // the panel will start to appear this many px from the end
     final int HYPERSPACE_OFFRAMP = 200;
 
-    public Choreographer(View root, View scrim, View content) {
+    public Choreographer(View root, View scrim, View content, Animator.AnimatorListener listener) {
         mRootView = root;
         mScrimView = scrim;
         mContentView = content;
+        mListener = listener;
     }
 
     void createAnimation(boolean appearing) {
@@ -86,6 +88,9 @@
                 .with(posAnim);
         mContentAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION);
         mContentAnim.addListener(this);
+        if (mListener != null) {
+            mContentAnim.addListener(mListener);
+        }
     }
 
     void startAnimation(boolean appearing) {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 194c9d1..3dbcc59 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.recent;
 
-import com.android.systemui.recent.RecentsPanelView.ActvityDescriptionAdapter;
+import com.android.systemui.recent.RecentsPanelView.ActivityDescriptionAdapter;
 
 import android.animation.Animator;
 import android.animation.Animator.AnimatorListener;
@@ -49,7 +49,7 @@
     private static final float THRESHHOLD = 50;
     private static final boolean DEBUG_INVALIDATE = false;
     private LinearLayout mLinearLayout;
-    private ActvityDescriptionAdapter mAdapter;
+    private ActivityDescriptionAdapter mAdapter;
     private RecentsCallback mCallback;
     protected int mLastScrollPosition;
     private View mCurrentView;
@@ -273,7 +273,7 @@
         }
     }
 
-    public void setAdapter(ActvityDescriptionAdapter adapter) {
+    public void setAdapter(ActivityDescriptionAdapter adapter) {
         mAdapter = adapter;
         mAdapter.registerDataSetObserver(new DataSetObserver() {
             public void onChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index e2b3446..b8dc63d 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -19,6 +19,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import android.animation.Animator;
 import android.animation.LayoutTransition;
 import android.app.ActivityManager;
 import android.content.Context;
@@ -52,27 +53,33 @@
 import android.widget.TextView;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.StatusBar;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
 import com.android.systemui.statusbar.tablet.StatusBarPanel;
 import com.android.systemui.statusbar.tablet.TabletStatusBar;
 
 public class RecentsPanelView extends RelativeLayout
-        implements OnItemClickListener, RecentsCallback, StatusBarPanel {
-    private static final int GLOW_PADDING = 15;
+        implements OnItemClickListener, RecentsCallback, StatusBarPanel, Animator.AnimatorListener {
     static final String TAG = "RecentsListView";
-    static final boolean DEBUG = TabletStatusBar.DEBUG;
+    static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG;
     private static final int DISPLAY_TASKS = 20;
     private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps
-    private TabletStatusBar mBar;
+    private StatusBar mBar;
     private ArrayList<ActivityDescription> mActivityDescriptions;
     private int mIconDpi;
     private View mRecentsScrim;
     private View mRecentsGlowView;
     private View mRecentsContainer;
     private Bitmap mGlowBitmap;
+    // TODO: add these widgets attributes to the layout file
+    private int mGlowBitmapPaddingLeftPx;
+    private int mGlowBitmapPaddingTopPx;
+    private int mGlowBitmapPaddingRightPx;
+    private int mGlowBitmapPaddingBottomPx;
     private boolean mShowing;
     private Choreographer mChoreo;
     private View mRecentsDismissButton;
-    private ActvityDescriptionAdapter mListAdapter;
+    private ActivityDescriptionAdapter mListAdapter;
 
     /* package */ final static class ActivityDescription {
         int taskId; // application task id for curating apps
@@ -108,10 +115,10 @@
         ActivityDescription activityDescription;
     }
 
-    /* package */ final class ActvityDescriptionAdapter extends BaseAdapter {
+    /* package */ final class ActivityDescriptionAdapter extends BaseAdapter {
         private LayoutInflater mInflater;
 
-        public ActvityDescriptionAdapter(Context context) {
+        public ActivityDescriptionAdapter(Context context) {
             mInflater = LayoutInflater.from(context);
         }
 
@@ -183,6 +190,26 @@
         }
     }
 
+    public void onAnimationCancel(Animator animation) {
+    }
+
+    public void onAnimationEnd(Animator animation) {
+        if (mShowing) {
+            final LayoutTransition transitioner = new LayoutTransition();
+            ((ViewGroup)mRecentsContainer).setLayoutTransition(transitioner);
+            createCustomAnimations(transitioner);
+        } else {
+            ((ViewGroup)mRecentsContainer).setLayoutTransition(null);
+        }
+    }
+
+    public void onAnimationRepeat(Animator animation) {
+    }
+
+    public void onAnimationStart(Animator animation) {
+    }
+
+
     /**
      * We need to be aligned at the bottom.  LinearLayout can't do this, so instead,
      * let LinearLayout do all the hard work, and then shift everything down to the bottom.
@@ -201,7 +228,7 @@
         return mShowing;
     }
 
-    public void setBar(TabletStatusBar bar) {
+    public void setBar(StatusBar bar) {
         mBar = bar;
     }
 
@@ -217,7 +244,16 @@
                 & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE;
 
         mIconDpi = xlarge ? DisplayMetrics.DENSITY_HIGH : res.getDisplayMetrics().densityDpi;
+
         mGlowBitmap = BitmapFactory.decodeResource(res, R.drawable.recents_thumbnail_bg);
+        mGlowBitmapPaddingLeftPx =
+                res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_left);
+        mGlowBitmapPaddingTopPx =
+                res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_top);
+        mGlowBitmapPaddingRightPx =
+                res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_right);
+        mGlowBitmapPaddingBottomPx =
+                res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_bottom);
     }
 
     @Override
@@ -225,7 +261,7 @@
         super.onFinishInflate();
         mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         mRecentsContainer = findViewById(R.id.recents_container);
-        mListAdapter = new ActvityDescriptionAdapter(mContext);
+        mListAdapter = new ActivityDescriptionAdapter(mContext);
         if (mRecentsContainer instanceof RecentsListView) {
             RecentsListView listView = (RecentsListView) mRecentsContainer;
             listView.setAdapter(mListAdapter);
@@ -246,13 +282,10 @@
             throw new IllegalArgumentException("missing RecentsListView/RecentsScrollView");
         }
 
-        final LayoutTransition transitioner = new LayoutTransition();
-        ((ViewGroup)mRecentsContainer).setLayoutTransition(transitioner);
-        createCustomAnimations(transitioner);
 
         mRecentsGlowView = findViewById(R.id.recents_glow);
         mRecentsScrim = (View) findViewById(R.id.recents_bg_protect);
-        mChoreo = new Choreographer(this, mRecentsScrim, mRecentsGlowView);
+        mChoreo = new Choreographer(this, mRecentsScrim, mRecentsGlowView, this);
         mRecentsDismissButton = findViewById(R.id.recents_dismiss_button);
         mRecentsDismissButton.setOnClickListener(new OnClickListener() {
             public void onClick(View v) {
@@ -402,10 +435,9 @@
             Log.v(TAG, "Source thumb: " + srcWidth + "x" + srcHeight);
             canvas.drawBitmap(thumbnail,
                     new Rect(0, 0, srcWidth-1, srcHeight-1),
-                    new RectF(GLOW_PADDING,
-                            GLOW_PADDING - 7.0f,
-                            outBitmap.getWidth() - GLOW_PADDING + 3.0f,
-                            outBitmap.getHeight() - GLOW_PADDING + 7.0f), paint);
+                    new RectF(mGlowBitmapPaddingLeftPx, mGlowBitmapPaddingTopPx,
+                            outBitmap.getWidth() - mGlowBitmapPaddingRightPx,
+                            outBitmap.getHeight() - mGlowBitmapPaddingBottomPx), paint);
         }
         return outBitmap;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 54ec6b5..6a962cb 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.recent;
 
-import com.android.systemui.recent.RecentsPanelView.ActvityDescriptionAdapter;
+import com.android.systemui.recent.RecentsPanelView.ActivityDescriptionAdapter;
 
 import android.animation.Animator;
 import android.animation.Animator.AnimatorListener;
@@ -49,7 +49,7 @@
     private static final float THRESHHOLD = 50;
     private static final boolean DEBUG_INVALIDATE = false;
     private LinearLayout mLinearLayout;
-    private ActvityDescriptionAdapter mAdapter;
+    private ActivityDescriptionAdapter mAdapter;
     private RecentsCallback mCallback;
     protected int mLastScrollPosition;
     private View mCurrentView;
@@ -275,7 +275,7 @@
         }
     }
 
-    public void setAdapter(ActvityDescriptionAdapter adapter) {
+    public void setAdapter(ActivityDescriptionAdapter adapter) {
         mAdapter = adapter;
         mAdapter.registerDataSetObserver(new DataSetObserver() {
             public void onChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsActivity.java
deleted file mode 100644
index 45e230f..0000000
--- a/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsActivity.java
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Copyright (C) 2010 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.systemui.recent.carousel;
-
-import com.android.systemui.R;
-
-import com.android.ex.carousel.CarouselView;
-import com.android.ex.carousel.CarouselViewHelper;
-import com.android.ex.carousel.CarouselRS.CarouselCallback;
-import com.android.ex.carousel.CarouselViewHelper.DetailTextureParameters;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
-import android.app.IThumbnailReceiver;
-import android.app.ActivityManager.RunningTaskInfo;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.PaintFlagsDrawFilter;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.PorterDuff;
-import android.graphics.Bitmap.Config;
-import android.graphics.drawable.Drawable;
-import android.graphics.PixelFormat;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.widget.TextView;
-
-public class RecentApplicationsActivity extends Activity {
-    private static final String TAG = "RecentApplicationsActivity";
-    private static boolean DBG = false;
-    private static final int CARD_SLOTS = 56;
-    private static final int VISIBLE_SLOTS = 7;
-    private static final int MAX_TASKS = VISIBLE_SLOTS * 2;
-
-    // TODO: these should be configurable
-    private static final int DETAIL_TEXTURE_MAX_WIDTH = 200;
-    private static final int DETAIL_TEXTURE_MAX_HEIGHT = 80;
-    private static final int TEXTURE_WIDTH = 256;
-    private static final int TEXTURE_HEIGHT = 256;
-
-    private ActivityManager mActivityManager;
-    private List<RunningTaskInfo> mRunningTaskList;
-    private boolean mPortraitMode = true;
-    private ArrayList<ActivityDescription> mActivityDescriptions
-            = new ArrayList<ActivityDescription>();
-    private CarouselView mCarouselView;
-    private LocalCarouselViewHelper mHelper;
-    private View mNoRecentsView;
-    private Bitmap mLoadingBitmap;
-    private Bitmap mRecentOverlay;
-    private boolean mHidden = false;
-    private boolean mHiding = false;
-    private DetailInfo mDetailInfo;
-
-    /**
-     * This class is a container for all items associated with the DetailView we'll
-     * be drawing to a bitmap and sending to Carousel.
-     *
-     */
-    static final class DetailInfo {
-        public DetailInfo(View _view, TextView _title, TextView _desc) {
-            view = _view;
-            title = _title;
-            description = _desc;
-        }
-
-        /**
-         * Draws view into the given bitmap, if provided
-         * @param bitmap
-         */
-        public Bitmap draw(Bitmap bitmap) {
-            resizeView(view, DETAIL_TEXTURE_MAX_WIDTH, DETAIL_TEXTURE_MAX_HEIGHT);
-            int desiredWidth = view.getWidth();
-            int desiredHeight = view.getHeight();
-            if (bitmap == null || desiredWidth != bitmap.getWidth()
-                    || desiredHeight != bitmap.getHeight()) {
-                bitmap = Bitmap.createBitmap(desiredWidth, desiredHeight, Config.ARGB_8888);
-            }
-            Canvas canvas = new Canvas(bitmap);
-            view.draw(canvas);
-            return bitmap;
-        }
-
-        /**
-         * Force a layout pass on the given view.
-         */
-        private void resizeView(View view, int maxWidth, int maxHeight) {
-            int widthSpec = MeasureSpec.getMode(MeasureSpec.AT_MOST)
-                    | MeasureSpec.getSize(maxWidth);
-            int heightSpec = MeasureSpec.getMode(MeasureSpec.AT_MOST)
-                    | MeasureSpec.getSize(maxHeight);
-            view.measure(widthSpec, heightSpec);
-            view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
-            Log.v(TAG, "RESIZED VIEW: " + view.getWidth() + ", " + view.getHeight());
-        }
-
-        public View view;
-        public TextView title;
-        public TextView description;
-    }
-
-    static class ActivityDescription {
-        int id;
-        Bitmap thumbnail; // generated by Activity.onCreateThumbnail()
-        Drawable icon; // application package icon
-        String label; // application package label
-        CharSequence description; // generated by Activity.onCreateDescription()
-        Intent intent; // launch intent for application
-        Matrix matrix; // arbitrary rotation matrix to correct orientation
-        int position; // position in list
-
-        public ActivityDescription(Bitmap _thumbnail,
-                Drawable _icon, String _label, String _desc, int _id, int _pos)
-        {
-            thumbnail = _thumbnail;
-            icon = _icon;
-            label = _label;
-            description = _desc;
-            id = _id;
-            position = _pos;
-        }
-
-        public void clear() {
-            icon = null;
-            thumbnail = null;
-            label = null;
-            description = null;
-            intent = null;
-            matrix = null;
-            id = -1;
-            position = -1;
-        }
-    };
-
-    private ActivityDescription findActivityDescription(int id) {
-        for (int i = 0; i < mActivityDescriptions.size(); i++) {
-            ActivityDescription item = mActivityDescriptions.get(i);
-            if (item != null && item.id == id) {
-                return item;
-            }
-        }
-        return null;
-    }
-
-    private class LocalCarouselViewHelper extends CarouselViewHelper {
-        private DetailTextureParameters mDetailParams = new DetailTextureParameters(10.0f, 20.0f);
-
-        public LocalCarouselViewHelper(Context context) {
-            super(context);
-        }
-
-        @Override
-        public DetailTextureParameters getDetailTextureParameters(int id) {
-            return mDetailParams;
-        }
-
-        public void onCardSelected(int n) {
-            if (n < mActivityDescriptions.size()) {
-                ActivityDescription item = mActivityDescriptions.get(n);
-                if (item.id >= 0) {
-                    // This is an active task; it should just go to the foreground.
-                    final ActivityManager am = (ActivityManager)
-                            getSystemService(Context.ACTIVITY_SERVICE);
-                    am.moveTaskToFront(item.id, ActivityManager.MOVE_TASK_WITH_HOME);
-                } else if (item.intent != null) {
-                    // prepare a launch intent and send it
-                    item.intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
-                            | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
-                    try {
-                        if (DBG) Log.v(TAG, "Starting intent " + item.intent);
-                        startActivity(item.intent);
-                        overridePendingTransition(R.anim.recent_app_enter, R.anim.recent_app_leave);
-                    } catch (ActivityNotFoundException e) {
-                        if (DBG) Log.w("Recent", "Unable to launch recent task", e);
-                    }
-                    finish();
-                }
-            }
-        }
-
-        @Override
-        public Bitmap getTexture(final int id) {
-            if (DBG) Log.v(TAG, "onRequestTexture(" + id + ")");
-            ActivityDescription info;
-            synchronized(mActivityDescriptions) {
-                info = mActivityDescriptions.get(id);
-            }
-            Bitmap bitmap = null;
-            if (info != null) {
-                bitmap = compositeBitmap(info);
-            }
-            return bitmap;
-        }
-
-        @Override
-        public Bitmap getDetailTexture(int n) {
-            Bitmap bitmap = null;
-            if (n < mActivityDescriptions.size()) {
-                ActivityDescription item = mActivityDescriptions.get(n);
-                mDetailInfo.title.setText(item.label);
-                mDetailInfo.description.setText(item.description);
-                bitmap = mDetailInfo.draw(null);
-            }
-            return bitmap;
-        }
-    };
-
-    private Bitmap compositeBitmap(ActivityDescription info) {
-        final int targetWidth = TEXTURE_WIDTH;
-        final int targetHeight = TEXTURE_HEIGHT;
-        final int border = 3; // inset along the edge for thumnnail content
-        final int overlap = 1; // how many pixels of overlap between border and thumbnail
-        final Resources res = getResources();
-        if (mRecentOverlay == null) {
-            mRecentOverlay = BitmapFactory.decodeResource(res, R.drawable.recent_overlay);
-        }
-
-        // Create a bitmap of the proper size/format and set the canvas to draw to it
-        final Bitmap result = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888);
-        final Canvas canvas = new Canvas(result);
-        canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, Paint.FILTER_BITMAP_FLAG));
-        Paint paint = new Paint();
-        paint.setFilterBitmap(false);
-
-        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
-        canvas.save();
-        if (info.thumbnail != null) {
-            // Draw the thumbnail
-            int sourceWidth = targetWidth - 2 * (border - overlap);
-            int sourceHeight = targetHeight - 2 * (border - overlap);
-            final float scaleX = (float) sourceWidth / info.thumbnail.getWidth();
-            final float scaleY = (float) sourceHeight / info.thumbnail.getHeight();
-            canvas.translate(border * 0.5f, border * 0.5f);
-            canvas.scale(scaleX, scaleY);
-            canvas.drawBitmap(info.thumbnail, 0, 0, paint);
-        } else {
-            // Draw the Loading bitmap placeholder, TODO: Remove when RS handles blending
-            final float scaleX = (float) targetWidth / mLoadingBitmap.getWidth();
-            final float scaleY = (float) targetHeight / mLoadingBitmap.getHeight();
-            canvas.scale(scaleX, scaleY);
-            canvas.drawBitmap(mLoadingBitmap, 0, 0, paint);
-        }
-        canvas.restore();
-
-        // Draw overlay
-        canvas.save();
-        final float scaleOverlayX = (float) targetWidth / mRecentOverlay.getWidth();
-        final float scaleOverlayY = (float) targetHeight / mRecentOverlay.getHeight();
-        canvas.scale(scaleOverlayX, scaleOverlayY);
-        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
-        canvas.drawBitmap(mRecentOverlay, 0, 0, paint);
-        canvas.restore();
-
-        // Draw icon
-        if (info.icon != null) {
-            canvas.save();
-            info.icon.draw(canvas);
-            canvas.restore();
-        }
-
-        return result;
-    }
-
-    private final IThumbnailReceiver mThumbnailReceiver = new IThumbnailReceiver.Stub() {
-
-        public void finished() throws RemoteException {
-
-        }
-
-        public void newThumbnail(final int id, final Bitmap bitmap, CharSequence description)
-                throws RemoteException {
-            int w = bitmap.getWidth();
-            int h = bitmap.getHeight();
-            if (DBG) Log.v(TAG, "New thumbnail for id=" + id + ", dimensions=" + w + "x" + h
-                    + " description '" + description + "'");
-            ActivityDescription info = findActivityDescription(id);
-            if (info != null) {
-                info.thumbnail = bitmap;
-                info.description = description;
-                final int thumbWidth = bitmap.getWidth();
-                final int thumbHeight = bitmap.getHeight();
-                if ((mPortraitMode && thumbWidth > thumbHeight)
-                        || (!mPortraitMode && thumbWidth < thumbHeight)) {
-                    Matrix matrix = new Matrix();
-                    matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2);
-                    info.matrix = matrix;
-                } else {
-                    info.matrix = null;
-                }
-                // Force Carousel to request new textures for this item.
-                mCarouselView.setTextureForItem(info.position, null);
-                mCarouselView.setDetailTextureForItem(info.position, 0, 0, 0, 0, null);
-            } else {
-                if (DBG) Log.v(TAG, "Can't find view for id " + id);
-            }
-        }
-    };
-
-    /**
-     * We never really finish() RecentApplicationsActivity, since we don't want to
-     * get destroyed and pay the start-up cost to restart it.
-     */
-    @Override
-    public void finish() {
-        moveTaskToBack(true);
-    }
-
-    @Override
-    protected void onNewIntent(Intent intent) {
-        mHidden = !mHidden;
-        if (mHidden) {
-            mHiding = true;
-            moveTaskToBack(true);
-        } else {
-            mHiding = false;
-        }
-        super.onNewIntent(intent);
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        final Resources res = getResources();
-        final View decorView = getWindow().getDecorView();
-
-        getWindow().getDecorView().setBackgroundColor(0x80000000);
-
-        if (mCarouselView == null) {
-            long t = System.currentTimeMillis();
-            setContentView(R.layout.recent_apps_activity);
-            long elapsed = System.currentTimeMillis() - t;
-            Log.v(TAG, "Recents layout took " + elapsed + "ms to load");
-            mLoadingBitmap = BitmapFactory.decodeResource(res, R.drawable.recent_rez_border);
-            mCarouselView = (CarouselView)findViewById(R.id.carousel);
-            mHelper = new LocalCarouselViewHelper(this);
-            mHelper.setCarouselView(mCarouselView);
-
-            mCarouselView.setSlotCount(CARD_SLOTS);
-            mCarouselView.setVisibleSlots(VISIBLE_SLOTS);
-            mCarouselView.createCards(0);
-            mCarouselView.setStartAngle((float) -(2.0f*Math.PI * 5 / CARD_SLOTS));
-            mCarouselView.setDefaultBitmap(mLoadingBitmap);
-            mCarouselView.setLoadingBitmap(mLoadingBitmap);
-            mCarouselView.setRezInCardCount(3.0f);
-            mCarouselView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
-
-            mNoRecentsView = (View) findViewById(R.id.no_applications_message);
-
-            mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
-            mPortraitMode = decorView.getHeight() > decorView.getWidth();
-
-            // Load detail view which will be used to render text
-            View detail = getLayoutInflater().inflate(R.layout.recents_detail_view, null);
-            TextView title = (TextView) detail.findViewById(R.id.app_title);
-            TextView description = (TextView) detail.findViewById(R.id.app_description);
-            mDetailInfo = new DetailInfo(detail, title, description);
-
-            refresh();
-        }
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        refresh();
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        mPortraitMode = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT;
-        if (DBG) Log.v(TAG, "CONFIG CHANGE, mPortraitMode = " + mPortraitMode);
-        refresh();
-    }
-
-    void updateRunningTasks() {
-        mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS,
-                0, mThumbnailReceiver);
-        if (DBG) Log.v(TAG, "Portrait: " + mPortraitMode);
-        for (RunningTaskInfo r : mRunningTaskList) {
-            if (r.thumbnail != null) {
-                int thumbWidth = r.thumbnail.getWidth();
-                int thumbHeight = r.thumbnail.getHeight();
-                if (DBG) Log.v(TAG, "Got thumbnail " + thumbWidth + "x" + thumbHeight);
-                ActivityDescription desc = findActivityDescription(r.id);
-                if (desc != null) {
-                    desc.thumbnail = r.thumbnail;
-                    desc.description = r.description;
-                    if ((mPortraitMode && thumbWidth > thumbHeight)
-                            || (!mPortraitMode && thumbWidth < thumbHeight)) {
-                        Matrix matrix = new Matrix();
-                        matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2);
-                        desc.matrix = matrix;
-                    }
-                } else {
-                    if (DBG) Log.v(TAG, "Couldn't find ActivityDesc for id=" + r.id);
-                }
-            } else {
-                if (DBG) Log.v(TAG, "*** RUNNING THUMBNAIL WAS NULL ***");
-            }
-        }
-    }
-
-    private void updateRecentTasks() {
-        final PackageManager pm = getPackageManager();
-        final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
-
-        final List<ActivityManager.RecentTaskInfo> recentTasks =
-                am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
-
-        ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
-                    .resolveActivityInfo(pm, 0);
-
-        // IconUtilities iconUtilities = new IconUtilities(this); // FIXME
-
-        int numTasks = recentTasks.size();
-        mActivityDescriptions.clear();
-        for (int i = 0, index = 0; i < numTasks && (index < MAX_TASKS); ++i) {
-            final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i);
-
-            Intent intent = new Intent(recentInfo.baseIntent);
-            if (recentInfo.origActivity != null) {
-                intent.setComponent(recentInfo.origActivity);
-            }
-
-            // Skip the current home activity.
-            if (homeInfo != null
-                    && homeInfo.packageName.equals(intent.getComponent().getPackageName())
-                    && homeInfo.name.equals(intent.getComponent().getClassName())) {
-                continue;
-            }
-
-            intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
-                    | Intent.FLAG_ACTIVITY_NEW_TASK);
-            final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
-            if (resolveInfo != null) {
-                final ActivityInfo info = resolveInfo.activityInfo;
-                final String title = info.loadLabel(pm).toString();
-                Drawable icon = info.loadIcon(pm);
-
-                int id = recentTasks.get(i).id;
-                if (id != -1 && title != null && title.length() > 0 && icon != null) {
-                    // icon = null; FIXME: iconUtilities.createIconDrawable(icon);
-                    ActivityDescription item = new ActivityDescription(
-                            null, icon, title, null, id, index);
-                    item.intent = intent;
-                    mActivityDescriptions.add(item);
-                    if (DBG) Log.v(TAG, "Added item[" + index
-                            + "], id=" + item.id
-                            + ", title=" + item.label);
-                    ++index;
-                } else {
-                    if (DBG) Log.v(TAG, "SKIPPING item " + id);
-                }
-            }
-        }
-    }
-
-    private final Runnable mRefreshRunnable = new Runnable() {
-        public void run() {
-            updateRecentTasks();
-            updateRunningTasks();
-            showCarousel(mActivityDescriptions.size() > 0);
-        }
-    };
-
-    private void showCarousel(boolean show) {
-        if (show) {
-            mCarouselView.createCards(mActivityDescriptions.size());
-            for (int i = 1; i < mActivityDescriptions.size(); i++) {
-                // Force Carousel to update textures. Note we don't do this for the first item,
-                // since it will be updated when mThumbnailReceiver returns a thumbnail.
-                // TODO: only do this for apps that have changed.
-                mCarouselView.setTextureForItem(i, null);
-                mCarouselView.setDetailTextureForItem(i, 0, 0, 0, 0, null);
-            }
-            // Make carousel visible
-            mNoRecentsView.setVisibility(View.GONE);
-            mCarouselView.setVisibility(View.VISIBLE);
-            mCarouselView.createCards(mActivityDescriptions.size());
-        } else {
-            // show "No Recent Tasks"
-            mNoRecentsView.setVisibility(View.VISIBLE);
-            mCarouselView.setVisibility(View.GONE);
-        }
-    }
-
-    private void refresh() {
-        if (!mHiding && mCarouselView != null) {
-            // Don't update the view now. Instead, post a request so it happens next time
-            // we reach the looper after a delay. This way we can fold multiple refreshes
-            // into just the latest.
-            mCarouselView.removeCallbacks(mRefreshRunnable);
-            mCarouselView.postDelayed(mRefreshRunnable, 50);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsCarouselView.java b/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsCarouselView.java
deleted file mode 100644
index 1afb086..0000000
--- a/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsCarouselView.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2010 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.systemui.recent.carousel;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import com.android.ex.carousel.CarouselView;
-import com.android.systemui.R;
-
-public class RecentApplicationsCarouselView extends CarouselView {
-
-    public RecentApplicationsCarouselView(Context context) {
-        this(context, null);
-    }
-
-    public RecentApplicationsCarouselView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public Info getRenderScriptInfo() {
-        return new Info(R.raw.carousel);
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index f81820e..62d7500 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -61,6 +61,7 @@
     private static final int MSG_SET_HARD_KEYBOARD_STATUS = 10 << MSG_SHIFT;
     
     private static final int MSG_USER_ACTIVITY          = 11 << MSG_SHIFT;
+    private static final int MSG_TOGGLE_RECENT_APPS       = 12 << MSG_SHIFT;
 
     private StatusBarIconList mList;
     private Callbacks mCallbacks;
@@ -90,6 +91,7 @@
         public void setImeWindowStatus(IBinder token, int vis, int backDisposition);
         public void setHardKeyboardStatus(boolean available, boolean enabled);
         public void userActivity();
+        public void toggleRecentApps();
     }
 
     public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -196,6 +198,13 @@
         }
     }
 
+    public void toggleRecentApps() {
+        synchronized (mList) {
+            mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS);
+            mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null).sendToTarget();
+        }
+    }
+
     private final class H extends Handler {
         public void handleMessage(Message msg) {
             final int what = msg.what & MSG_MASK;
@@ -265,6 +274,9 @@
                 case MSG_USER_ACTIVITY:
                     mCallbacks.userActivity();
                     break;
+                case MSG_TOGGLE_RECENT_APPS:
+                    mCallbacks.toggleRecentApps();
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
index e567dc7..ca75138 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
@@ -53,6 +53,7 @@
     protected abstract View makeStatusBarView();
     protected abstract int getStatusBarGravity();
     public abstract int getStatusBarHeight();
+    public abstract void animateCollapse();
 
     private DoNotDisturb mDoNotDisturb;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index cc8358e..0b82123 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -28,10 +28,12 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Resources;
+import android.content.res.Configuration;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.Handler;
@@ -74,6 +76,7 @@
 import com.android.internal.statusbar.StatusBarNotification;
 
 import com.android.systemui.R;
+import com.android.systemui.recent.RecentsPanelView;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.StatusBar;
 import com.android.systemui.statusbar.StatusBarIconView;
@@ -83,6 +86,7 @@
 public class PhoneStatusBar extends StatusBar {
     static final String TAG = "PhoneStatusBar";
     static final boolean SPEW = false;
+    public static final boolean DEBUG = false;
 
     public static final String ACTION_STATUSBAR_START
             = "com.android.internal.policy.statusbar.START";
@@ -94,6 +98,8 @@
     private static final int MSG_ANIMATE_REVEAL = 1001;
     private static final int MSG_SHOW_INTRUDER = 1002;
     private static final int MSG_HIDE_INTRUDER = 1003;
+    private static final int MSG_OPEN_RECENTS_PANEL = 1020;
+    private static final int MSG_CLOSE_RECENTS_PANEL = 1021;
 
     // will likely move to a resource or other tunable param at some point
     private static final int INTRUDER_ALERT_DECAY_MS = 10000;
@@ -160,6 +166,9 @@
     private View mTickerView;
     private boolean mTicking;
 
+    // Recent applications
+    private RecentsPanelView mRecentsPanel;
+
     // Tracking finger for opening/closing.
     int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
     boolean mTracking;
@@ -296,6 +305,9 @@
         setAreThereNotifications();
         mDateView.setVisibility(View.INVISIBLE);
 
+        // Recents Panel
+        initializeRecentsPanel();
+
         // receive broadcasts
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
@@ -306,6 +318,51 @@
         return sb;
     }
 
+    protected WindowManager.LayoutParams getRecentsLayoutParams() {
+        boolean translucent = false;
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT,
+                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
+                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
+                (translucent ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
+        lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
+        lp.setTitle("RecentsPanel");
+        lp.windowAnimations = R.style.Animation_RecentPanel;
+        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
+        | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
+        return lp;
+    }
+
+    protected void initializeRecentsPanel() {
+        // Recents Panel
+        boolean visible = false;
+        if (mRecentsPanel != null) {
+            visible = mRecentsPanel.getVisibility() == View.VISIBLE;
+            WindowManagerImpl.getDefault().removeView(mRecentsPanel);
+        }
+        mRecentsPanel = (RecentsPanelView) View.inflate(mContext,
+                R.layout.status_bar_recent_panel, null);
+
+        mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL,
+                mRecentsPanel));
+        mRecentsPanel.setVisibility(View.GONE);
+        WindowManager.LayoutParams lp = getRecentsLayoutParams();
+
+        WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
+        mRecentsPanel.setBar(this);
+        if (visible) {
+            // need to set visibility to View.GONE earlier since that
+            // triggers refreshing application list
+            mRecentsPanel.setVisibility(View.VISIBLE);
+            mRecentsPanel.show(true, false);
+        }
+
+    }
+
     protected int getStatusBarGravity() {
         return Gravity.TOP | Gravity.FILL_HORIZONTAL;
     }
@@ -581,6 +638,12 @@
         }
     }
 
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        initializeRecentsPanel();
+    }
+
+
     View[] makeNotificationView(StatusBarNotification notification, ViewGroup parent) {
         Notification n = notification.notification;
         RemoteViews remoteViews = n.contentView;
@@ -789,6 +852,21 @@
                 case MSG_HIDE_INTRUDER:
                     setIntruderAlertVisibility(false);
                     break;
+                case MSG_OPEN_RECENTS_PANEL:
+                    if (DEBUG) Slog.d(TAG, "opening recents panel");
+                    if (mRecentsPanel != null) {
+                        disable(StatusBarManager.DISABLE_BACK);
+                        mRecentsPanel.setVisibility(View.VISIBLE);
+                        mRecentsPanel.show(true, true);
+                    }
+                    break;
+                case MSG_CLOSE_RECENTS_PANEL:
+                    if (DEBUG) Slog.d(TAG, "closing recents panel");
+                    if (mRecentsPanel != null && mRecentsPanel.isShowing()) {
+                        disable(StatusBarManager.DISABLE_NONE);
+                        mRecentsPanel.show(false, true);
+                    }
+                    break;
             }
         }
     }
@@ -835,6 +913,10 @@
     }
 
     public void animateCollapse() {
+        animateCollapse(false);
+    }
+
+    public void animateCollapse(boolean excludeRecents) {
         if (SPEW) {
             Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded
                     + " mExpandedVisible=" + mExpandedVisible
@@ -844,6 +926,11 @@
                     + " mAnimVel=" + mAnimVel);
         }
 
+        if (!excludeRecents) {
+            mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
+            mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
+        }
+
         if (!mExpandedVisible) {
             return;
         }
@@ -1557,6 +1644,13 @@
         } catch (RemoteException ex) { }
     }
 
+    public void toggleRecentApps() {
+        int msg = (mRecentsPanel.getVisibility() == View.GONE)
+                ? MSG_OPEN_RECENTS_PANEL : MSG_CLOSE_RECENTS_PANEL;
+        mHandler.removeMessages(msg);
+        mHandler.sendEmptyMessage(msg);
+    }
+
     /**
      * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
      * This was added last-minute and is inconsistent with the way the rest of the notifications
@@ -1625,7 +1719,14 @@
             String action = intent.getAction();
             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
                     || Intent.ACTION_SCREEN_OFF.equals(action)) {
-                animateCollapse();
+                boolean excludeRecents = false;
+                if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
+                    String reason = intent.getExtras().getString("reason");
+                    if (reason != null) {
+                        excludeRecents = reason.equals("recentapps");
+                    }
+                }
+                animateCollapse(excludeRecents);
             }
             else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
                 repositionNavigationBar();
@@ -1690,5 +1791,27 @@
             vibrate();
         }
     };
+
+    public class TouchOutsideListener implements View.OnTouchListener {
+        private int mMsg;
+        private RecentsPanelView mPanel;
+
+        public TouchOutsideListener(int msg, RecentsPanelView panel) {
+            mMsg = msg;
+            mPanel = panel;
+        }
+
+        public boolean onTouch(View v, MotionEvent ev) {
+            final int action = ev.getAction();
+            if (action == MotionEvent.ACTION_OUTSIDE
+                || (action == MotionEvent.ACTION_DOWN
+                    && !mPanel.isInContentArea((int)ev.getX(), (int)ev.getY()))) {
+                mHandler.removeMessages(mMsg);
+                mHandler.sendEmptyMessage(mMsg);
+                return true;
+            }
+            return false;
+        }
+    }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index 24eee27..b5ea7b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -20,6 +20,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
+import android.animation.TimeAnimator;
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Resources;
@@ -30,6 +31,8 @@
 import android.util.AttributeSet;
 import android.util.Slog;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.AccelerateInterpolator;
@@ -45,10 +48,15 @@
 public class NotificationRowLayout extends ViewGroup {
     private static final String TAG = "NotificationRowLayout";
     private static final boolean DEBUG = false;
+    private static final boolean SLOW_ANIMATIONS = false; // DEBUG;
 
     private static final boolean ANIMATE_LAYOUT = true;
 
-    private static final int ANIM_LEN = DEBUG ? 5000 : 250;
+    private static final int APPEAR_ANIM_LEN = SLOW_ANIMATIONS ? 5000 : 250;
+    private static final int DISAPPEAR_ANIM_LEN = APPEAR_ANIM_LEN;
+    private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 250;
+
+    private static final float SWIPE_ESCAPE_VELOCITY = 1500f;
 
     Rect mTmpRect = new Rect();
     int mNumRows = 0;
@@ -58,6 +66,11 @@
     HashSet<View> mAppearingViews = new HashSet<View>();
     HashSet<View> mDisappearingViews = new HashSet<View>();
 
+    VelocityTracker mVT;
+    float mInitialTouchX, mInitialTouchY;
+    View mSlidingChild = null;
+    float mLiftoffVelocity;
+
     public NotificationRowLayout(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
@@ -65,6 +78,8 @@
     public NotificationRowLayout(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
+        mVT = VelocityTracker.obtain();
+
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NotificationRowLayout,
                 defStyle, 0);
         mRowHeight = a.getDimensionPixelSize(R.styleable.NotificationRowLayout_rowHeight, 0);
@@ -89,6 +104,92 @@
 
     }
 
+    // Swipey code
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        final int action = ev.getAction();
+//        if (DEBUG) Slog.d(TAG, "intercepting touch event: " + ev);
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mVT.clear();
+                mVT.addMovement(ev);
+                mInitialTouchX = ev.getX();
+                mInitialTouchY = ev.getY();
+                mSlidingChild = null;
+                break;
+            case MotionEvent.ACTION_MOVE:
+                mVT.addMovement(ev);
+                if (mSlidingChild == null) {
+                    if (Math.abs(ev.getX() - mInitialTouchX) > 4) { // slide slop
+
+                        // find the view under the pointer, accounting for GONE views
+                        final int count = getChildCount();
+                        int y = 0;
+                        int childIdx = 0;
+                        for (; childIdx < count; childIdx++) {
+                            mSlidingChild = getChildAt(childIdx);
+                            if (mSlidingChild.getVisibility() == GONE) {
+                                continue;
+                            }
+                            y += mRowHeight;
+                            if (mInitialTouchY < y) break;
+                        }
+
+                        mInitialTouchX -= mSlidingChild.getTranslationX();
+                        mSlidingChild.animate().cancel();
+
+                        if (DEBUG) {
+                            Slog.d(TAG, String.format(
+                                "now sliding child %d: %s (touchY=%.1f, rowHeight=%d, count=%d)",
+                                childIdx, mSlidingChild, mInitialTouchY, mRowHeight, count));
+                        }
+                    }
+                }
+                break;
+        }
+        return mSlidingChild != null;
+    }
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        final int action = ev.getAction();
+//        if (DEBUG) Slog.d(TAG, "touch event: " + ev + " sliding: " + mSlidingChild);
+        if (mSlidingChild != null) {
+            switch (action) {
+                case MotionEvent.ACTION_OUTSIDE:
+                case MotionEvent.ACTION_MOVE:
+                    mVT.addMovement(ev);
+
+                    mSlidingChild.setTranslationX(ev.getX() - mInitialTouchX);
+                    break;
+                case MotionEvent.ACTION_UP:
+                case MotionEvent.ACTION_CANCEL:
+                    mVT.addMovement(ev);
+                    mVT.computeCurrentVelocity(1000 /* px/sec */);
+                    if (DEBUG) Slog.d(TAG, "exit velocity: " + mVT.getXVelocity());
+                    boolean restore = true;
+                    mLiftoffVelocity = mVT.getXVelocity();
+                    if (Math.abs(mLiftoffVelocity) > SWIPE_ESCAPE_VELOCITY) {
+                        // flingadingy
+
+                        View veto = mSlidingChild.findViewById(R.id.veto);
+                        if (veto != null && veto.getVisibility() == View.VISIBLE) {
+                            veto.performClick();
+                            restore = false;
+                        }
+                    }
+                    if (restore) {
+                        // snappity
+                        mSlidingChild.animate().translationX(0)
+                            .setDuration(SNAP_ANIM_LEN)
+                            .start();
+                    }
+                    break;
+            }
+            return true;
+        }
+        return false;
+    }
+
     //**
     @Override
     public void addView(View child, int index, LayoutParams params) {
@@ -105,7 +206,7 @@
                     ObjectAnimator.ofFloat(child, "alpha", 0f, 1f)
 //                    ,ObjectAnimator.ofFloat(child, "scaleY", 0f, 1f)
             );
-            a.setDuration(ANIM_LEN);
+            a.setDuration(APPEAR_ANIM_LEN);
             a.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
@@ -127,21 +228,36 @@
             mDisappearingViews.add(child);
 
             child.setPivotY(0);
-            AnimatorSet a = new AnimatorSet();
-            a.playTogether(
-                    ObjectAnimator.ofFloat(child, "alpha", 0f)
-//                    ,ObjectAnimator.ofFloat(child, "scaleY", 0f)
-                    ,ObjectAnimator.ofFloat(child, "translationX", 300f)
-            );
-            a.setDuration(ANIM_LEN);
-            a.addListener(new AnimatorListenerAdapter() {
+
+            final float velocity = (mSlidingChild == child) 
+                    ? mLiftoffVelocity : SWIPE_ESCAPE_VELOCITY;
+            final TimeAnimator zoom = new TimeAnimator();
+            zoom.setTimeListener(new TimeAnimator.TimeListener() {
+                @Override
+                public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
+                    childF.setTranslationX(childF.getTranslationX() + deltaTime / 1000f * velocity);
+                }
+            });
+
+            final ObjectAnimator alphaFade = ObjectAnimator.ofFloat(child, "alpha", 0f);
+            alphaFade.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
+                    zoom.cancel(); // it won't end on its own
+                    if (DEBUG) Slog.d(TAG, "actually removing child: " + childF);
                     NotificationRowLayout.super.removeView(childF);
                     childF.setAlpha(1f);
                     mDisappearingViews.remove(childF);
                 }
             });
+
+            AnimatorSet a = new AnimatorSet();
+            a.playTogether(alphaFade, zoom);
+                    
+//                    ,ObjectAnimator.ofFloat(child, "scaleY", 0f)
+//                    ,ObjectAnimator.ofFloat(child, "translationX", child.getTranslationX() + 300f)
+
+            a.setDuration(DISAPPEAR_ANIM_LEN);
             a.start();
             requestLayout(); // start the container animation
         } else {
@@ -160,8 +276,8 @@
     public void onDraw(android.graphics.Canvas c) {
         super.onDraw(c);
         if (DEBUG) {
-            Slog.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
-                    + getMeasuredHeight() + "px");
+            //Slog.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
+            //        + getMeasuredHeight() + "px");
             c.save();
             c.clipRect(6, 6, c.getWidth() - 6, getMeasuredHeight() - 6,
                     android.graphics.Region.Op.DIFFERENCE);
@@ -199,7 +315,7 @@
 
             if (ANIMATE_LAYOUT && isShown()) {
                 ObjectAnimator.ofInt(this, "forcedHeight", computedHeight)
-                    .setDuration(ANIM_LEN)
+                    .setDuration(APPEAR_ANIM_LEN)
                     .start();
             } else {
                 setForcedHeight(computedHeight);
@@ -230,7 +346,7 @@
         final int width = right - left;
         final int height = bottom - top;
 
-        if (DEBUG) Slog.d(TAG, "onLayout: height=" + height);
+        //if (DEBUG) Slog.d(TAG, "onLayout: height=" + height);
 
         final int count = getChildCount();
         int y = 0;
@@ -252,7 +368,7 @@
     }
 
     public void setForcedHeight(int h) {
-        if (DEBUG) Slog.d(TAG, "forcedHeight: " + h);
+        //if (DEBUG) Slog.d(TAG, "forcedHeight: " + h);
         if (h != mHeight) {
             mHeight = h;
             requestLayout();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java
index 5a82d1b..c62c4ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java
@@ -107,9 +107,14 @@
 
     private void refresh() {
         int mode = mAM.getFrontActivityScreenCompatMode();
+        if (mode == ActivityManager.COMPAT_MODE_ALWAYS
+                || mode == ActivityManager.COMPAT_MODE_NEVER) {
+            // No longer have something to switch.
+            closePanel();
+            return;
+        }
         final boolean on = (mode == ActivityManager.COMPAT_MODE_ENABLED);
         mOnButton.setChecked(on);
         mOffButton.setChecked(!on);
     }
-
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index a7af30d..93f7af3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -76,12 +76,12 @@
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.Prefs;
 import com.android.systemui.recent.RecentsPanelView;
-import com.android.systemui.recent.carousel.RecentApplicationsActivity;
 
 public class TabletStatusBar extends StatusBar implements
         HeightReceiver.OnBarHeightChangedListener,
         InputMethodsPanel.OnHardKeyboardEnabledChangeListener {
     public static final boolean DEBUG = false;
+    public static final boolean DEBUG_COMPAT_HELP = false;
     public static final String TAG = "TabletStatusBar";
 
 
@@ -166,6 +166,8 @@
     View mFakeSpaceBar;
     KeyEvent mSpaceBarKeyEvent = null;
 
+    View mCompatibilityHelpDialog = null;
+    
     // for disabling the status bar
     int mDisabled = 0;
 
@@ -1010,20 +1012,31 @@
 
         mCompatModeButton.refresh();
         if (mCompatModeButton.getVisibility() == View.VISIBLE) {
-            if (! Prefs.read(mContext).getBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, false)) {
+            if (DEBUG_COMPAT_HELP
+                    || ! Prefs.read(mContext).getBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, false)) {
                 showCompatibilityHelp();
             }
+        } else {
+            hideCompatibilityHelp();
+            mCompatModePanel.closePanel();
         }
     }
 
     private void showCompatibilityHelp() {
-        final View dlg = View.inflate(mContext, R.layout.compat_mode_help, null);
-        View button = dlg.findViewById(R.id.button);
+        if (mCompatibilityHelpDialog != null) {
+            return;
+        }
+        
+        mCompatibilityHelpDialog = View.inflate(mContext, R.layout.compat_mode_help, null);
+        View button = mCompatibilityHelpDialog.findViewById(R.id.button);
 
         button.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                WindowManagerImpl.getDefault().removeView(dlg);
+                hideCompatibilityHelp();
+                SharedPreferences.Editor editor = Prefs.edit(mContext);
+                editor.putBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, true);
+                editor.apply();
             }
         });
 
@@ -1040,13 +1053,16 @@
                 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
         lp.windowAnimations = com.android.internal.R.style.Animation_ZoomButtons; // simple fade
 
-        WindowManagerImpl.getDefault().addView(dlg, lp);
-
-        SharedPreferences.Editor editor = Prefs.edit(mContext);
-        editor.putBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, true);
-        editor.apply();
+        WindowManagerImpl.getDefault().addView(mCompatibilityHelpDialog, lp);
     }
 
+    private void hideCompatibilityHelp() {
+        if (mCompatibilityHelpDialog != null) {
+            WindowManagerImpl.getDefault().removeView(mCompatibilityHelpDialog);
+            mCompatibilityHelpDialog = null;
+        }
+    }
+    
     public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
         mInputMethodSwitchButton.setImeWindowStatus(token,
                 (vis & InputMethodService.IME_ACTIVE) != 0);
@@ -1156,20 +1172,12 @@
 
     public void onClickRecentButton() {
         if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
-        if (mRecentsPanel == null) {
-            Intent intent = new Intent();
-            intent.setClass(mContext, RecentApplicationsActivity.class);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-            mContext.startActivity(intent);
-        } else {
-            if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
-                int msg = (mRecentsPanel.getVisibility() == View.GONE)
-                    ? MSG_OPEN_RECENTS_PANEL
-                    : MSG_CLOSE_RECENTS_PANEL;
-                mHandler.removeMessages(msg);
-                mHandler.sendEmptyMessage(msg);
-            }
+        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
+            int msg = (mRecentsPanel.getVisibility() == View.GONE)
+                ? MSG_OPEN_RECENTS_PANEL
+                : MSG_CLOSE_RECENTS_PANEL;
+            mHandler.removeMessages(msg);
+            mHandler.sendEmptyMessage(msg);
         }
     }
 
@@ -1681,6 +1689,13 @@
     public void userActivity() {
     }
 
+    public void toggleRecentApps() {
+        int msg = (mRecentsPanel.getVisibility() == View.GONE)
+                ? MSG_OPEN_RECENTS_PANEL : MSG_CLOSE_RECENTS_PANEL;
+        mHandler.removeMessages(msg);
+        mHandler.sendEmptyMessage(msg);
+    }
+
     public class TouchOutsideListener implements View.OnTouchListener {
         private int mMsg;
         private StatusBarPanel mPanel;
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
index 8fa6c7a..c54e719 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
@@ -23,7 +23,8 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
+import android.net.IConnectivityManager;
+import android.os.ServiceManager;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
@@ -37,7 +38,7 @@
 
     private String mPackageName;
 
-    private ConnectivityManager mService;
+    private IConnectivityManager mService;
 
     private AlertDialog mDialog;
     private Button mButton;
@@ -47,7 +48,9 @@
         super.onResume();
         try {
             mPackageName = getCallingPackage();
-            mService = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+
+            mService = IConnectivityManager.Stub.asInterface(
+                    ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
 
             if (mPackageName.equals(mService.prepareVpn(null))) {
                 setResult(RESULT_OK);
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index 853e625..f1da49d 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -23,9 +23,10 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
+import android.net.IConnectivityManager;
 import android.os.Handler;
 import android.os.Message;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.util.Log;
 import android.view.View;
@@ -45,7 +46,7 @@
     private String mInterfaceName;
     private long mStartTime;
 
-    private ConnectivityManager mService;
+    private IConnectivityManager mService;
 
     private AlertDialog mDialog;
     private TextView mDuration;
@@ -64,7 +65,8 @@
             mInterfaceName = intent.getStringExtra("interfaceName");
             mStartTime = intent.getLongExtra("startTime", 0);
 
-            mService = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+            mService = IConnectivityManager.Stub.asInterface(
+                    ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
 
             PackageManager pm = getPackageManager();
             ApplicationInfo app = pm.getApplicationInfo(mPackageName, 0);
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 72209f6..f385a23 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -114,7 +114,15 @@
             }
             String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
             if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
-                this.simState = IccCard.State.ABSENT;
+                final String absentReason = intent
+                    .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
+
+                if (IccCard.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
+                        absentReason)) {
+                    this.simState = IccCard.State.PERM_DISABLED;
+                } else {
+                    this.simState = IccCard.State.ABSENT;
+                }
             } else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
                 this.simState = IccCard.State.READY;
             } else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 8a60098..8ba235b 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -580,7 +580,9 @@
             final boolean provisioned = mUpdateMonitor.isDeviceProvisioned();
             final IccCard.State state = mUpdateMonitor.getSimState();
             final boolean lockedOrMissing = state.isPinLocked()
-                    || ((state == IccCard.State.ABSENT) && requireSim);
+                    || ((state == IccCard.State.ABSENT
+                            || state == IccCard.State.PERM_DISABLED)
+                            && requireSim);
 
             if (!lockedOrMissing && !provisioned) {
                 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
@@ -687,12 +689,15 @@
 
         switch (simState) {
             case ABSENT:
+            case PERM_DISABLED:
                 // only force lock screen in case of missing sim if user hasn't
                 // gone through setup wizard
                 if (!mUpdateMonitor.isDeviceProvisioned()) {
                     if (!isShowing()) {
-                        if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_ABSENT and keygaurd isn't showing, we need "
-                             + "to show the keyguard since the device isn't provisioned yet.");
+                        if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_ABSENT "
+                                + "or PERM_DISABLED and keygaurd isn't showing,"
+                                + " we need to show the keyguard since the "
+                                + "device isn't provisioned yet.");
                         doKeyguard();
                     } else {
                         resetStateLocked();
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 874acd0..eea30407 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -181,7 +181,8 @@
     private boolean stuckOnLockScreenBecauseSimMissing() {
         return mRequiresSim
                 && (!mUpdateMonitor.isDeviceProvisioned())
-                && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT);
+                && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT ||
+                    mUpdateMonitor.getSimState() == IccCard.State.PERM_DISABLED);
     }
 
     /**
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
index ed5a058..19adb3e 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
@@ -55,8 +55,10 @@
 
     private boolean isSimPinSecure() {
         final IccCard.State simState = mUpdateMonitor.getSimState();
-        return (simState == IccCard.State.PIN_REQUIRED || simState == IccCard.State.PUK_REQUIRED
-            || simState == IccCard.State.ABSENT);
+        return (simState == IccCard.State.PIN_REQUIRED
+                || simState == IccCard.State.PUK_REQUIRED
+                || simState == IccCard.State.ABSENT
+                || simState == IccCard.State.PERM_DISABLED);
     }
 
 }
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 08f9ebb..8b7a61e 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -129,7 +129,12 @@
         /**
          * The sim card is locked.
          */
-        SimLocked(true);
+        SimLocked(true),
+
+        /**
+         * The sim card is permanently disabled due to puk unlock failure
+         */
+        SimPermDisabled(false);
 
         private final boolean mShowStatusLines;
 
@@ -503,7 +508,9 @@
      */
     private Status getCurrentStatus(IccCard.State simState) {
         boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned()
-                && simState == IccCard.State.ABSENT);
+                && (simState == IccCard.State.ABSENT
+                        || simState == IccCard.State.PERM_DISABLED));
+
         if (missingAndNotProvisioned) {
             return Status.SimMissingLocked;
         }
@@ -521,6 +528,8 @@
                 return Status.SimPukLocked;
             case READY:
                 return Status.Normal;
+            case PERM_DISABLED:
+                return Status.SimPermDisabled;
             case UNKNOWN:
                 return Status.SimMissing;
         }
@@ -595,6 +604,18 @@
                 enableUnlock(); // do not need to show the e-call button; user may unlock
                 break;
 
+            case SimPermDisabled:
+                // text
+                mStatusView.setCarrierText(R.string.lockscreen_missing_sim_message_short);
+                mScreenLocked.setText(
+                        R.string.lockscreen_permanent_disabled_sim_instructions);
+
+                // layout
+                mScreenLocked.setVisibility(View.VISIBLE);
+                mLockPatternUtils.updateEmergencyCallText(mEmergencyCallText);
+                enableUnlock(); // do not need to show the e-call button; user may unlock
+                break;
+
             case SimMissingLocked:
                 // text
                 mStatusView.setCarrierText(
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 5728989..b52e7e1 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -149,10 +149,12 @@
     static final int LONG_PRESS_POWER_NOTHING = 0;
     static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
     static final int LONG_PRESS_POWER_SHUT_OFF = 2;
-    
+
+    // These need to match the documentation/constant in
+    // core/res/res/values/config.xml
     static final int LONG_PRESS_HOME_NOTHING = 0;
     static final int LONG_PRESS_HOME_RECENT_DIALOG = 1;
-    static final int LONG_PRESS_HOME_RECENT_ACTIVITY = 2;
+    static final int LONG_PRESS_HOME_RECENT_SYSTEM_UI = 2;
 
     // wallpaper is at the bottom, though the window manager may move it.
     static final int WALLPAPER_LAYER = 2;
@@ -623,7 +625,7 @@
             mLongPressOnHomeBehavior
                     = mContext.getResources().getInteger(R.integer.config_longPressOnHomeBehavior);
             if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING ||
-                    mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_ACTIVITY) {
+                    mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
                 mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
             }
         }
@@ -639,17 +641,11 @@
 
         if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
             showOrHideRecentAppsDialog(0, true /*dismissIfShown*/);
-        } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_ACTIVITY) {
+        } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
             try {
-                Intent intent = new Intent();
-                intent.setClassName("com.android.systemui", 
-                        "com.android.systemui.recent.RecentApplicationsActivity");
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 
-                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-                mContext.startActivity(intent);
-                return;
-            } catch (ActivityNotFoundException e) {
-                Log.e(TAG, "Failed to launch RecentAppsIntent", e);
+                mStatusBarService.toggleRecentApps();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "RemoteException when showing recent apps", e);
             }
         }
     }
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 1e8c30b..a011ae2 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -147,6 +147,14 @@
         return NULL;
     }
 
+    char value[PROPERTY_VALUE_MAX];
+    property_get("sys.secpolicy.camera.disabled", value, "0");
+    if (strcmp(value, "1") == 0) {
+        // Camera is disabled by DevicePolicyManager.
+        LOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
+        return NULL;
+    }
+
     Mutex::Autolock lock(mServiceLock);
     if (mClient[cameraId] != 0) {
         client = mClient[cameraId].promote();
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index fd502d8..158c778 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -395,41 +395,47 @@
     public void bindAppWidgetId(int appWidgetId, ComponentName provider) {
         mContext.enforceCallingPermission(android.Manifest.permission.BIND_APPWIDGET,
                 "bindGagetId appWidgetId=" + appWidgetId + " provider=" + provider);
-        synchronized (mAppWidgetIds) {
-            AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
-            if (id == null) {
-                throw new IllegalArgumentException("bad appWidgetId");
+        
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (mAppWidgetIds) {
+                AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
+                if (id == null) {
+                    throw new IllegalArgumentException("bad appWidgetId");
+                }
+                if (id.provider != null) {
+                    throw new IllegalArgumentException("appWidgetId " + appWidgetId + " already bound to "
+                            + id.provider.info.provider);
+                }
+                Provider p = lookupProviderLocked(provider);
+                if (p == null) {
+                    throw new IllegalArgumentException("not a appwidget provider: " + provider);
+                }
+                if (p.zombie) {
+                    throw new IllegalArgumentException("can't bind to a 3rd party provider in"
+                            + " safe mode: " + provider);
+                }
+    
+                id.provider = p;
+                p.instances.add(id);
+                int instancesSize = p.instances.size();
+                if (instancesSize == 1) {
+                    // tell the provider that it's ready
+                    sendEnableIntentLocked(p);
+                }
+    
+                // send an update now -- We need this update now, and just for this appWidgetId.
+                // It's less critical when the next one happens, so when we schdule the next one,
+                // we add updatePeriodMillis to its start time.  That time will have some slop,
+                // but that's okay.
+                sendUpdateIntentLocked(p, new int[] { appWidgetId });
+    
+                // schedule the future updates
+                registerForBroadcastsLocked(p, getAppWidgetIds(p));
+                saveStateLocked();
             }
-            if (id.provider != null) {
-                throw new IllegalArgumentException("appWidgetId " + appWidgetId + " already bound to "
-                        + id.provider.info.provider);
-            }
-            Provider p = lookupProviderLocked(provider);
-            if (p == null) {
-                throw new IllegalArgumentException("not a appwidget provider: " + provider);
-            }
-            if (p.zombie) {
-                throw new IllegalArgumentException("can't bind to a 3rd party provider in"
-                        + " safe mode: " + provider);
-            }
-
-            id.provider = p;
-            p.instances.add(id);
-            int instancesSize = p.instances.size();
-            if (instancesSize == 1) {
-                // tell the provider that it's ready
-                sendEnableIntentLocked(p);
-            }
-
-            // send an update now -- We need this update now, and just for this appWidgetId.
-            // It's less critical when the next one happens, so when we schdule the next one,
-            // we add updatePeriodMillis to its start time.  That time will have some slop,
-            // but that's okay.
-            sendUpdateIntentLocked(p, new int[] { appWidgetId });
-
-            // schedule the future updates
-            registerForBroadcastsLocked(p, getAppWidgetIds(p));
-            saveStateLocked();
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index c6f4c20..383842d 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -48,7 +48,6 @@
 import android.net.vpn.VpnManager;
 import android.net.wifi.WifiStateTracker;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.FileUtils;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -67,6 +66,7 @@
 import android.util.Slog;
 import android.util.SparseIntArray;
 
+import com.android.internal.net.VpnConfig;
 import com.android.internal.telephony.Phone;
 import com.android.server.connectivity.Tethering;
 import com.android.server.connectivity.Vpn;
@@ -1267,8 +1267,30 @@
             }
         }
         intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
+
+        // Reset interface if no other connections are using the same interface
+        boolean doReset = true;
+        LinkProperties linkProperties = mNetTrackers[prevNetType].getLinkProperties();
+        if (linkProperties != null) {
+            String oldIface = linkProperties.getInterfaceName();
+            if (TextUtils.isEmpty(oldIface) == false) {
+                for (NetworkStateTracker networkStateTracker : mNetTrackers) {
+                    if (networkStateTracker == null) continue;
+                    NetworkInfo networkInfo = networkStateTracker.getNetworkInfo();
+                    if (networkInfo.isConnected() && networkInfo.getType() != prevNetType) {
+                        LinkProperties l = networkStateTracker.getLinkProperties();
+                        if (l == null) continue;
+                        if (oldIface.equals(l.getInterfaceName())) {
+                            doReset = false;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
         // do this before we broadcast the change
-        handleConnectivityChange(prevNetType);
+        handleConnectivityChange(prevNetType, doReset);
 
         sendStickyBroadcast(intent);
         /*
@@ -1490,7 +1512,7 @@
         }
         thisNet.setTeardownRequested(false);
         updateNetworkSettings(thisNet);
-        handleConnectivityChange(type);
+        handleConnectivityChange(type, false);
         sendConnectedBroadcast(info);
     }
 
@@ -1500,7 +1522,7 @@
      * according to which networks are connected, and ensuring that the
      * right routing table entries exist.
      */
-    private void handleConnectivityChange(int netType) {
+    private void handleConnectivityChange(int netType, boolean doReset) {
         /*
          * If a non-default network is enabled, add the host routes that
          * will allow it's DNS servers to be accessed.
@@ -1540,6 +1562,17 @@
                 removePrivateDnsRoutes(mNetTrackers[netType]);
             }
         }
+
+        if (doReset) {
+            LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties();
+            if (linkProperties != null) {
+                String iface = linkProperties.getInterfaceName();
+                if (TextUtils.isEmpty(iface) == false) {
+                    if (DBG) log("resetConnections(" + iface + ")");
+                    NetworkUtils.resetConnections(iface);
+                }
+            }
+        }
     }
 
     private void addPrivateDnsRoutes(NetworkStateTracker nt) {
@@ -1965,7 +1998,7 @@
                     break;
                 case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED:
                     info = (NetworkInfo) msg.obj;
-                    handleConnectivityChange(info.getType());
+                    handleConnectivityChange(info.getType(), true);
                     break;
                 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK:
                     String causedBy = null;
@@ -2396,24 +2429,37 @@
         return value;
     }
 
-    // @see ConnectivityManager#protectVpn(ParcelFileDescriptor)
-    // Permission checks are done in Vpn class.
+    /**
+     * Protect a socket from VPN routing rules. This method is used by
+     * VpnBuilder and not available in ConnectivityManager. Permission
+     * checks are done in Vpn class.
+     * @hide
+     */
     @Override
     public void protectVpn(ParcelFileDescriptor socket) {
         mVpn.protect(socket, getDefaultInterface());
     }
 
-    // @see ConnectivityManager#prepareVpn(String)
-    // Permission checks are done in Vpn class.
+    /**
+     * Prepare for a VPN application. This method is used by VpnDialogs
+     * and not available in ConnectivityManager. Permission checks are
+     * done in Vpn class.
+     * @hide
+     */
     @Override
     public String prepareVpn(String packageName) {
         return mVpn.prepare(packageName);
     }
 
-    // @see ConnectivityManager#establishVpn(Bundle)
-    // Permission checks are done in Vpn class.
+    /**
+     * Configure a TUN interface and return its file descriptor. Parameters
+     * are encoded and opaque to this class. This method is used by VpnBuilder
+     * and not available in ConnectivityManager. Permission checks are done
+     * in Vpn class.
+     * @hide
+     */
     @Override
-    public ParcelFileDescriptor establishVpn(Bundle config) {
+    public ParcelFileDescriptor establishVpn(VpnConfig config) {
         return mVpn.establish(config);
     }
 
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index b1bce50..286a937 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -345,6 +345,15 @@
         });
     }
 
+    @Override
+    public void toggleRecentApps() {
+        if (mBar != null) {
+            try {
+                mBar.toggleRecentApps();
+            } catch (RemoteException ex) {}
+        }
+    }
+
     private void enforceStatusBar() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR,
                 "StatusBarManagerService");
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index ab85b14..372ba85 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -29,12 +29,12 @@
 import android.graphics.drawable.Drawable;
 import android.net.INetworkManagementEventObserver;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.util.Log;
 
 import com.android.internal.R;
+import com.android.internal.net.VpnConfig;
 import com.android.server.ConnectivityService.VpnCallback;
 
 /**
@@ -108,7 +108,7 @@
      * @param configuration The parameters to configure the interface.
      * @return The file descriptor of the interface.
      */
-    public synchronized ParcelFileDescriptor establish(Bundle config) {
+    public synchronized ParcelFileDescriptor establish(VpnConfig config) {
         // Check the permission of the caller.
         mContext.enforceCallingPermission(VPN, "establish");
 
@@ -124,17 +124,9 @@
             throw new SecurityException("Not prepared");
         }
 
-        // Unpack the config.
-        // TODO: move constants into VpnBuilder.
-        int mtu = config.getInt("mtu", -1);
-        String session = config.getString("session");
-        String addresses = config.getString("addresses");
-        String routes = config.getString("routes");
-        String dnsServers = config.getString("dnsServers");
-
         // Create and configure the interface.
-        ParcelFileDescriptor descriptor =
-                ParcelFileDescriptor.adoptFd(nativeEstablish(mtu, addresses, routes));
+        ParcelFileDescriptor descriptor = ParcelFileDescriptor.adoptFd(
+                nativeEstablish(config.mtu, config.addresses, config.routes));
 
         // Replace the interface and abort if it fails.
         try {
@@ -153,22 +145,13 @@
             throw e;
         }
 
-        dnsServers = (dnsServers == null) ? "" : dnsServers.trim();
+        String dnsServers = (config.dnsServers == null) ? "" : config.dnsServers.trim();
         mCallback.override(dnsServers.isEmpty() ? null : dnsServers.split(" "));
 
-        showNotification(pm, app, session);
+        showNotification(pm, app, config.sessionName);
         return descriptor;
     }
 
-    public synchronized boolean onInterfaceRemoved(String name) {
-        if (name.equals(mInterfaceName) && nativeCheck(name) == 0) {
-            hideNotification();
-            mInterfaceName = null;
-            return true;
-        }
-        return false;
-    }
-
     // INetworkManagementEventObserver.Stub
     public void interfaceLinkStatusChanged(String name, boolean up) {
     }
@@ -186,7 +169,7 @@
         }
     }
 
-    private void showNotification(PackageManager pm, ApplicationInfo app, String session) {
+    private void showNotification(PackageManager pm, ApplicationInfo app, String sessionName) {
         NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
 
@@ -207,11 +190,6 @@
             // Load the label.
             String label = app.loadLabel(pm).toString();
 
-            // If session is null, use the application name instead.
-            if (session == null) {
-                session = label;
-            }
-
             // Build the intent.
             // TODO: move these into VpnBuilder.
             Intent intent = new Intent();
@@ -219,23 +197,24 @@
                     "com.android.vpndialogs.ManageDialog");
             intent.putExtra("packageName", mPackageName);
             intent.putExtra("interfaceName", mInterfaceName);
-            intent.putExtra("session", session);
+            intent.putExtra("session", sessionName);
             intent.putExtra("startTime", android.os.SystemClock.elapsedRealtime());
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
 
             // Build the notification.
+            String text = (sessionName == null) ? mContext.getString(R.string.vpn_text) :
+                    mContext.getString(R.string.vpn_text_long, sessionName);
             long identity = Binder.clearCallingIdentity();
             Notification notification = new Notification.Builder(mContext)
                     .setSmallIcon(R.drawable.vpn_connected)
                     .setLargeIcon(bitmap)
                     .setTicker(mContext.getString(R.string.vpn_ticker, label))
                     .setContentTitle(mContext.getString(R.string.vpn_title, label))
-                    .setContentText(mContext.getString(R.string.vpn_text, session))
+                    .setContentText(text)
                     .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0))
                     .setDefaults(Notification.DEFAULT_ALL)
                     .setOngoing(true)
                     .getNotification();
-
             nm.notify(R.drawable.vpn_connected, notification);
             Binder.restoreCallingIdentity(identity);
         }
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 2164334..dac0044 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -25,6 +25,9 @@
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.NetworkPolicy.WARNING_DISABLED;
+import static android.net.NetworkPolicyManager.ACTION_DATA_USAGE_LIMIT;
+import static android.net.NetworkPolicyManager.ACTION_DATA_USAGE_WARNING;
+import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
 import static android.net.NetworkPolicyManager.POLICY_NONE;
 import static android.net.NetworkPolicyManager.POLICY_REJECT_PAID_BACKGROUND;
 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
@@ -138,11 +141,6 @@
     private static final String ATTR_UID = "uid";
     private static final String ATTR_POLICY = "policy";
 
-    public static final String ACTION_DATA_USAGE_WARNING =
-            "android.intent.action.DATA_USAGE_WARNING";
-    public static final String ACTION_DATA_USAGE_LIMIT =
-            "android.intent.action.DATA_USAGE_LIMIT";
-
     private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS;
 
     private final Context mContext;
@@ -402,9 +400,12 @@
                 builder.setTicker(title);
                 builder.setContentTitle(title);
                 builder.setContentText(body);
-                builder.setContentIntent(PendingIntent.getActivity(mContext, 0,
-                        new Intent(ACTION_DATA_USAGE_WARNING),
-                        PendingIntent.FLAG_UPDATE_CURRENT));
+
+                final Intent intent = new Intent(ACTION_DATA_USAGE_WARNING);
+                intent.addCategory(Intent.CATEGORY_DEFAULT);
+                intent.putExtra(EXTRA_NETWORK_TEMPLATE, policy.networkTemplate);
+                builder.setContentIntent(PendingIntent.getActivity(
+                        mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
                 break;
             }
             case TYPE_LIMIT: {
@@ -426,9 +427,12 @@
                 builder.setTicker(title);
                 builder.setContentTitle(title);
                 builder.setContentText(body);
-                builder.setContentIntent(PendingIntent.getActivity(mContext, 0,
-                        new Intent(ACTION_DATA_USAGE_LIMIT),
-                        PendingIntent.FLAG_UPDATE_CURRENT));
+
+                final Intent intent = new Intent(ACTION_DATA_USAGE_LIMIT);
+                intent.addCategory(Intent.CATEGORY_DEFAULT);
+                intent.putExtra(EXTRA_NETWORK_TEMPLATE, policy.networkTemplate);
+                builder.setContentIntent(PendingIntent.getActivity(
+                        mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
                 break;
             }
         }
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 476aded..edccf6c 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -25,13 +25,16 @@
 import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.TrafficStats.TEMPLATE_WIFI;
+import static org.easymock.EasyMock.anyInt;
 import static org.easymock.EasyMock.capture;
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.isA;
 
 import android.app.IActivityManager;
+import android.app.INotificationManager;
 import android.app.IProcessObserver;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -81,14 +84,15 @@
     private INetworkPolicyListener mPolicyListener;
     private TrustedTime mTime;
     private IConnectivityManager mConnManager;
+    private INotificationManager mNotifManager;
 
     private NetworkPolicyManagerService mService;
     private IProcessObserver mProcessObserver;
 
     private Binder mStubBinder = new Binder();
 
-    private static final int UID_A = 800;
-    private static final int UID_B = 801;
+    private static final int UID_A = android.os.Process.FIRST_APPLICATION_UID + 800;
+    private static final int UID_B = android.os.Process.FIRST_APPLICATION_UID + 801;
 
     private static final int PID_1 = 400;
     private static final int PID_2 = 401;
@@ -119,10 +123,12 @@
         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);
         mService.bindConnectivityManager(mConnManager);
+        mService.bindNotificationManager(mNotifManager);
 
         // RemoteCallbackList needs a binder to use as key
         expect(mPolicyListener.asBinder()).andReturn(mStubBinder).atLeastOnce();
@@ -137,6 +143,7 @@
 
         // expect to answer screen status during systemReady()
         expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce();
+        expectTime(System.currentTimeMillis());
 
         replay();
         mService.systemReady();
@@ -365,6 +372,8 @@
         // expect that quota remaining should be 1536 bytes
         // TODO: write up NetworkManagementService mock
 
+        expectClearNotifications();
+
         replay();
         setNetworkPolicies(new NetworkPolicy(TEMPLATE_WIFI, null, CYCLE_DAY, 1024L, 2048L));
         verifyAndReset();
@@ -388,7 +397,7 @@
         return new NetworkState(info, prop, null);
     }
 
-    public void expectTime(long currentTime) throws Exception {
+    private void expectTime(long currentTime) throws Exception {
         expect(mTime.forceRefresh()).andReturn(false).anyTimes();
         expect(mTime.hasCache()).andReturn(true).anyTimes();
         expect(mTime.currentTimeMillis()).andReturn(currentTime).anyTimes();
@@ -396,6 +405,11 @@
         expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
     }
 
+    private void expectClearNotifications() throws Exception {
+        mNotifManager.cancelNotificationWithTag(isA(String.class), isA(String.class), anyInt());
+        expectLastCall().anyTimes();
+    }
+
     private void expectRulesChanged(int uid, int policy) throws Exception {
         mPolicyListener.onRulesChanged(eq(uid), eq(policy));
         expectLastCall().atLeastOnce();
@@ -403,13 +417,13 @@
 
     private void replay() {
         EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime,
-                mConnManager);
+                mConnManager, mNotifManager);
     }
 
     private void verifyAndReset() {
         EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime,
-                mConnManager);
+                mConnManager, mNotifManager);
         EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime,
-                mConnManager);
+                mConnManager, mNotifManager);
     }
 }
diff --git a/telephony/java/com/android/internal/telephony/DataCallState.java b/telephony/java/com/android/internal/telephony/DataCallState.java
index 1d67d45..f5651e0 100644
--- a/telephony/java/com/android/internal/telephony/DataCallState.java
+++ b/telephony/java/com/android/internal/telephony/DataCallState.java
@@ -202,7 +202,7 @@
 
                 result = SetupResult.SUCCESS;
             } catch (UnknownHostException e) {
-                Log.d(LOG_TAG, "onSetupCompleted: UnknownHostException " + e);
+                Log.d(LOG_TAG, "setLinkProperties: UnknownHostException " + e);
                 e.printStackTrace();
                 result = SetupResult.ERR_UnacceptableParameter;
             }
@@ -216,8 +216,10 @@
 
         // An error occurred so clear properties
         if (result != SetupResult.SUCCESS) {
-            if(DBG) Log.d(LOG_TAG,
-                    "onSetupConnectionCompleted with an error, clearing LinkProperties");
+            if(DBG) {
+                Log.d(LOG_TAG, "setLinkProperties: error clearing LinkProperties " +
+                        "status=" + status + " result=" + result);
+            }
             linkProperties.clear();
         }
 
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index c21a96a..5c030fd 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -228,7 +228,6 @@
         mId = id;
         mRetryMgr = rm;
         this.cid = -1;
-        clearSettings();
 
         setDbg(false);
         addState(mDefaultState);
@@ -313,7 +312,6 @@
             AsyncResult.forMessage(msg);
             msg.sendToTarget();
         }
-        clearSettings();
         if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp);
     }
 
@@ -632,7 +630,6 @@
                 }
                 case DataConnectionAc.REQ_RESET:
                     if (VDBG) log("DcDefaultState: msg.what=REQ_RESET");
-                    clearSettings();
                     mAc.replyToMessage(msg, DataConnectionAc.RSP_RESET);
                     transitionTo(mInactiveState);
                     break;
@@ -718,6 +715,7 @@
                 if (VDBG) log("DcInactiveState: enter notifyDisconnectCompleted");
                 notifyDisconnectCompleted(mDisconnectParams);
             }
+            clearSettings();
         }
 
         @Override
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
index 5d8fc78..02617c8 100644
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ b/telephony/java/com/android/internal/telephony/IccCard.java
@@ -84,6 +84,9 @@
     static public final String INTENT_VALUE_LOCKED_ON_PUK = "PUK";
     /* NETWORK means ICC is locked on NETWORK PERSONALIZATION */
     static public final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK";
+    /* PERM_DISABLED means ICC is permanently disabled due to puk fails */
+    static public final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED";
+
 
     protected static final int EVENT_ICC_LOCKED_OR_ABSENT = 1;
     private static final int EVENT_GET_ICC_STATUS_DONE = 2;
@@ -112,7 +115,8 @@
         PUK_REQUIRED,
         NETWORK_LOCKED,
         READY,
-        NOT_READY;
+        NOT_READY,
+        PERM_DISABLED;
 
         public boolean isPinLocked() {
             return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED));
@@ -120,7 +124,8 @@
 
         public boolean iccCardExist() {
             return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)
-                    || (this == NETWORK_LOCKED) || (this == READY));
+                    || (this == NETWORK_LOCKED) || (this == READY)
+                    || (this == PERM_DISABLED));
         }
     }
 
@@ -416,6 +421,7 @@
         boolean transitionedIntoPinLocked;
         boolean transitionedIntoAbsent;
         boolean transitionedIntoNetworkLocked;
+        boolean transitionedIntoPermBlocked;
         boolean isIccCardRemoved;
         boolean isIccCardAdded;
 
@@ -434,6 +440,8 @@
         transitionedIntoAbsent = (oldState != State.ABSENT && newState == State.ABSENT);
         transitionedIntoNetworkLocked = (oldState != State.NETWORK_LOCKED
                 && newState == State.NETWORK_LOCKED);
+        transitionedIntoPermBlocked = (oldState != State.PERM_DISABLED
+                && newState == State.PERM_DISABLED);
         isIccCardRemoved = (oldState != null &&
                         oldState.iccCardExist() && newState == State.ABSENT);
         isIccCardAdded = (oldState == State.ABSENT &&
@@ -454,6 +462,10 @@
             mNetworkLockedRegistrants.notifyRegistrants();
             broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED,
                   INTENT_VALUE_LOCKED_NETWORK);
+        } else if (transitionedIntoPermBlocked) {
+            if (mDbg) log("Notify SIM permanently disabled.");
+            broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT,
+                    INTENT_VALUE_ABSENT_ON_PERM_DISABLED);
         }
 
         if (isIccCardRemoved) {
@@ -762,6 +774,9 @@
         }
 
         // check if PIN required
+        if (app.pin1.isPermBlocked()) {
+            return IccCard.State.PERM_DISABLED;
+        }
         if (app.app_state.isPinRequired()) {
             return IccCard.State.PIN_REQUIRED;
         }
diff --git a/telephony/java/com/android/internal/telephony/IccCardApplication.java b/telephony/java/com/android/internal/telephony/IccCardApplication.java
index 434c484..abb740e 100644
--- a/telephony/java/com/android/internal/telephony/IccCardApplication.java
+++ b/telephony/java/com/android/internal/telephony/IccCardApplication.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import com.android.internal.telephony.IccCardStatus.PinState;
+
 
 /**
  * See also RIL_AppStatus in include/telephony/ril.h
@@ -104,8 +106,8 @@
     public String         app_label;
     // applicable to USIM and CSIM
     public int            pin1_replaced;
-    public int            pin1;
-    public int            pin2;
+    public PinState            pin1;
+    public PinState            pin2;
 
     AppType AppTypeFromRILInt(int type) {
         AppType newType;
@@ -177,6 +179,33 @@
         return newSubState;
     }
 
+    PinState PinStateFromRILInt(int state) {
+        PinState newPinState;
+        switch(state) {
+            case 0:
+                newPinState = PinState.PINSTATE_UNKNOWN;
+                break;
+            case 1:
+                newPinState = PinState.PINSTATE_ENABLED_NOT_VERIFIED;
+                break;
+            case 2:
+                newPinState = PinState.PINSTATE_ENABLED_VERIFIED;
+                break;
+            case 3:
+                newPinState = PinState.PINSTATE_DISABLED;
+                break;
+            case 4:
+                newPinState = PinState.PINSTATE_ENABLED_BLOCKED;
+                break;
+            case 5:
+                newPinState = PinState.PINSTATE_ENABLED_PERM_BLOCKED;
+                break;
+            default:
+                throw new RuntimeException("Unrecognized RIL_PinState: " + state);
+        }
+        return newPinState;
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -185,6 +214,12 @@
         if (app_state == AppState.APPSTATE_SUBSCRIPTION_PERSO) {
             sb.append(",").append(perso_substate);
         }
+        if (app_type == AppType.APPTYPE_CSIM ||
+                app_type == AppType.APPTYPE_USIM ||
+                app_type == AppType.APPTYPE_ISIM) {
+            sb.append(",pin1=").append(pin1);
+            sb.append(",pin2=").append(pin2);
+        }
         sb.append("}");
         return sb.toString();
     }
diff --git a/telephony/java/com/android/internal/telephony/IccCardStatus.java b/telephony/java/com/android/internal/telephony/IccCardStatus.java
index e9de922..c751a21 100644
--- a/telephony/java/com/android/internal/telephony/IccCardStatus.java
+++ b/telephony/java/com/android/internal/telephony/IccCardStatus.java
@@ -42,7 +42,19 @@
         PINSTATE_ENABLED_VERIFIED,
         PINSTATE_DISABLED,
         PINSTATE_ENABLED_BLOCKED,
-        PINSTATE_ENABLED_PERM_BLOCKED
+        PINSTATE_ENABLED_PERM_BLOCKED;
+
+        boolean isPermBlocked() {
+            return this == PINSTATE_ENABLED_PERM_BLOCKED;
+        }
+
+        boolean isPinRequired() {
+            return this == PINSTATE_ENABLED_NOT_VERIFIED;
+        }
+
+        boolean isPukRequired() {
+            return this == PINSTATE_ENABLED_BLOCKED;
+        }
     }
 
     private CardState  mCardState;
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 572bbaa..76f1ab7 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -2924,8 +2924,8 @@
             ca.aid            = p.readString();
             ca.app_label      = p.readString();
             ca.pin1_replaced  = p.readInt();
-            ca.pin1           = p.readInt();
-            ca.pin2           = p.readInt();
+            ca.pin1           = ca.PinStateFromRILInt(p.readInt());
+            ca.pin2           = ca.PinStateFromRILInt(p.readInt());
             status.addApplication(ca);
         }
         return status;
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
old mode 100644
new mode 100755
diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
old mode 100644
new mode 100755
index c8dd718..73260fb
--- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
+++ b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
@@ -194,6 +194,7 @@
 
     public static final String CONTENT_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
     public static final String CONTENT_TYPE_B_MMS = "application/vnd.wap.mms-message";
+    public static final String CONTENT_TYPE_B_PUSH_SYNCML_NOTI = "application/vnd.syncml.notification";
 
     byte[] wspData;
     int    dataLength;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
old mode 100644
new mode 100755
index 29349db..07b0f4f
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -41,6 +41,7 @@
 import com.android.internal.telephony.SmsMessageBase;
 import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
 import com.android.internal.telephony.TelephonyProperties;
+import com.android.internal.telephony.WspTypeDecoder;
 import com.android.internal.telephony.cdma.sms.SmsEnvelope;
 import com.android.internal.telephony.cdma.sms.UserData;
 import com.android.internal.util.HexDump;
@@ -50,6 +51,8 @@
 import java.util.Arrays;
 import java.util.HashMap;
 
+import android.content.res.Resources;
+
 
 final class CdmaSMSDispatcher extends SMSDispatcher {
     private static final String TAG = "CDMA";
@@ -57,6 +60,9 @@
     private byte[] mLastDispatchedSmsFingerprint;
     private byte[] mLastAcknowledgedSmsFingerprint;
 
+    private boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean(
+            com.android.internal.R.bool.config_duplicate_port_omadm_wappush);
+
     CdmaSMSDispatcher(CDMAPhone phone) {
         super(phone);
     }
@@ -253,6 +259,13 @@
             sourcePort |= 0xFF & pdu[index++];
             destinationPort = (0xFF & pdu[index++]) << 8;
             destinationPort |= 0xFF & pdu[index++];
+            // Some carriers incorrectly send duplicate port fields in omadm wap pushes.
+            // If configured, check for that here
+            if (mCheckForDuplicatePortsInOmadmWapPush) {
+                if (checkDuplicatePortOmadmWappush(pdu,index)) {
+                    index = index + 4; // skip duplicate port fields
+                }
+            }
         }
 
         // Lookup all other related parts
@@ -502,4 +515,42 @@
             return CommandsInterface.CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM;
         }
     }
+
+    /**
+     * Optional check to see if the received WapPush is an OMADM notification with erroneous
+     * extra port fields.
+     * - Some carriers make this mistake.
+     * ex: MSGTYPE-TotalSegments-CurrentSegment
+     *       -SourcePortDestPort-SourcePortDestPort-OMADM PDU
+     * @param origPdu The WAP-WDP PDU segment
+     * @param index Current Index while parsing the PDU.
+     * @return True if OrigPdu is OmaDM Push Message which has duplicate ports.
+     *         False if OrigPdu is NOT OmaDM Push Message which has duplicate ports.
+     */
+    private boolean checkDuplicatePortOmadmWappush(byte[] origPdu, int index) {
+        index += 4;
+        byte[] omaPdu = new byte[origPdu.length - index];
+        System.arraycopy(origPdu, index, omaPdu, 0, omaPdu.length);
+
+        WspTypeDecoder pduDecoder = new WspTypeDecoder(omaPdu);
+        int wspIndex = 2;
+
+        // Process header length field
+        if (pduDecoder.decodeUintvarInteger(wspIndex) == false) {
+            return false;
+        }
+
+        wspIndex += pduDecoder.getDecodedDataLength(); // advance to next field
+
+        // Process content type field
+        if (pduDecoder.decodeContentType(wspIndex) == false) {
+            return false;
+        }
+
+        String mimeType = pduDecoder.getValueString();
+        if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_SYNCML_NOTI)) {
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
index ee63ede..9af2d26 100755
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
@@ -119,8 +119,11 @@
 
         adnCache.reset();
 
-        phone.setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, null);
-        phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
+        // Don't clean up PROPERTY_ICC_OPERATOR_ISO_COUNTRY and
+        // PROPERTY_ICC_OPERATOR_NUMERIC here. Since not all CDMA
+        // devices have RUIM, these properties should keep the original
+        // values, e.g. build time settings, when there is no RUIM but
+        // set new values when RUIM is available and loaded.
 
         // recordsRequested is set to false indicating that the SIM
         // read requests made so far are not valid. This is set to
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index dcde71a..19c06f6 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -1850,7 +1850,7 @@
             if (!dc.configureRetry(SystemProperties.get("ro.gsm.data_retry_config"))) {
                 if (!dc.configureRetry(DEFAULT_DATA_RETRY_CONFIG)) {
                     // Should never happen, log an error and default to a simple linear sequence.
-                    loge("createDataConnection: Could not configure using " +
+                    loge("configureRetry: Could not configure using " +
                             "DEFAULT_DATA_RETRY_CONFIG=" + DEFAULT_DATA_RETRY_CONFIG);
                     dc.configureRetry(20, 2000, 1000);
                 }
@@ -1859,7 +1859,7 @@
             if (!dc.configureRetry(SystemProperties.get("ro.gsm.2nd_data_retry_config"))) {
                 if (!dc.configureRetry(SECONDARY_DATA_RETRY_CONFIG)) {
                     // Should never happen, log an error and default to a simple sequence.
-                    loge("createDataConnection: Could note configure using " +
+                    loge("configureRetry: Could note configure using " +
                             "SECONDARY_DATA_RETRY_CONFIG=" + SECONDARY_DATA_RETRY_CONFIG);
                     dc.configureRetry("max_retries=3, 333, 333, 333");
                 }
@@ -1872,7 +1872,7 @@
             if (DBG) log("destroyDataConnections: clear mDataConnectionList");
             mDataConnections.clear();
         } else {
-            if (DBG) log("destroyDataConnectionList mDataConnecitonList is empty, ignore");
+            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
         }
     }
 
diff --git a/tests/BiDiTests/res/layout/table_layout_locale.xml b/tests/BiDiTests/res/layout/table_layout_locale.xml
index 2589b40..bd2ad23 100644
--- a/tests/BiDiTests/res/layout/table_layout_locale.xml
+++ b/tests/BiDiTests/res/layout/table_layout_locale.xml
@@ -44,7 +44,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -64,7 +64,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
@@ -73,7 +73,7 @@
                      android:layout_height="wrap_content"
                      android:stretchColumns="1,2"
                      android:layoutDirection="inherit">
-    
+
             <TableRow>
                 <Button android:layout_height="wrap_content"
                         android:layout_width="wrap_content"
@@ -90,7 +90,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -110,7 +110,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
@@ -119,7 +119,7 @@
                      android:layout_height="wrap_content"
                      android:stretchColumns="1,2"
                      android:layoutDirection="ltr">
-    
+
             <TableRow>
                 <Button android:layout_height="wrap_content"
                         android:layout_width="wrap_content"
@@ -136,7 +136,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -156,7 +156,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
@@ -165,7 +165,7 @@
                      android:layout_height="wrap_content"
                      android:stretchColumns="1,2"
                      android:layoutDirection="rtl">
-    
+
             <TableRow>
                 <Button android:layout_height="wrap_content"
                         android:layout_width="wrap_content"
@@ -182,7 +182,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -202,7 +202,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
@@ -211,7 +211,7 @@
                      android:layout_height="wrap_content"
                      android:stretchColumns="1,2"
                      android:layoutDirection="locale">
-    
+
             <TableRow>
                 <Button android:layout_height="wrap_content"
                         android:layout_width="wrap_content"
@@ -228,7 +228,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -248,7 +248,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
diff --git a/tests/BiDiTests/res/layout/table_layout_ltr.xml b/tests/BiDiTests/res/layout/table_layout_ltr.xml
index d8d412c..18c0817 100644
--- a/tests/BiDiTests/res/layout/table_layout_ltr.xml
+++ b/tests/BiDiTests/res/layout/table_layout_ltr.xml
@@ -44,7 +44,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -64,7 +64,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
@@ -90,7 +90,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -110,7 +110,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
@@ -136,7 +136,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -156,7 +156,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
@@ -182,7 +182,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -202,7 +202,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
@@ -228,7 +228,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -248,7 +248,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
diff --git a/tests/BiDiTests/res/layout/table_layout_rtl.xml b/tests/BiDiTests/res/layout/table_layout_rtl.xml
index 53130fe2..d7e097d 100644
--- a/tests/BiDiTests/res/layout/table_layout_rtl.xml
+++ b/tests/BiDiTests/res/layout/table_layout_rtl.xml
@@ -44,7 +44,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -64,7 +64,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
@@ -73,7 +73,7 @@
                      android:layout_height="wrap_content"
                      android:stretchColumns="1,2"
                      android:layoutDirection="inherit">
-    
+
             <TableRow>
                 <Button android:layout_height="wrap_content"
                         android:layout_width="wrap_content"
@@ -90,7 +90,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -110,7 +110,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
@@ -119,7 +119,7 @@
                      android:layout_height="wrap_content"
                      android:stretchColumns="1,2"
                      android:layoutDirection="ltr">
-    
+
             <TableRow>
                 <Button android:layout_height="wrap_content"
                         android:layout_width="wrap_content"
@@ -136,7 +136,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -156,7 +156,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
@@ -165,7 +165,7 @@
                      android:layout_height="wrap_content"
                      android:stretchColumns="1,2"
                      android:layoutDirection="rtl">
-    
+
             <TableRow>
                 <Button android:layout_height="wrap_content"
                         android:layout_width="wrap_content"
@@ -182,7 +182,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -202,7 +202,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
@@ -211,7 +211,7 @@
                      android:layout_height="wrap_content"
                      android:stretchColumns="1,2"
                      android:layoutDirection="locale">
-    
+
             <TableRow>
                 <Button android:layout_height="wrap_content"
                         android:layout_width="wrap_content"
@@ -228,7 +228,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_after_text"
                         android:textSize="24dip"
-                        android:gravity="after"
+                        android:gravity="end"
                         />
             </TableRow>
 
@@ -248,7 +248,7 @@
                         android:layout_width="wrap_content"
                         android:text="@string/button_before_text"
                         android:textSize="24dip"
-                        android:gravity="before"
+                        android:gravity="start"
                         />
             </TableRow>
         </TableLayout>
diff --git a/tests/RenderScriptTests/PerfTest/res/drawable/flares.png b/tests/RenderScriptTests/PerfTest/res/drawable/flares.png
new file mode 100644
index 0000000..3a5c970
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/drawable/flares.png
Binary files differ
diff --git a/tests/RenderScriptTests/PerfTest/res/drawable/light1.jpg b/tests/RenderScriptTests/PerfTest/res/drawable/light1.jpg
new file mode 100644
index 0000000..2f2f10e
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/drawable/light1.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/PerfTest/res/drawable/space.jpg b/tests/RenderScriptTests/PerfTest/res/drawable/space.jpg
new file mode 100644
index 0000000..b61f6a3
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/drawable/space.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
index b568781..3f57799 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
@@ -38,6 +38,10 @@
 import android.renderscript.ProgramStore.BlendDstFunc;
 import android.renderscript.RenderScript.RSMessageHandler;
 import android.renderscript.Sampler.Value;
+import android.renderscript.Mesh.Primitive;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramVertexFixedFunction;
+
 import android.util.Log;
 
 
@@ -45,7 +49,9 @@
 
     private static final String TAG = "RsBenchRS";
     private static final String SAMPLE_TEXT = "Bench Test";
-
+    private static final String LIST_TEXT =
+      "This is a sample list of text to show in the list view";
+    private static int PARTICLES_COUNT = 12000;
     int mWidth;
     int mHeight;
     int mLoops;
@@ -82,6 +88,7 @@
     private Sampler mLinearWrap;
     private Sampler mMipLinearWrap;
     private Sampler mNearestClamp;
+    private Sampler mNearesWrap;
 
     private ProgramStore mProgStoreBlendNoneDepth;
     private ProgramStore mProgStoreBlendNone;
@@ -106,6 +113,7 @@
     private ScriptField_VertexShaderConstants3_s mVSConstPixel;
     private ScriptField_FragentShaderConstants3_s mFSConstPixel;
 
+
     private ProgramRaster mCullBack;
     private ProgramRaster mCullFront;
     private ProgramRaster mCullNone;
@@ -121,6 +129,7 @@
     private Mesh mWbyHMesh;
     private Mesh mTorus;
     private Mesh mSingleMesh;
+    private Mesh mParticlesMesh;
 
     Font mFontSans;
     Font mFontSerif;
@@ -128,6 +137,9 @@
 
     private ScriptField_ListAllocs_s mTextureAllocs;
     private ScriptField_ListAllocs_s mSampleTextAllocs;
+    private ScriptField_ListAllocs_s mSampleListViewAllocs;
+    private ScriptField_VpConsts mPvStarAlloc;
+
 
     private ScriptC_rsbench mScript;
 
@@ -300,6 +312,15 @@
         mScript.set_gProgStoreBlendNone(mProgStoreBlendNone);
         mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha);
         mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd);
+
+        // For GALAXY
+        builder = new ProgramStore.Builder(mRS);
+        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
+        mRS.bindProgramStore(builder.create());
+
+        builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
+        mScript.set_gPSLights(builder.create());
+
     }
 
     private void initProgramFragment() {
@@ -316,8 +337,59 @@
 
         mScript.set_gProgFragmentColor(mProgFragmentColor);
         mScript.set_gProgFragmentTexture(mProgFragmentTexture);
+
+
+        // For Galaxy live wallpaper drawing
+        ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
+        builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+                           ProgramFragmentFixedFunction.Builder.Format.RGB, 0);
+        ProgramFragment pfb = builder.create();
+        pfb.bindSampler(mNearesWrap, 0);
+        mScript.set_gPFBackground(pfb);
+
+        builder = new ProgramFragmentFixedFunction.Builder(mRS);
+        builder.setPointSpriteTexCoordinateReplacement(true);
+        builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
+                           ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
+        builder.setVaryingColor(true);
+        ProgramFragment pfs = builder.create();
+        pfs.bindSampler(mMipLinearWrap, 0);
+        mScript.set_gPFStars(pfs);
+
     }
 
+    private Matrix4f getProjectionNormalized(int w, int h) {
+      // range -1,1 in the narrow axis at z = 0.
+      Matrix4f m1 = new Matrix4f();
+      Matrix4f m2 = new Matrix4f();
+
+      if(w > h) {
+          float aspect = ((float)w) / h;
+          m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
+      } else {
+          float aspect = ((float)h) / w;
+          m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
+      }
+
+      m2.loadRotate(180, 0, 1, 0);
+      m1.loadMultiply(m1, m2);
+
+      m2.loadScale(-2, 2, 1);
+      m1.loadMultiply(m1, m2);
+
+      m2.loadTranslate(0, 0, 2);
+      m1.loadMultiply(m1, m2);
+      return m1;
+  }
+
+    private void updateProjectionMatrices() {
+      Matrix4f projNorm = getProjectionNormalized(mBenchmarkDimX, mBenchmarkDimY);
+      ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
+      i.Proj = projNorm;
+      i.MVP = projNorm;
+      mPvStarAlloc.set(i, 0, true);
+  }
+
     private void initProgramVertex() {
         ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
         mProgVertex = pvb.create();
@@ -329,6 +401,39 @@
         mPVA.setProjection(proj);
 
         mScript.set_gProgVertex(mProgVertex);
+
+        // For galaxy live wallpaper
+        mPvStarAlloc = new ScriptField_VpConsts(mRS, 1);
+        mScript.bind_vpConstants(mPvStarAlloc);
+        updateProjectionMatrices();
+
+        ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
+        String t =  "varying vec4 varColor;\n" +
+                    "varying vec2 varTex0;\n" +
+                    "void main() {\n" +
+                    "  float dist = ATTRIB_position.y;\n" +
+                    "  float angle = ATTRIB_position.x;\n" +
+                    "  float x = dist * sin(angle);\n" +
+                    "  float y = dist * cos(angle) * 0.892;\n" +
+                    "  float p = dist * 5.5;\n" +
+                    "  float s = cos(p);\n" +
+                    "  float t = sin(p);\n" +
+                    "  vec4 pos;\n" +
+                    "  pos.x = t * x + s * y;\n" +
+                    "  pos.y = s * x - t * y;\n" +
+                    "  pos.z = ATTRIB_position.z;\n" +
+                    "  pos.w = 1.0;\n" +
+                    "  gl_Position = UNI_MVP * pos;\n" +
+                    "  gl_PointSize = ATTRIB_color.a * 10.0;\n" +
+                    "  varColor.rgb = ATTRIB_color.rgb;\n" +
+                    "  varColor.a = 1.0;\n" +
+                    "}\n";
+        sb.setShader(t);
+        sb.addInput(mParticlesMesh.getVertexAllocation(0).getType().getElement());
+        sb.addConstant(mPvStarAlloc.getType());
+        ProgramVertex pvs = sb.create();
+        pvs.bindConstants(mPvStarAlloc.getAllocation(), 0);
+        mScript.set_gPVStars(pvs);
     }
 
     private void initCustomShaders() {
@@ -426,6 +531,11 @@
         mScript.set_gTexTransparent(mTexTransparent);
         mScript.set_gTexChecker(mTexChecker);
         mScript.set_gTexGlobe(mTexGlobe);
+
+        // For Galaxy live wallpaper
+        mScript.set_gTSpace(loadTextureRGB(R.drawable.space));
+        mScript.set_gTLight1(loadTextureRGB(R.drawable.light1));
+        mScript.set_gTFlares(loadTextureARGB(R.drawable.flares));
     }
 
     private void initFonts() {
@@ -440,6 +550,19 @@
         mScript.set_gFontSerif(mFontSerif);
     }
 
+    private void createParticlesMesh() {
+        ScriptField_Particle p = new ScriptField_Particle(mRS, PARTICLES_COUNT);
+
+        final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS);
+        meshBuilder.addVertexAllocation(p.getAllocation());
+        final int vertexSlot = meshBuilder.getCurrentVertexTypeIndex();
+        meshBuilder.addIndexSetType(Primitive.POINT);
+        mParticlesMesh = meshBuilder.create();
+
+        mScript.set_gParticlesMesh(mParticlesMesh);
+        mScript.bind_Particles(p);
+    }
+
     private void initMesh() {
         m10by10Mesh = getMbyNMesh(mBenchmarkDimX, mBenchmarkDimY, 10, 10);
         mScript.set_g10by10Mesh(m10by10Mesh);
@@ -458,6 +581,8 @@
             mTorus = (Mesh)entry.getObject();
             mScript.set_gTorusMesh(mTorus);
         }
+
+        createParticlesMesh();
     }
 
     private void initSamplers() {
@@ -471,6 +596,7 @@
         mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
         mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
         mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS);
+        mNearesWrap = Sampler.WRAP_NEAREST(mRS);
 
         mScript.set_gLinearClamp(mLinearClamp);
         mScript.set_gLinearWrap(mLinearWrap);
@@ -524,10 +650,10 @@
         initSamplers();
         initProgramStore();
         initProgramFragment();
+        initMesh();
         initProgramVertex();
         initFonts();
         loadImages();
-        initMesh();
         initProgramRaster();
         initCustomShaders();
 
@@ -567,6 +693,15 @@
         mSampleTextAllocs.copyAll();
         mScript.bind_gSampleTextList100(mSampleTextAllocs);
 
+        mSampleListViewAllocs = new ScriptField_ListAllocs_s(mRS, 1000);
+        for (int i = 0; i < 1000; i++) {
+            ScriptField_ListAllocs_s.Item textElem = new ScriptField_ListAllocs_s.Item();
+            textElem.item = Allocation.createFromString(mRS, LIST_TEXT, Allocation.USAGE_SCRIPT);
+            mSampleListViewAllocs.set(textElem, i, false);
+        }
+        mSampleListViewAllocs.copyAll();
+        mScript.bind_gListViewText(mSampleListViewAllocs);
+
         mRS.bindRootScript(mScript);
     }
 }
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
index 0294b31..6d80b0e 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
@@ -23,9 +23,50 @@
 const int RS_MSG_TEST_DONE = 100;
 const int RS_MSG_RESULTS_READY = 101;
 
-const int gMaxModes = 29;
+const int gMaxModes = 31;
 int gMaxLoops;
 
+// Parameters for galaxy live wallpaper
+rs_allocation gTSpace;
+rs_allocation gTLight1;
+rs_allocation gTFlares;
+rs_mesh gParticlesMesh;
+
+rs_program_fragment gPFBackground;
+rs_program_fragment gPFStars;
+rs_program_vertex gPVStars;
+rs_program_vertex gPVBkProj;
+rs_program_store gPSLights;
+
+float gXOffset = 0.5f;
+
+#define ELLIPSE_RATIO 0.892f
+#define PI 3.1415f
+#define TWO_PI 6.283f
+#define ELLIPSE_TWIST 0.023333333f
+
+static float angle = 50.f;
+static int gOldWidth;
+static int gOldHeight;
+static int gWidth;
+static int gHeight;
+static float gSpeed[12000];
+static int gGalaxyRadius = 300;
+static rs_allocation gParticlesBuffer;
+
+typedef struct __attribute__((packed, aligned(4))) Particle {
+    uchar4 color;
+    float3 position;
+} Particle_t;
+Particle_t *Particles;
+
+typedef struct VpConsts {
+    rs_matrix4x4 Proj;
+    rs_matrix4x4 MVP;
+} VpConsts_t;
+VpConsts_t *vpConstants;
+// End of parameters for galaxy live wallpaper
+
 // Allocation to send test names back to java
 char *gStringBuffer = 0;
 // Allocation to write the results into
@@ -52,6 +93,7 @@
 
 ListAllocs *gTexList100;
 ListAllocs *gSampleTextList100;
+ListAllocs *gListViewText;
 
 rs_mesh g10by10Mesh;
 rs_mesh g100by100Mesh;
@@ -109,6 +151,141 @@
                              0.5f, 0.6f, 0.7f, 1.0f,
 };
 
+/**
+  * Methods to draw the galaxy live wall paper
+  */
+static float mapf(float minStart, float minStop, float maxStart, float maxStop, float value) {
+    return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
+}
+
+/**
+ * Helper function to generate the stars.
+ */
+static float randomGauss() {
+    float x1;
+    float x2;
+    float w = 2.f;
+
+    while (w >= 1.0f) {
+        x1 = rsRand(2.0f) - 1.0f;
+        x2 = rsRand(2.0f) - 1.0f;
+        w = x1 * x1 + x2 * x2;
+    }
+
+    w = sqrt(-2.0f * log(w) / w);
+    return x1 * w;
+}
+
+/**
+ * Generates the properties for a given star.
+ */
+static void createParticle(Particle_t *part, int idx, float scale) {
+    float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f);
+    float id = d / gGalaxyRadius;
+    float z = randomGauss() * 0.4f * (1.0f - id);
+    float p = -d * ELLIPSE_TWIST;
+
+    if (d < gGalaxyRadius * 0.33f) {
+        part->color.x = (uchar) (220 + id * 35);
+        part->color.y = 220;
+        part->color.z = 220;
+    } else {
+        part->color.x = 180;
+        part->color.y = 180;
+        part->color.z = (uchar) clamp(140.f + id * 115.f, 140.f, 255.f);
+    }
+    // Stash point size * 10 in Alpha
+    part->color.w = (uchar) (rsRand(1.2f, 2.1f) * 60);
+
+    if (d > gGalaxyRadius * 0.15f) {
+        z *= 0.6f * (1.0f - id);
+    } else {
+        z *= 0.72f;
+    }
+
+    // Map to the projection coordinates (viewport.x = -1.0 -> 1.0)
+    d = mapf(-4.0f, gGalaxyRadius + 4.0f, 0.0f, scale, d);
+
+    part->position.x = rsRand(TWO_PI);
+    part->position.y = d;
+    gSpeed[idx] = rsRand(0.0015f, 0.0025f) * (0.5f + (scale / d)) * 0.8f;
+
+    part->position.z = z / 5.0f;
+}
+
+/**
+ * Initialize all the starts, called from Java
+ */
+void initParticles() {
+    Particle_t *part = Particles;
+    float scale = gGalaxyRadius / (gWidth * 0.5f);
+    int count = rsAllocationGetDimX(gParticlesBuffer);
+    for (int i = 0; i < count; i ++) {
+        createParticle(part, i, scale);
+        part++;
+    }
+}
+
+static void drawSpace() {
+    rsgBindProgramFragment(gPFBackground);
+    rsgBindTexture(gPFBackground, 0, gTSpace);
+    rsgDrawQuadTexCoords(
+            0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+            gWidth, 0.0f, 0.0f, 2.0f, 1.0f,
+            gWidth, gHeight, 0.0f, 2.0f, 0.0f,
+            0.0f, gHeight, 0.0f, 0.0f, 0.0f);
+}
+
+static void drawLights() {
+    rsgBindProgramVertex(gPVBkProj);
+    rsgBindProgramFragment(gPFBackground);
+    rsgBindTexture(gPFBackground, 0, gTLight1);
+
+    float scale = 512.0f / gWidth;
+    float x = -scale - scale * 0.05f;
+    float y = -scale;
+
+    scale *= 2.0f;
+
+    rsgDrawQuad(x, y, 0.0f,
+             x + scale * 1.1f, y, 0.0f,
+             x + scale * 1.1f, y + scale, 0.0f,
+             x, y + scale, 0.0f);
+}
+
+static void drawParticles(float offset) {
+    float a = offset * angle;
+    float absoluteAngle = fabs(a);
+
+    rs_matrix4x4 matrix;
+    rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, 10.0f - 6.0f * absoluteAngle / 50.0f);
+    if (gHeight > gWidth) {
+        rsMatrixScale(&matrix, 6.6f, 6.0f, 1.0f);
+    } else {
+        rsMatrixScale(&matrix, 12.6f, 12.0f, 1.0f);
+    }
+    rsMatrixRotate(&matrix, absoluteAngle, 1.0f, 0.0f, 0.0f);
+    rsMatrixRotate(&matrix, a, 0.0f, 0.4f, 0.1f);
+    rsMatrixLoad(&vpConstants->MVP, &vpConstants->Proj);
+    rsMatrixMultiply(&vpConstants->MVP, &matrix);
+    rsgAllocationSyncAll(rsGetAllocation(vpConstants));
+
+    rsgBindProgramVertex(gPVStars);
+    rsgBindProgramFragment(gPFStars);
+    rsgBindProgramStore(gPSLights);
+    rsgBindTexture(gPFStars, 0, gTFlares);
+
+    Particle_t *vtx = Particles;
+    int count = rsAllocationGetDimX(gParticlesBuffer);
+    for (int i = 0; i < count; i++) {
+        vtx->position.x = vtx->position.x + gSpeed[i];
+        vtx++;
+    }
+
+    rsgDrawMesh(gParticlesMesh);
+}
+/* end of methods for drawing galaxy */
+
 static void setupOffscreenTarget() {
     rsgBindColorTarget(gRenderBufferColor, 0);
     rsgBindDepthTarget(gRenderBufferDepth);
@@ -303,6 +480,71 @@
     }
 }
 
+// Display a list of text as the list view
+static void displayListView() {
+    // set text color
+    rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f);
+    rsgBindFont(gFontSans);
+
+    // get the size of the list
+    rs_allocation textAlloc;
+    textAlloc = rsGetAllocation(gListViewText);
+    int allocSize = rsAllocationGetDimX(textAlloc);
+
+    int listItemHeight = 80;
+    int yOffset = listItemHeight;
+
+    // set the color for the list divider
+    rsgBindProgramFragment(gProgFragmentColor);
+    rsgProgramFragmentConstantColor(gProgFragmentColor, 1.0, 1.0, 1.0, 1);
+
+    // draw the list with divider
+    for (int i = 0; i < allocSize; i++) {
+        if (yOffset - listItemHeight > gRenderSurfaceH) {
+            break;
+        }
+        rsgDrawRect(0, yOffset - 1, gRenderSurfaceW, yOffset, 0);
+        rsgDrawText(gListViewText[i].item, 20, yOffset - 10);
+        yOffset += listItemHeight;
+    }
+}
+
+static void drawGalaxy() {
+    rsgClearColor(0.f, 0.f, 0.f, 1.f);
+    gParticlesBuffer = rsGetAllocation(Particles);
+    rsgBindProgramFragment(gPFBackground);
+
+    gWidth = rsgGetWidth();
+    gHeight = rsgGetHeight();
+    if ((gWidth != gOldWidth) || (gHeight != gOldHeight)) {
+        initParticles();
+        gOldWidth = gWidth;
+        gOldHeight = gHeight;
+    }
+
+    float offset = mix(-1.0f, 1.0f, gXOffset);
+    drawSpace();
+    drawParticles(offset);
+    drawLights();
+}
+
+// Display images and text with live wallpaper in the background
+static void dispalyLiveWallPaper(int wResolution, int hResolution) {
+    bindProgramVertexOrtho();
+
+    drawGalaxy();
+
+    rsgBindProgramStore(gProgStoreBlendAlpha);
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+
+    drawMeshInPage(0, 0, wResolution, hResolution);
+    drawMeshInPage(-1.0f*gRenderSurfaceW, 0, wResolution, hResolution);
+    drawMeshInPage(1.0f*gRenderSurfaceW, 0, wResolution, hResolution);
+    drawMeshInPage(-2.0f*gRenderSurfaceW, 0, wResolution, hResolution);
+    drawMeshInPage(2.0f*gRenderSurfaceW, 0, wResolution, hResolution);
+}
+
 static float gTorusRotation = 0;
 static void updateModelMatrix(rs_matrix4x4 *matrix, void *buffer) {
     if (buffer == 0) {
@@ -602,14 +844,12 @@
     "Geo test 25.6k heavy fragment heavy vertex",
     "Geo test 51.2k heavy fragment heavy vertex",
     "Geo test 204.8k small tries heavy fragment heavy vertex",
-    "UI test with icon display 10 by 10",     // 25
-    "UI test with icon display 100 by 100",   // 26
-    "UI test with image and text display 3 pages",  // 27
-    "UI test with image and text display 5 pages",  // 28
-    "UI test with list view",                       // 29
-//    "UI test with live wallpaper",                  // 30
-//    "Mesh with 10 by 10 texture",
-//    "Mesh with 100 by 100 texture",
+    "UI test with icon display 10 by 10",
+    "UI test with icon display 100 by 100",
+    "UI test with image and text display 3 pages",
+    "UI test with image and text display 5 pages",
+    "UI test with list view",
+    "UI test with live wallpaper",
 };
 
 void getTestName(int testIndex) {
@@ -714,6 +954,12 @@
     case 28:
         displayImageWithText(7, 5, 1);
         break;
+    case 29:
+        displayListView();
+        break;
+    case 30:
+        dispalyLiveWallPaper(7, 5);
+        break;
     }
 }
 
@@ -737,7 +983,6 @@
 }
 
 int root(void) {
-
     gRenderSurfaceW = rsgGetWidth();
     gRenderSurfaceH = rsgGetHeight();
     rsgClearColor(0.2f, 0.2f, 0.2f, 1.0f);
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index 8e3ed93..b4448a9 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -1093,6 +1093,33 @@
     }
 
     @LayoutlibDelegate
+    /*package*/ static void native_drawTextWithGlyphs(int nativeCanvas, char[] text,
+            int index, int count, float x,
+            float y, int flags, int paint) {
+        native_drawText(nativeCanvas, text, index, count, x, y, flags, paint);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawTextWithGlyphs(int nativeCanvas, String text,
+            int start, int end, float x,
+            float y, int flags, int paint) {
+        int count = end - start;
+        char[] buffer = TemporaryBuffer.obtain(count);
+        TextUtils.getChars(text, start, end, buffer, 0);
+
+        native_drawText(nativeCanvas, text, 0, count, x, y, flags, paint);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawGlyphs(int nativeCanvas, char[] glyphs,
+            int index, int count, float x,
+            float y, int flags, int paint) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Canvas.drawGlyphs is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
     /*package*/ static void native_drawPosText(int nativeCanvas,
                                                   char[] text, int index,
                                                   int count, float[] pos,
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 373f482..7777e19 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -940,9 +940,16 @@
     }
 
     @LayoutlibDelegate
+    /* package */static int native_getTextGlyphs(int native_object, String text, int start,
+            int end, int contextStart, int contextEnd, int flags, char[] glyphs) {
+        // FIXME
+        return 0;
+    }
+
+    @LayoutlibDelegate
     /*package*/ static float native_getTextRunAdvances(int native_object,
             char[] text, int index, int count, int contextIndex, int contextCount,
-            int flags, float[] advances, int advancesIndex) {
+            int flags, float[] advances, int advancesIndex, int reserved) {
         // get the delegate from the native int.
         Paint_Delegate delegate = sManager.getDelegate(native_object);
         if (delegate == null) {
@@ -986,14 +993,14 @@
     @LayoutlibDelegate
     /*package*/ static float native_getTextRunAdvances(int native_object,
             String text, int start, int end, int contextStart, int contextEnd,
-            int flags, float[] advances, int advancesIndex) {
+            int flags, float[] advances, int advancesIndex, int reserved) {
         // FIXME: support contextStart, contextEnd and direction flag
         int count = end - start;
         char[] buffer = TemporaryBuffer.obtain(count);
         TextUtils.getChars(text, start, end, buffer, 0);
 
         return native_getTextRunAdvances(native_object, buffer, 0, count, contextStart,
-                contextEnd - contextStart, flags, advances, advancesIndex);
+                contextEnd - contextStart, flags, advances, advancesIndex, reserved);
     }
 
     @LayoutlibDelegate
diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
index e6dc646..98f8529 100644
--- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
+++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
@@ -44,6 +44,16 @@
     // --- Native methods accessing ICU's database.
 
     @LayoutlibDelegate
+    /*package*/ static String getIcuVersion() {
+        return "unknown_layoutlib";
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static String getUnicodeVersion() {
+        return "5.2";
+    }
+
+    @LayoutlibDelegate
     /*package*/ static String[] getAvailableBreakIteratorLocalesNative() {
         return new String[0];
     }
@@ -74,17 +84,27 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static String getCurrencyCodeNative(String locale) {
+    /*package*/ static String[] getAvailableCurrencyCodes() {
+        return new String[0];
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static String getCurrencyCode(String locale) {
         return "";
     }
 
     @LayoutlibDelegate
-    /*package*/ static int getCurrencyFractionDigitsNative(String currencyCode) {
+    /*package*/ static String getCurrencyDisplayName(String locale, String currencyCode) {
+        return "";
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int getCurrencyFractionDigits(String currencyCode) {
         return 0;
     }
 
     @LayoutlibDelegate
-    /*package*/ static String getCurrencySymbolNative(String locale, String currencyCode) {
+    /*package*/ static String getCurrencySymbol(String locale, String currencyCode) {
         return "";
     }
 
@@ -114,6 +134,12 @@
     }
 
     @LayoutlibDelegate
+    /*package*/ static String addLikelySubtags(String locale) {
+        return "";
+    }
+
+
+    @LayoutlibDelegate
     /*package*/ static String[] getISOLanguagesNative() {
         return Locale.getISOLanguages();
     }
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 3df3736..4f5349a 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1374,7 +1374,7 @@
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
         intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
-        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
+        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties (mLinkProperties));
         if (bssid != null)
             intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
         mContext.sendStickyBroadcast(intent);
@@ -1390,7 +1390,7 @@
     private void sendLinkConfigurationChangedBroadcast() {
         Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
+        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties(mLinkProperties));
         mContext.sendBroadcast(intent);
     }
 
@@ -1454,10 +1454,8 @@
         Log.d(TAG, "Reset connections and stopping DHCP");
 
         /*
-         * Reset connections & stop DHCP
+         * stop DHCP
          */
-        NetworkUtils.resetConnections(mInterfaceName);
-
         if (mDhcpStateMachine != null) {
             mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
             mDhcpStateMachine.quit();
@@ -1547,7 +1545,6 @@
             if (!linkProperties.equals(mLinkProperties)) {
                 Log.d(TAG, "Link configuration changed for netId: " + mLastNetworkId
                     + " old: " + mLinkProperties + "new: " + linkProperties);
-                NetworkUtils.resetConnections(mInterfaceName);
                 mLinkProperties = linkProperties;
                 sendLinkConfigurationChangedBroadcast();
             }
@@ -2820,7 +2817,6 @@
                     if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
                         if (result.hasIpChanged()) {
                             Log.d(TAG,"Reconfiguring IP on connection");
-                            NetworkUtils.resetConnections(mInterfaceName);
                             transitionTo(mConnectingState);
                         }
                         if (result.hasProxyChanged()) {