Merge "Remove unnecessary GL calls."
diff --git a/api/current.xml b/api/current.xml
index 715b49a..bac65eb 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -40322,13 +40322,15 @@
 </method>
 </class>
 <class name="ClipData"
- extends="android.content.ClipDescription"
+ extends="java.lang.Object"
  abstract="false"
  static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
+<implements name="android.os.Parcelable">
+</implements>
 <constructor name="ClipData"
  type="android.content.ClipData"
  static="false"
@@ -40345,6 +40347,20 @@
 <parameter name="item" type="android.content.ClipData.Item">
 </parameter>
 </constructor>
+<constructor name="ClipData"
+ type="android.content.ClipData"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="description" type="android.content.ClipDescription">
+</parameter>
+<parameter name="icon" type="android.graphics.Bitmap">
+</parameter>
+<parameter name="item" type="android.content.ClipData.Item">
+</parameter>
+</constructor>
 <method name="addItem"
  return="void"
  abstract="false"
@@ -40358,6 +40374,28 @@
 <parameter name="item" type="android.content.ClipData.Item">
 </parameter>
 </method>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getDescription"
+ return="android.content.ClipDescription"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getIcon"
  return="android.graphics.Bitmap"
  abstract="false"
@@ -40463,6 +40501,21 @@
 <parameter name="uri" type="android.net.Uri">
 </parameter>
 </method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dest" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
 <field name="CREATOR"
  type="android.os.Parcelable.Creator"
  transient="false"
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index f08d88d..378a8bd 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -645,11 +645,13 @@
     Activity mParent;
     boolean mCalled;
     boolean mCheckedForLoaderManager;
-    boolean mStarted;
+    boolean mLoadersStarted;
     private boolean mResumed;
     private boolean mStopped;
     boolean mFinished;
     boolean mStartedActivity;
+    /** true if the activity is going through a transient pause */
+    /*package*/ boolean mTemporaryPause = false;
     /** true if the activity is being destroyed in order to recreate it with a new configuration */
     /*package*/ boolean mChangingConfigurations = false;
     /*package*/ int mConfigChangeFlags;
@@ -768,7 +770,7 @@
             return mLoaderManager;
         }
         mCheckedForLoaderManager = true;
-        mLoaderManager = getLoaderManager(-1, mStarted, true);
+        mLoaderManager = getLoaderManager(-1, mLoadersStarted, true);
         return mLoaderManager;
     }
     
@@ -777,9 +779,13 @@
             mAllLoaderManagers = new SparseArray<LoaderManagerImpl>();
         }
         LoaderManagerImpl lm = mAllLoaderManagers.get(index);
-        if (lm == null && create) {
-            lm = new LoaderManagerImpl(started);
-            mAllLoaderManagers.put(index, lm);
+        if (lm == null) {
+            if (create) {
+                lm = new LoaderManagerImpl(this, started);
+                mAllLoaderManagers.put(index, lm);
+            }
+        } else {
+            lm.updateActivity(this);
         }
         return lm;
     }
@@ -979,13 +985,16 @@
      */
     protected void onStart() {
         mCalled = true;
-        mStarted = true;
-        if (mLoaderManager != null) {
-            mLoaderManager.doStart();
-        } else if (!mCheckedForLoaderManager) {
-            mLoaderManager = getLoaderManager(-1, mStarted, false);
+        
+        if (!mLoadersStarted) {
+            mLoadersStarted = true;
+            if (mLoaderManager != null) {
+                mLoaderManager.doStart();
+            } else if (!mCheckedForLoaderManager) {
+                mLoaderManager = getLoaderManager(-1, mLoadersStarted, false);
+            }
+            mCheckedForLoaderManager = true;
         }
-        mCheckedForLoaderManager = true;
     }
 
     /**
@@ -4249,7 +4258,7 @@
     }
     
     final void performStart() {
-        mFragments.mStateSaved = false;
+        mFragments.noteStateNotSaved();
         mCalled = false;
         mFragments.execPendingActions();
         mInstrumentation.callActivityOnStart(this);
@@ -4267,7 +4276,7 @@
     }
     
     final void performRestart() {
-        mFragments.mStateSaved = false;
+        mFragments.noteStateNotSaved();
 
         synchronized (mManagedCursors) {
             final int N = mManagedCursors.size();
@@ -4347,8 +4356,8 @@
     }
     
     final void performStop() {
-        if (mStarted) {
-            mStarted = false;
+        if (mLoadersStarted) {
+            mLoadersStarted = false;
             if (mLoaderManager != null) {
                 if (!mChangingConfigurations) {
                     mLoaderManager.doStop();
@@ -4407,7 +4416,7 @@
         if (Config.LOGV) Log.v(
             TAG, "Dispatching result: who=" + who + ", reqCode=" + requestCode
             + ", resCode=" + resultCode + ", data=" + data);
-        mFragments.mStateSaved = false;
+        mFragments.noteStateNotSaved();
         if (who == null) {
             onActivityResult(requestCode, resultCode, data);
         } else {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f3f7ee7..2abe822 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1757,6 +1757,7 @@
         for (int i=0; i<N; i++) {
             Intent intent = intents.get(i);
             intent.setExtrasClassLoader(r.activity.getClassLoader());
+            r.activity.mFragments.noteStateNotSaved();
             mInstrumentation.callActivityOnNewIntent(r.activity, intent);
         }
     }
@@ -1767,11 +1768,13 @@
         if (r != null) {
             final boolean resumed = !r.paused;
             if (resumed) {
+                r.activity.mTemporaryPause = true;
                 mInstrumentation.callActivityOnPause(r.activity);
             }
             deliverNewIntents(r, intents);
             if (resumed) {
                 mInstrumentation.callActivityOnResume(r.activity);
+                r.activity.mTemporaryPause = false;
             }
         }
     }
@@ -2594,6 +2597,7 @@
                 try {
                     // Now we are idle.
                     r.activity.mCalled = false;
+                    r.activity.mTemporaryPause = true;
                     mInstrumentation.callActivityOnPause(r.activity);
                     if (!r.activity.mCalled) {
                         throw new SuperNotCalledException(
@@ -2614,6 +2618,7 @@
             deliverResults(r, res.results);
             if (resumed) {
                 mInstrumentation.callActivityOnResume(r.activity);
+                r.activity.mTemporaryPause = false;
             }
         }
     }
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 12bf7e5..3ec0912 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -403,7 +403,7 @@
     View mView;
     
     LoaderManagerImpl mLoaderManager;
-    boolean mStarted;
+    boolean mLoadersStarted;
     boolean mCheckedForLoaderManager;
     
     /**
@@ -728,7 +728,7 @@
             return mLoaderManager;
         }
         mCheckedForLoaderManager = true;
-        mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, true);
+        mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, true);
         return mLoaderManager;
     }
     
@@ -880,13 +880,16 @@
      */
     public void onStart() {
         mCalled = true;
-        mStarted = true;
-        if (!mCheckedForLoaderManager) {
-            mCheckedForLoaderManager = true;
-            mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false);
-        }
-        if (mLoaderManager != null) {
-            mLoaderManager.doStart();
+        
+        if (!mLoadersStarted) {
+            mLoadersStarted = true;
+            if (!mCheckedForLoaderManager) {
+                mCheckedForLoaderManager = true;
+                mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, false);
+            }
+            if (mLoaderManager != null) {
+                mLoaderManager.doStart();
+            }
         }
     }
     
@@ -971,7 +974,7 @@
         //        + " mLoaderManager=" + mLoaderManager);
         if (!mCheckedForLoaderManager) {
             mCheckedForLoaderManager = true;
-            mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false);
+            mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, false);
         }
         if (mLoaderManager != null) {
             mLoaderManager.doDestroy();
@@ -1182,7 +1185,7 @@
         }
         if (mLoaderManager != null) {
             writer.print(prefix); writer.print("mLoaderManager="); writer.print(mLoaderManager);
-                    writer.print(" mStarted="); writer.print(mStarted);
+                    writer.print(" mLoadersStarted="); writer.print(mLoadersStarted);
                     writer.print(" mCheckedForLoaderManager=");
                     writer.println(mCheckedForLoaderManager);
         }
@@ -1190,11 +1193,12 @@
 
     void performStop() {
         onStop();
-        if (mStarted) {
-            mStarted = false;
+        
+        if (mLoadersStarted) {
+            mLoadersStarted = false;
             if (!mCheckedForLoaderManager) {
                 mCheckedForLoaderManager = true;
-                mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false);
+                mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, false);
             }
             if (mLoaderManager != null) {
                 if (mActivity == null || !mActivity.mChangingConfigurations) {
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 37e7253..d9a6171 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -86,6 +86,15 @@
     /**
      * Start a series of edit operations on the Fragments associated with
      * this FragmentManager.
+     * 
+     * <p>Note: A fragment transaction can only be created/committed prior
+     * to an activity saving its state.  If you try to commit a transaction
+     * after {@link Activity#onSaveInstanceState Activity.onSaveInstanceState()}
+     * (and prior to a following {@link Activity#onStart Activity.onStart}
+     * or {@link Activity#onResume Activity.onResume()}, you will get an error.
+     * This is because the framework takes care of saving your current fragments
+     * in the state, and if changes are made after the state is saved then they
+     * will be lost.</p>
      */
     public FragmentTransaction openTransaction();
 
@@ -271,6 +280,7 @@
     
     boolean mNeedMenuInvalidate;
     boolean mStateSaved;
+    String mNoTransactionsBecause;
     
     // Temporary vars for state save and restore.
     Bundle mStateBundle = null;
@@ -843,6 +853,10 @@
             throw new IllegalStateException(
                     "Can not perform this action after onSaveInstanceState");
         }
+        if (mNoTransactionsBecause != null) {
+            throw new IllegalStateException(
+                    "Can not perform this action inside of " + mNoTransactionsBecause);
+        }
         synchronized (this) {
             if (mPendingActions == null) {
                 mPendingActions = new ArrayList<Runnable>();
@@ -1271,6 +1285,10 @@
         mActivity = activity;
     }
     
+    public void noteStateNotSaved() {
+        mStateSaved = false;
+    }
+    
     public void dispatchCreate() {
         mStateSaved = false;
         moveToState(Fragment.CREATED, false);
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index 28abcaa..4d4ea9a 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -40,7 +40,12 @@
         public Loader<D> onCreateLoader(int id, Bundle args);
 
         /**
-         * Called when a previously created loader has finished its load.
+         * Called when a previously created loader has finished its load.  Note
+         * that normally an application is <em>not</em> allowed to commit fragment
+         * transactions while in this call, since it can happen after an
+         * activity's state is saved.  See {@link FragmentManager#openTransaction()
+         * FragmentManager.openTransaction()} for further discussion on this.
+         * 
          * @param loader The Loader that has finished.
          * @param data The data generated by the Loader.
          */
@@ -102,6 +107,7 @@
     // previously run loader until the new loader's data is available.
     final SparseArray<LoaderInfo> mInactiveLoaders = new SparseArray<LoaderInfo>();
 
+    Activity mActivity;
     boolean mStarted;
     boolean mRetaining;
     boolean mRetainingStarted;
@@ -172,12 +178,12 @@
                         stop();
                     }
                 }
-                if (mStarted && mData != null && mCallbacks != null) {
+                if (mStarted && mData != null) {
                     // This loader was retained, and now at the point of
                     // finishing the retain we find we remain started, have
                     // our data, and the owner has a new callback...  so
                     // let's deliver the data now.
-                    mCallbacks.onLoadFinished(mLoader, mData);
+                    callOnLoadFinished(mLoader, mData);
                 }
             }
         }
@@ -219,9 +225,7 @@
             // Notify of the new data so the app can switch out the old data before
             // we try to destroy it.
             mData = data;
-            if (mCallbacks != null) {
-                mCallbacks.onLoadFinished(loader, data);
-            }
+            callOnLoadFinished(loader, data);
 
             if (DEBUG) Log.v(TAG, "onLoadFinished returned: " + this);
 
@@ -236,6 +240,23 @@
             }
         }
 
+        void callOnLoadFinished(Loader<Object> loader, Object data) {
+            if (mCallbacks != null) {
+                String lastBecause = null;
+                if (mActivity != null) {
+                    lastBecause = mActivity.mFragments.mNoTransactionsBecause;
+                    mActivity.mFragments.mNoTransactionsBecause = "onLoadFinished";
+                }
+                try {
+                    mCallbacks.onLoadFinished(loader, data);
+                } finally {
+                    if (mActivity != null) {
+                        mActivity.mFragments.mNoTransactionsBecause = lastBecause;
+                    }
+                }
+            }
+        }
+        
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder(64);
@@ -252,10 +273,15 @@
         }
     }
     
-    LoaderManagerImpl(boolean started) {
+    LoaderManagerImpl(Activity activity, boolean started) {
+        mActivity = activity;
         mStarted = started;
     }
     
+    void updateActivity(Activity activity) {
+        mActivity = activity;
+    }
+    
     private LoaderInfo createLoader(int id, Bundle args,
             LoaderManager.LoaderCallbacks<Object> callback) {
         LoaderInfo info = new LoaderInfo(id, args,  (LoaderManager.LoaderCallbacks<Object>)callback);
@@ -286,7 +312,7 @@
         
         if (info.mData != null && mStarted) {
             // If the loader has already generated its data, report it now.
-            info.mCallbacks.onLoadFinished(info.mLoader, info.mData);
+            info.callOnLoadFinished(info.mLoader, info.mData);
         }
         
         return (Loader<D>)info.mLoader;
@@ -348,7 +374,13 @@
  
     void doStart() {
         if (DEBUG) Log.v(TAG, "Starting: " + this);
-
+        if (mStarted) {
+            RuntimeException e = new RuntimeException("here");
+            e.fillInStackTrace();
+            Log.w(TAG, "Called doStart when already started: " + this, e);
+            return;
+        }
+        
         // Call out to sub classes so they can start their loaders
         // Let the existing loaders know that we want to be notified when a load is complete
         for (int i = mLoaders.size()-1; i >= 0; i--) {
@@ -359,6 +391,12 @@
     
     void doStop() {
         if (DEBUG) Log.v(TAG, "Stopping: " + this);
+        if (!mStarted) {
+            RuntimeException e = new RuntimeException("here");
+            e.fillInStackTrace();
+            Log.w(TAG, "Called doStop when not started: " + this, e);
+            return;
+        }
 
         for (int i = mLoaders.size()-1; i >= 0; i--) {
             mLoaders.valueAt(i).stop();
@@ -368,6 +406,12 @@
     
     void doRetain() {
         if (DEBUG) Log.v(TAG, "Retaining: " + this);
+        if (!mStarted) {
+            RuntimeException e = new RuntimeException("here");
+            e.fillInStackTrace();
+            Log.w(TAG, "Called doRetain when not started: " + this, e);
+            return;
+        }
 
         mRetaining = true;
         mStarted = false;
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index a19b132..6f4d098 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -37,8 +37,9 @@
  * each of which can hold one or more representations of an item of data.
  * For display to the user, it also has a label and iconic representation.</p>
  *
- * <p>A ClipData is a sub-class of {@link ClipDescription}, which describes
- * important meta-data about the clip.  In particular, its {@link #getMimeType(int)}
+ * <p>A ClipData contains a {@link ClipDescription}, which describes
+ * important meta-data about the clip.  In particular, its
+ * {@link ClipDescription#getMimeType(int) getDescription().getMimeType(int)}
  * must return correct MIME type(s) describing the data in the clip.  For help
  * in correctly constructing a clip with the correct MIME type, use
  * {@link #newPlainText(CharSequence, Bitmap, CharSequence)},
@@ -62,8 +63,8 @@
  * <p>If all you want is the textual representation of the clipped data, you
  * can use the convenience method {@link Item#coerceToText Item.coerceToText}.
  * In this case there is generally no need to worry about the MIME types
- * reported by {@link #getMimeType(int)}, since any clip item an always be
- * converted to a string.
+ * reported by {@link ClipDescription#getMimeType(int) getDescription().getMimeType(int)},
+ * since any clip item an always be converted to a string.
  *
  * <p>More complicated exchanges will be done through URIs, in particular
  * "content:" URIs.  A content URI allows the recipient of a ClippedData item
@@ -133,11 +134,16 @@
  * into an editor), then {@link Item#coerceToText(Context)} will ask the content
  * provider for the clip URI as text and successfully paste the entire note.
  */
-public class ClipData extends ClipDescription {
-    static final String[] MIMETYPES_TEXT_PLAIN = new String[] { MIMETYPE_TEXT_PLAIN };
-    static final String[] MIMETYPES_TEXT_URILIST = new String[] { MIMETYPE_TEXT_URILIST };
-    static final String[] MIMETYPES_TEXT_INTENT = new String[] { MIMETYPE_TEXT_INTENT };
+public class ClipData implements Parcelable {
+    static final String[] MIMETYPES_TEXT_PLAIN = new String[] {
+        ClipDescription.MIMETYPE_TEXT_PLAIN };
+    static final String[] MIMETYPES_TEXT_URILIST = new String[] {
+        ClipDescription.MIMETYPE_TEXT_URILIST };
+    static final String[] MIMETYPES_TEXT_INTENT = new String[] {
+        ClipDescription.MIMETYPE_TEXT_INTENT };
 
+    final ClipDescription mClipDescription;
+    
     final Bitmap mIcon;
 
     final ArrayList<Item> mItems = new ArrayList<Item>();
@@ -320,7 +326,7 @@
      * @param item The contents of the first item in the clip.
      */
     public ClipData(CharSequence label, String[] mimeTypes, Bitmap icon, Item item) {
-        super(label, mimeTypes);
+        mClipDescription = new ClipDescription(label, mimeTypes);
         if (item == null) {
             throw new NullPointerException("item is null");
         }
@@ -329,7 +335,25 @@
     }
 
     /**
-     * Create a new ClipData holding data of the type {@link #MIMETYPE_TEXT_PLAIN}.
+     * Create a new clip.
+     *
+     * @param description The ClipDescription describing the clip contents.
+     * @param icon Bitmap providing the user with an iconing representation of
+     * the clip.
+     * @param item The contents of the first item in the clip.
+     */
+    public ClipData(ClipDescription description, Bitmap icon, Item item) {
+        mClipDescription = description;
+        if (item == null) {
+            throw new NullPointerException("item is null");
+        }
+        mIcon = icon;
+        mItems.add(item);
+    }
+
+    /**
+     * Create a new ClipData holding data of the type
+     * {@link ClipDescription#MIMETYPE_TEXT_PLAIN}.
      *
      * @param label User-visible label for the clip data.
      * @param icon Iconic representation of the clip data.
@@ -342,7 +366,8 @@
     }
 
     /**
-     * Create a new ClipData holding an Intent with MIME type {@link #MIMETYPE_TEXT_INTENT}.
+     * Create a new ClipData holding an Intent with MIME type
+     * {@link ClipDescription#MIMETYPE_TEXT_INTENT}.
      *
      * @param label User-visible label for the clip data.
      * @param icon Iconic representation of the clip data.
@@ -358,7 +383,7 @@
      * Create a new ClipData holding a URI.  If the URI is a content: URI,
      * this will query the content provider for the MIME type of its data and
      * use that as the MIME type.  Otherwise, it will use the MIME type
-     * {@link #MIMETYPE_TEXT_URILIST}.
+     * {@link ClipDescription#MIMETYPE_TEXT_URILIST}.
      *
      * @param resolver ContentResolver used to get information about the URI.
      * @param label User-visible label for the clip data.
@@ -375,7 +400,7 @@
             mimeTypes = resolver.getStreamTypes(uri, "*/*");
             if (mimeTypes == null) {
                 if (realType != null) {
-                    mimeTypes = new String[] { realType, MIMETYPE_TEXT_URILIST };
+                    mimeTypes = new String[] { realType, ClipDescription.MIMETYPE_TEXT_URILIST };
                 }
             } else {
                 String[] tmp = new String[mimeTypes.length + (realType != null ? 2 : 1)];
@@ -385,7 +410,7 @@
                     i++;
                 }
                 System.arraycopy(mimeTypes, 0, tmp, i, mimeTypes.length);
-                tmp[i + mimeTypes.length] = MIMETYPE_TEXT_URILIST;
+                tmp[i + mimeTypes.length] = ClipDescription.MIMETYPE_TEXT_URILIST;
                 mimeTypes = tmp;
             }
         }
@@ -396,7 +421,8 @@
     }
 
     /**
-     * Create a new ClipData holding an URI with MIME type {@link #MIMETYPE_TEXT_URILIST}.
+     * Create a new ClipData holding an URI with MIME type
+     * {@link ClipDescription#MIMETYPE_TEXT_URILIST}.
      * Unlike {@link #newUri(ContentResolver, CharSequence, Bitmap, Uri)}, nothing
      * is inferred about the URI -- if it is a content: URI holding a bitmap,
      * the reported type will still be uri-list.  Use this with care!
@@ -411,6 +437,14 @@
         return new ClipData(label, MIMETYPES_TEXT_URILIST, icon, item);
     }
 
+    /**
+     * Return the {@link ClipDescription} associated with this data, describing
+     * what it contains.
+     */
+    public ClipDescription getDescription() {
+        return mClipDescription;
+    }
+    
     public void addItem(Item item) {
         if (item == null) {
             throw new NullPointerException("item is null");
@@ -437,7 +471,7 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        super.writeToParcel(dest, flags);
+        mClipDescription.writeToParcel(dest, flags);
         if (mIcon != null) {
             dest.writeInt(1);
             mIcon.writeToParcel(dest, flags);
@@ -465,7 +499,7 @@
     }
 
     ClipData(Parcel in) {
-        super(in);
+        mClipDescription = new ClipDescription(in);
         if (in.readInt() != 0) {
             mIcon = Bitmap.CREATOR.createFromParcel(in);
         } else {
diff --git a/core/java/android/nfc/ErrorCodes.java b/core/java/android/nfc/ErrorCodes.java
index 5b76d84..69329df 100644
--- a/core/java/android/nfc/ErrorCodes.java
+++ b/core/java/android/nfc/ErrorCodes.java
@@ -33,6 +33,34 @@
         }
     }
 
+    public static String asString(int code) {
+        switch (code) {
+            case SUCCESS: return "SUCCESS";
+            case ERROR_IO: return "IO";
+            case ERROR_CANCELLED: return "CANCELLED";
+            case ERROR_TIMEOUT: return "TIMEOUT";
+            case ERROR_BUSY: return "BUSY";
+            case ERROR_CONNECT: return "CONNECT/DISCONNECT";
+//            case ERROR_DISCONNECT: return "DISCONNECT";
+            case ERROR_READ: return "READ";
+            case ERROR_WRITE: return "WRITE";
+            case ERROR_INVALID_PARAM: return "INVALID_PARAM";
+            case ERROR_INSUFFICIENT_RESOURCES: return "INSUFFICIENT_RESOURCES";
+            case ERROR_SOCKET_CREATION: return "SOCKET_CREATION";
+            case ERROR_SOCKET_NOT_CONNECTED: return "SOCKET_NOT_CONNECTED";
+            case ERROR_BUFFER_TO_SMALL: return "BUFFER_TO_SMALL";
+            case ERROR_SAP_USED: return "SAP_USED";
+            case ERROR_SERVICE_NAME_USED: return "SERVICE_NAME_USED";
+            case ERROR_SOCKET_OPTIONS: return "SOCKET_OPTIONS";
+            case ERROR_NFC_ON: return "NFC_ON";
+            case ERROR_NOT_INITIALIZED: return "NOT_INITIALIZED";
+            case ERROR_SE_ALREADY_SELECTED: return "SE_ALREADY_SELECTED";
+            case ERROR_SE_CONNECTED: return "SE_CONNECTED";
+            case ERROR_NO_SE_CONNECTED: return "NO_SE_CONNECTED";
+            default: return "UNKNOWN ERROR";
+        }
+    }
+
     public static final int SUCCESS = 0;
 
     public static final int ERROR_IO = -1;
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index b6da308..b5e85a0 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -498,6 +498,7 @@
                     handleSinkPlayingStateChange(device, BluetoothA2dp.STATE_NOT_PLAYING,
                         BluetoothA2dp.STATE_PLAYING);
                 } else {
+                   mPlayingA2dpDevice = null;
                    int prevState = mAudioDevices.get(device);
                    handleSinkStateChange(device, prevState, state);
                 }
@@ -512,7 +513,6 @@
                 mSinkCount--;
             } else if (state == BluetoothA2dp.STATE_CONNECTED) {
                 mSinkCount ++;
-                mPlayingA2dpDevice = null;
             }
             mAudioDevices.put(device, state);
 
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 0e92eeb..e6d5984 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -114,6 +114,7 @@
     private int mTouchSlop;
     private int mMaximumVelocity;
     private VelocityTracker mVelocityTracker;
+    private boolean mTransitionIsSetup = false;
 
     private static HolographicHelper sHolographicHelper;
     private ImageView mHighlight;
@@ -225,6 +226,48 @@
         }
     }
 
+    private void setupStackSlider(View v, int mode) {
+        mStackSlider.setMode(mode);
+        if (v != null) {
+            mHighlight.setImageBitmap(sHolographicHelper.createOutline(v));
+            mHighlight.setRotation(v.getRotation());
+            mHighlight.setTranslationY(v.getTranslationY());
+            mHighlight.bringToFront();
+            v.bringToFront();
+            mStackSlider.setView(v);
+
+            v.setVisibility(VISIBLE);
+        }
+    }
+
+    @Override
+    @android.view.RemotableViewMethod
+    public void showNext() {
+        if (!mTransitionIsSetup) {
+            View v = getViewAtRelativeIndex(1);
+            if (v != null) {
+                setupStackSlider(v, StackSlider.NORMAL_MODE);
+                mStackSlider.setYProgress(0);
+                mStackSlider.setXProgress(0);
+            }
+        }
+        super.showNext();
+    }
+
+    @Override
+    @android.view.RemotableViewMethod
+    public void showPrevious() {
+        if (!mTransitionIsSetup) {
+            View v = getViewAtRelativeIndex(0);
+            if (v != null) {
+                setupStackSlider(v, StackSlider.NORMAL_MODE);
+                mStackSlider.setYProgress(1);
+                mStackSlider.setXProgress(0);
+            }
+        }
+        super.showPrevious();
+    }
+
     private void transformViewAtIndex(int index, View view) {
         float maxPerpectiveShift = mMeasuredHeight * PERSPECTIVE_SHIFT_FACTOR;
 
@@ -256,11 +299,12 @@
         super.showOnly(childIndex, animate, onLayout);
 
         // Here we need to make sure that the z-order of the children is correct
-	for (int i = mCurrentWindowEnd; i >= mCurrentWindowStart; i--) {
+        for (int i = mCurrentWindowEnd; i >= mCurrentWindowStart; i--) {
             int index = modulo(i, getWindowSize());
             View v = mViewsMap.get(index).view;
             if (v != null) v.bringToFront();
         }
+        mTransitionIsSetup = false;
     }
 
     private void updateChildTransforms() {
@@ -364,29 +408,24 @@
                 activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? 1 : 0;
             }
 
+            int stackMode;
             if (mLoopViews) {
-                mStackSlider.setMode(StackSlider.NORMAL_MODE);
+                stackMode = StackSlider.NORMAL_MODE;
             } else if (mCurrentWindowStartUnbounded + activeIndex == -1) {
                 activeIndex++;
-                mStackSlider.setMode(StackSlider.BEGINNING_OF_STACK_MODE);
+                stackMode = StackSlider.BEGINNING_OF_STACK_MODE;
             } else if (mCurrentWindowStartUnbounded + activeIndex == mAdapter.getCount() - 1) {
-                mStackSlider.setMode(StackSlider.END_OF_STACK_MODE);
+                stackMode = StackSlider.END_OF_STACK_MODE;
             } else {
-                mStackSlider.setMode(StackSlider.NORMAL_MODE);
+                stackMode = StackSlider.NORMAL_MODE;
             }
 
+            mTransitionIsSetup = stackMode == StackSlider.NORMAL_MODE;
+
             View v = getViewAtRelativeIndex(activeIndex);
             if (v == null) return;
 
-            mHighlight.setImageBitmap(sHolographicHelper.createOutline(v));
-            mHighlight.setRotation(v.getRotation());
-            mHighlight.setTranslationY(v.getTranslationY());
-            mHighlight.bringToFront();
-            v.bringToFront();
-            mStackSlider.setView(v);
-
-            if (swipeGestureType == GESTURE_SLIDE_DOWN)
-                v.setVisibility(VISIBLE);
+            setupStackSlider(v, stackMode);
 
             // We only register this gesture if we've made it this far without a problem
             mSwipeGestureType = swipeGestureType;
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index ff31dec..2949208 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -21,6 +21,7 @@
 import android.app.LocalActivityManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.util.AttributeSet;
@@ -63,6 +64,8 @@
     private OnTabChangeListener mOnTabChangeListener;
     private OnKeyListener mTabKeyListener;
 
+    private int mTabLayoutId;
+
     public TabHost(Context context) {
         super(context);
         initTabHost();
@@ -70,6 +73,18 @@
 
     public TabHost(Context context, AttributeSet attrs) {
         super(context, attrs);
+
+        TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.TabWidget,
+                com.android.internal.R.attr.tabWidgetStyle, 0);
+
+        mTabLayoutId = a.getResourceId(R.styleable.TabWidget_tabLayout, 0);
+        if (mTabLayoutId == 0) {
+            throw new IllegalArgumentException("Invalid TabWidget tabLayout id");
+        }
+
+        a.recycle();
+
         initTabHost();
     }
 
@@ -214,6 +229,7 @@
         if (tabSpec.mIndicatorStrategy instanceof ViewIndicatorStrategy) {
             mTabWidget.setStripEnabled(false);
         }
+
         mTabWidget.addView(tabIndicator);
         mTabSpecs.add(tabSpec);
 
@@ -513,7 +529,7 @@
             final Context context = getContext();
             LayoutInflater inflater =
                     (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            View tabIndicator = inflater.inflate(R.layout.tab_indicator,
+            View tabIndicator = inflater.inflate(mTabLayoutId,
                     mTabWidget, // tab widget is the parent
                     false); // no inflate params
 
@@ -525,7 +541,7 @@
                 tabIndicator.setBackgroundResource(R.drawable.tab_indicator_v4);
                 tv.setTextColor(context.getResources().getColorStateList(R.color.tab_indicator_text_v4));
             }
-            
+
             return tabIndicator;
         }
     }
@@ -547,7 +563,7 @@
             final Context context = getContext();
             LayoutInflater inflater =
                     (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            View tabIndicator = inflater.inflate(R.layout.tab_indicator,
+            View tabIndicator = inflater.inflate(mTabLayoutId,
                     mTabWidget, // tab widget is the parent
                     false); // no inflate params
 
@@ -555,14 +571,17 @@
             tv.setText(mLabel);
 
             final ImageView iconView = (ImageView) tabIndicator.findViewById(R.id.icon);
-            iconView.setImageDrawable(mIcon);
+            if (mIcon != null) {
+                iconView.setImageDrawable(mIcon);
+                iconView.setVisibility(VISIBLE);
+            }
 
             if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
                 // Donut apps get old color scheme
                 tabIndicator.setBackgroundResource(R.drawable.tab_indicator_v4);
                 tv.setTextColor(context.getResources().getColorStateList(R.color.tab_indicator_text_v4));
             }
-            
+
             return tabIndicator;
         }
     }
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 0469e7b..36adacd 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -120,7 +120,9 @@
 
         final Context context = mContext;
         final Resources resources = context.getResources();
-        
+
+        // Tests the target Sdk version, as set in the Manifest. Could not be set using styles.xml
+        // in a values-v? directory which targets the current platform Sdk version instead.
         if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
             // Donut apps get old color scheme
             if (mLeftStrip == null) {
@@ -131,16 +133,6 @@
                 mRightStrip = resources.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_right_v4);
             }
-        } else {
-            // Use modern color scheme for Eclair and beyond
-            if (mLeftStrip == null) {
-                mLeftStrip = resources.getDrawable(
-                        com.android.internal.R.drawable.tab_bottom_left);
-            }
-            if (mRightStrip == null) {
-                mRightStrip = resources.getDrawable(
-                        com.android.internal.R.drawable.tab_bottom_right);
-            }
         }
 
         // Deal with focus, as we don't want the focus to go by default
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 09563fc..6897537 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7142,6 +7142,7 @@
                     case Gravity.RIGHT:
                         return 0.0f;
                     case Gravity.CENTER_HORIZONTAL:
+                    case Gravity.FILL_HORIZONTAL:
                         return (mLayout.getLineWidth(0) - ((mRight - mLeft) -
                                 getCompoundPaddingLeft() - getCompoundPaddingRight())) /
                                 getHorizontalFadingEdgeLength();
diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp
index f3be8b0..e2a959d 100644
--- a/core/jni/android/graphics/ColorFilter.cpp
+++ b/core/jni/android/graphics/ColorFilter.cpp
@@ -24,6 +24,7 @@
 #include "SkPorterDuff.h"
 
 #include <SkiaColorFilter.h>
+#include <Caches.h>
 
 namespace android {
 
@@ -32,28 +33,37 @@
 class SkColorFilterGlue {
 public:
     static void finalizer(JNIEnv* env, jobject clazz, SkColorFilter* obj, SkiaColorFilter* f) {
-        delete f;
         obj->safeUnref();
+        // f == NULL when not !USE_OPENGL_RENDERER, so no need to delete outside the ifdef
+#ifdef USE_OPENGL_RENDERER
+        if (android::uirenderer::Caches::hasInstance()) {
+            android::uirenderer::Caches::getInstance().resourceCache.destructor(f);
+        } else {
+            delete f;
+        }
+#endif
     }
 
-    static SkiaColorFilter* glCreatePorterDuffFilter(JNIEnv* env, jobject, jint srcColor,
-            SkPorterDuff::Mode mode) {
+    static SkiaColorFilter* glCreatePorterDuffFilter(JNIEnv* env, jobject, SkColorFilter *skFilter,
+            jint srcColor, SkPorterDuff::Mode mode) {
 #ifdef USE_OPENGL_RENDERER
-        return new SkiaBlendFilter(srcColor, SkPorterDuff::ToXfermodeMode(mode));
+        return new SkiaBlendFilter(skFilter, srcColor, SkPorterDuff::ToXfermodeMode(mode));
 #else
         return NULL;
 #endif
     }
 
-    static SkiaColorFilter* glCreateLightingFilter(JNIEnv* env, jobject, jint mul, jint add) {
+    static SkiaColorFilter* glCreateLightingFilter(JNIEnv* env, jobject, SkColorFilter *skFilter,
+            jint mul, jint add) {
 #ifdef USE_OPENGL_RENDERER
-        return new SkiaLightingFilter(mul, add);
+        return new SkiaLightingFilter(skFilter, mul, add);
 #else
         return NULL;
 #endif
     }
 
-    static SkiaColorFilter* glCreateColorMatrixFilter(JNIEnv* env, jobject, jfloatArray jarray) {
+    static SkiaColorFilter* glCreateColorMatrixFilter(JNIEnv* env, jobject, SkColorFilter *skFilter,
+            jfloatArray jarray) {
 #ifdef USE_OPENGL_RENDERER
         AutoJavaFloatArray autoArray(env, jarray, 20);
         const float* src = autoArray.ptr();
@@ -70,7 +80,7 @@
         colorVector[2] = src[14];
         colorVector[3] = src[19];
 
-        return new SkiaColorMatrixFilter(colorMatrix, colorVector);
+        return new SkiaColorMatrixFilter(skFilter, colorMatrix, colorVector);
 #else
         return NULL;
 #endif
@@ -107,17 +117,17 @@
 
 static JNINativeMethod porterduff_methods[] = {
     { "native_CreatePorterDuffFilter", "(II)I", (void*) SkColorFilterGlue::CreatePorterDuffFilter   },
-    { "nCreatePorterDuffFilter",       "(II)I", (void*) SkColorFilterGlue::glCreatePorterDuffFilter }
+    { "nCreatePorterDuffFilter",       "(III)I", (void*) SkColorFilterGlue::glCreatePorterDuffFilter }
 };
 
 static JNINativeMethod lighting_methods[] = {
     { "native_CreateLightingFilter", "(II)I", (void*) SkColorFilterGlue::CreateLightingFilter   },
-    { "nCreateLightingFilter",       "(II)I", (void*) SkColorFilterGlue::glCreateLightingFilter },
+    { "nCreateLightingFilter",       "(III)I", (void*) SkColorFilterGlue::glCreateLightingFilter },
 };
 
 static JNINativeMethod colormatrix_methods[] = {
     { "nativeColorMatrixFilter", "([F)I", (void*) SkColorFilterGlue::CreateColorMatrixFilter   },
-    { "nColorMatrixFilter",      "([F)I", (void*) SkColorFilterGlue::glCreateColorMatrixFilter }
+    { "nColorMatrixFilter",      "(I[F)I", (void*) SkColorFilterGlue::glCreateColorMatrixFilter }
 };
 
 #define REG(env, name, array) \
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 79051c2..4be1321 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -58,6 +58,8 @@
 #ifdef USE_OPENGL_RENDERER
     if (android::uirenderer::Caches::hasInstance()) {
         android::uirenderer::Caches::getInstance().resourceCache.destructor(skiaShader);
+    } else {
+        delete skiaShader;
     }
 #endif
 }
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 45fd5a0..a586f49 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -1029,7 +1029,7 @@
 
 #define FIND_CLASS(var, className) \
         var = env->FindClass(className); \
-        LOG_FATAL_IF(! var, "Unable to find class " className); \
+        LOG_FATAL_IF(! var, "Unable to find class %s", className); \
         var = jclass(env->NewGlobalRef(var));
 
 #define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index defd0a0..a024420 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -25,6 +25,7 @@
 #include "wifi.h"
 
 #define WIFI_PKG_NAME "android/net/wifi/WifiNative"
+#define BUF_SIZE 256
 
 namespace android {
 
@@ -67,7 +68,7 @@
 
 static jint doIntCommand(const char *cmd)
 {
-    char reply[256];
+    char reply[BUF_SIZE];
 
     if (doCommand(cmd, reply, sizeof(reply)) != 0) {
         return (jint)-1;
@@ -78,7 +79,7 @@
 
 static jboolean doBooleanCommand(const char *cmd, const char *expect)
 {
-    char reply[256];
+    char reply[BUF_SIZE];
 
     if (doCommand(cmd, reply, sizeof(reply)) != 0) {
         return (jboolean)JNI_FALSE;
@@ -137,7 +138,7 @@
 
 static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject clazz)
 {
-    char buf[256];
+    char buf[BUF_SIZE];
 
     int nread = ::wifi_wait_for_event(buf, sizeof buf);
     if (nread > 0) {
@@ -159,7 +160,7 @@
 
 static jboolean android_net_wifi_wpsPbcCommand(JNIEnv* env, jobject clazz, jstring bssid)
 {
-    char cmdstr[50];
+    char cmdstr[BUF_SIZE];
     jboolean isCopy;
 
     const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy);
@@ -172,9 +173,9 @@
     return doBooleanCommand(cmdstr, "OK");
 }
 
-static jboolean android_net_wifi_wpsPinCommand(JNIEnv* env, jobject clazz, jstring bssid, int apPin)
+static jboolean android_net_wifi_wpsPinFromAccessPointCommand(JNIEnv* env, jobject clazz, jstring bssid, int apPin)
 {
-    char cmdstr[50];
+    char cmdstr[BUF_SIZE];
     jboolean isCopy;
 
     const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy);
@@ -187,13 +188,29 @@
     return doBooleanCommand(cmdstr, "OK");
 }
 
+static jint android_net_wifi_wpsPinFromDeviceCommand(JNIEnv* env, jobject clazz, jstring bssid)
+{
+    char cmdstr[BUF_SIZE];
+    jboolean isCopy;
+
+    const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy);
+    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "WPS_PIN %s", bssidStr);
+    env->ReleaseStringUTFChars(bssid, bssidStr);
+
+    if ((numWritten == -1) || (numWritten >= (int)sizeof(cmdstr))) {
+        return false;
+    }
+    return doIntCommand(cmdstr);
+}
+
+
 static jboolean android_net_wifi_setNetworkVariableCommand(JNIEnv* env,
                                                            jobject clazz,
                                                            jint netId,
                                                            jstring name,
                                                            jstring value)
 {
-    char cmdstr[256];
+    char cmdstr[BUF_SIZE];
     jboolean isCopy;
 
     const char *nameStr = env->GetStringUTFChars(name, &isCopy);
@@ -216,7 +233,7 @@
                                                           jint netId,
                                                           jstring name)
 {
-    char cmdstr[256];
+    char cmdstr[BUF_SIZE];
     jboolean isCopy;
 
     const char *nameStr = env->GetStringUTFChars(name, &isCopy);
@@ -234,7 +251,7 @@
 
 static jboolean android_net_wifi_removeNetworkCommand(JNIEnv* env, jobject clazz, jint netId)
 {
-    char cmdstr[256];
+    char cmdstr[BUF_SIZE];
 
     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "REMOVE_NETWORK %d", netId);
     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
@@ -247,7 +264,7 @@
                                                   jint netId,
                                                   jboolean disableOthers)
 {
-    char cmdstr[256];
+    char cmdstr[BUF_SIZE];
     const char *cmd = disableOthers ? "SELECT_NETWORK" : "ENABLE_NETWORK";
 
     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "%s %d", cmd, netId);
@@ -258,7 +275,7 @@
 
 static jboolean android_net_wifi_disableNetworkCommand(JNIEnv* env, jobject clazz, jint netId)
 {
-    char cmdstr[256];
+    char cmdstr[BUF_SIZE];
 
     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DISABLE_NETWORK %d", netId);
     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
@@ -352,7 +369,7 @@
 
 static jint android_net_wifi_getRssiHelper(const char *cmd)
 {
-    char reply[256];
+    char reply[BUF_SIZE];
     int rssi = -200;
 
     if (doCommand(cmd, reply, sizeof(reply)) != 0) {
@@ -391,7 +408,7 @@
 
 static jint android_net_wifi_getLinkSpeedCommand(JNIEnv* env, jobject clazz)
 {
-    char reply[256];
+    char reply[BUF_SIZE];
     int linkspeed;
 
     if (doCommand("DRIVER LINKSPEED", reply, sizeof(reply)) != 0) {
@@ -405,8 +422,8 @@
 
 static jstring android_net_wifi_getMacAddressCommand(JNIEnv* env, jobject clazz)
 {
-    char reply[256];
-    char buf[256];
+    char reply[BUF_SIZE];
+    char buf[BUF_SIZE];
 
     if (doCommand("DRIVER MACADDR", reply, sizeof(reply)) != 0) {
         return env->NewStringUTF(NULL);
@@ -421,7 +438,7 @@
 
 static jboolean android_net_wifi_setPowerModeCommand(JNIEnv* env, jobject clazz, jint mode)
 {
-    char cmdstr[256];
+    char cmdstr[BUF_SIZE];
 
     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER POWERMODE %d", mode);
     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
@@ -431,7 +448,7 @@
 
 static jint android_net_wifi_getPowerModeCommand(JNIEnv* env, jobject clazz)
 {
-    char reply[256];
+    char reply[BUF_SIZE];
     int power;
 
     if (doCommand("DRIVER GETPOWER", reply, sizeof(reply)) != 0) {
@@ -469,7 +486,7 @@
 
 static jboolean android_net_wifi_setNumAllowedChannelsCommand(JNIEnv* env, jobject clazz, jint numChannels)
 {
-    char cmdstr[256];
+    char cmdstr[BUF_SIZE];
 
     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER SCAN-CHANNELS %u", numChannels);
     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
@@ -479,7 +496,7 @@
 
 static jint android_net_wifi_getNumAllowedChannelsCommand(JNIEnv* env, jobject clazz)
 {
-    char reply[256];
+    char reply[BUF_SIZE];
     int numChannels;
 
     if (doCommand("DRIVER SCAN-CHANNELS", reply, sizeof(reply)) != 0) {
@@ -495,7 +512,7 @@
 
 static jboolean android_net_wifi_setBluetoothCoexistenceModeCommand(JNIEnv* env, jobject clazz, jint mode)
 {
-    char cmdstr[256];
+    char cmdstr[BUF_SIZE];
 
     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER BTCOEXMODE %d", mode);
     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
@@ -505,7 +522,7 @@
 
 static jboolean android_net_wifi_setBluetoothCoexistenceScanModeCommand(JNIEnv* env, jobject clazz, jboolean setCoexScanMode)
 {
-    char cmdstr[256];
+    char cmdstr[BUF_SIZE];
 
     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER BTCOEXSCAN-%s", setCoexScanMode ? "START" : "STOP");
     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
@@ -527,7 +544,7 @@
 
 static jboolean android_net_wifi_setScanResultHandlingCommand(JNIEnv* env, jobject clazz, jint mode)
 {
-    char cmdstr[256];
+    char cmdstr[BUF_SIZE];
 
     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "AP_SCAN %d", mode);
     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
@@ -537,7 +554,7 @@
 
 static jboolean android_net_wifi_addToBlacklistCommand(JNIEnv* env, jobject clazz, jstring bssid)
 {
-    char cmdstr[256];
+    char cmdstr[BUF_SIZE];
     jboolean isCopy;
 
     const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy);
@@ -554,6 +571,15 @@
     return doBooleanCommand("BLACKLIST clear", "OK");
 }
 
+static jboolean android_net_wifi_setSuspendOptimizationsCommand(JNIEnv* env, jobject clazz, jboolean enabled)
+{
+    char cmdstr[BUF_SIZE];
+
+    snprintf(cmdstr, sizeof(cmdstr), "DRIVER SETSUSPENDOPT %d", enabled ? 0 : 1);
+    return doBooleanCommand(cmdstr, "OK");
+}
+
+
 static jboolean android_net_wifi_doDhcpRequest(JNIEnv* env, jobject clazz, jobject info)
 {
     jint ipaddr, gateway, mask, dns1, dns2, server, lease;
@@ -636,7 +662,12 @@
     { "addToBlacklistCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_addToBlacklistCommand },
     { "clearBlacklistCommand", "()Z", (void*) android_net_wifi_clearBlacklistCommand },
     { "startWpsPbcCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_wpsPbcCommand },
-    { "startWpsPinCommand", "(Ljava/lang/String;I)Z", (void*) android_net_wifi_wpsPinCommand },
+    { "startWpsWithPinFromAccessPointCommand", "(Ljava/lang/String;I)Z",
+        (void*) android_net_wifi_wpsPinFromAccessPointCommand },
+    { "startWpsWithPinFromDeviceCommand", "(Ljava/lang/String;)I",
+        (void*) android_net_wifi_wpsPinFromDeviceCommand },
+    { "setSuspendOptimizationsCommand", "(Z)Z",
+        (void*) android_net_wifi_setSuspendOptimizationsCommand},
     { "doDhcpRequest", "(Landroid/net/DhcpInfo;)Z", (void*) android_net_wifi_doDhcpRequest },
     { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_wifi_getDhcpError },
 };
diff --git a/core/res/res/drawable-hdpi/tab_arrow_left_holo_dark.png b/core/res/res/drawable-hdpi/tab_arrow_left_holo_dark.png
deleted file mode 100644
index cfd6f78..0000000
--- a/core/res/res/drawable-hdpi/tab_arrow_left_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_arrow_left_holo_light.png b/core/res/res/drawable-hdpi/tab_arrow_left_holo_light.png
deleted file mode 100644
index 036aa8c..0000000
--- a/core/res/res/drawable-hdpi/tab_arrow_left_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_arrow_right_holo_dark.png b/core/res/res/drawable-hdpi/tab_arrow_right_holo_dark.png
deleted file mode 100644
index b226038..0000000
--- a/core/res/res/drawable-hdpi/tab_arrow_right_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_arrow_right_holo_light.png b/core/res/res/drawable-hdpi/tab_arrow_right_holo_light.png
deleted file mode 100644
index 0e5fbe6..0000000
--- a/core/res/res/drawable-hdpi/tab_arrow_right_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_bottom_holo.9.png b/core/res/res/drawable-hdpi/tab_bottom_holo.9.png
new file mode 100644
index 0000000..ec9fa8d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_bottom_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_divider_holo_dark.png b/core/res/res/drawable-hdpi/tab_divider_holo_dark.png
deleted file mode 100644
index 112cb04..0000000
--- a/core/res/res/drawable-hdpi/tab_divider_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_divider_holo_light.png b/core/res/res/drawable-hdpi/tab_divider_holo_light.png
deleted file mode 100644
index 1bf4d38..0000000
--- a/core/res/res/drawable-hdpi/tab_divider_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_selected_focused_holo.9.png b/core/res/res/drawable-hdpi/tab_selected_focused_holo.9.png
new file mode 100644
index 0000000..1ba35d5
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_selected_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_selected_holo.9.png b/core/res/res/drawable-hdpi/tab_selected_holo.9.png
new file mode 100644
index 0000000..ef913cc
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_selected_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png b/core/res/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png
new file mode 100644
index 0000000..d7e9688
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_selected_pressed_holo.9.png b/core/res/res/drawable-hdpi/tab_selected_pressed_holo.9.png
new file mode 100644
index 0000000..b8b1fcf
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_selected_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_selector_holo_dark.9.png b/core/res/res/drawable-hdpi/tab_selector_holo_dark.9.png
deleted file mode 100644
index f01b9bc..0000000
--- a/core/res/res/drawable-hdpi/tab_selector_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_strip_holo.9.png b/core/res/res/drawable-hdpi/tab_strip_holo.9.png
deleted file mode 100644
index d937f6b..0000000
--- a/core/res/res/drawable-hdpi/tab_strip_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_unselected_focused_holo.9.png b/core/res/res/drawable-hdpi/tab_unselected_focused_holo.9.png
new file mode 100644
index 0000000..256e8e7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_unselected_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_unselected_holo.9.png b/core/res/res/drawable-hdpi/tab_unselected_holo.9.png
new file mode 100644
index 0000000..eaa306a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_unselected_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png b/core/res/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png
new file mode 100644
index 0000000..d17b820
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_unselected_pressed_holo.9.png b/core/res/res/drawable-hdpi/tab_unselected_pressed_holo.9.png
new file mode 100644
index 0000000..a344994
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_unselected_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_arrow_left_holo_dark.png b/core/res/res/drawable-mdpi/tab_arrow_left_holo_dark.png
deleted file mode 100644
index 4f8bafe..0000000
--- a/core/res/res/drawable-mdpi/tab_arrow_left_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_arrow_left_holo_light.png b/core/res/res/drawable-mdpi/tab_arrow_left_holo_light.png
deleted file mode 100644
index 8e225fc..0000000
--- a/core/res/res/drawable-mdpi/tab_arrow_left_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_arrow_right_holo_dark.png b/core/res/res/drawable-mdpi/tab_arrow_right_holo_dark.png
deleted file mode 100644
index 0a8006d..0000000
--- a/core/res/res/drawable-mdpi/tab_arrow_right_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_arrow_right_holo_light.png b/core/res/res/drawable-mdpi/tab_arrow_right_holo_light.png
deleted file mode 100644
index 85aae47..0000000
--- a/core/res/res/drawable-mdpi/tab_arrow_right_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_bottom_holo.9.png b/core/res/res/drawable-mdpi/tab_bottom_holo.9.png
new file mode 100644
index 0000000..1e40b9c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_bottom_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_divider_holo_dark.png b/core/res/res/drawable-mdpi/tab_divider_holo_dark.png
deleted file mode 100644
index 89d7b8b..0000000
--- a/core/res/res/drawable-mdpi/tab_divider_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_divider_holo_light.png b/core/res/res/drawable-mdpi/tab_divider_holo_light.png
deleted file mode 100644
index 878b2b4..0000000
--- a/core/res/res/drawable-mdpi/tab_divider_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_focused_holo.9.png b/core/res/res/drawable-mdpi/tab_focused_holo.9.png
new file mode 100644
index 0000000..187d8c5
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_pressed_holo.9.png b/core/res/res/drawable-mdpi/tab_pressed_holo.9.png
new file mode 100644
index 0000000..a76fbae
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_selected_focused_holo.9.png b/core/res/res/drawable-mdpi/tab_selected_focused_holo.9.png
new file mode 100644
index 0000000..9a33cd2
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_selected_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_selected_holo.9.png b/core/res/res/drawable-mdpi/tab_selected_holo.9.png
new file mode 100644
index 0000000..e029e57
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_selected_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png b/core/res/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png
new file mode 100644
index 0000000..285116e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_selected_pressed_holo.9.png b/core/res/res/drawable-mdpi/tab_selected_pressed_holo.9.png
new file mode 100644
index 0000000..dadefa7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_selected_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_selector_holo_dark.9.png b/core/res/res/drawable-mdpi/tab_selector_holo_dark.9.png
deleted file mode 100644
index 30d30df..0000000
--- a/core/res/res/drawable-mdpi/tab_selector_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_unselected_focused_holo.9.png b/core/res/res/drawable-mdpi/tab_unselected_focused_holo.9.png
new file mode 100644
index 0000000..032a992
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_unselected_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_unselected_holo.9.png b/core/res/res/drawable-mdpi/tab_unselected_holo.9.png
new file mode 100644
index 0000000..848f3f1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_unselected_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png b/core/res/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png
new file mode 100644
index 0000000..3845135
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_unselected_pressed_holo.9.png b/core/res/res/drawable-mdpi/tab_unselected_pressed_holo.9.png
new file mode 100644
index 0000000..23fd8c9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_unselected_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable/tab_bottom_right.xml b/core/res/res/drawable/tab_bottom_right.xml
index f7f5c2f..450c461 100644
--- a/core/res/res/drawable/tab_bottom_right.xml
+++ b/core/res/res/drawable/tab_bottom_right.xml
@@ -16,6 +16,6 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true" android:drawable="@drawable/tab_press_bar_right"/>
-    <item android:state_focused="false" android:state_pressed="false" android:drawable="@drawable/tab_selected_bar_right"/>
-    <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/tab_focus_bar_right"/>
+    <item android:state_focused="false" android:drawable="@drawable/tab_selected_bar_right"/>
+    <item android:state_focused="true" android:drawable="@drawable/tab_focus_bar_right"/>
 </selector>
diff --git a/core/res/res/drawable/tab_indicator_holo.xml b/core/res/res/drawable/tab_indicator_holo.xml
new file mode 100644
index 0000000..0d46e0c
--- /dev/null
+++ b/core/res/res/drawable/tab_indicator_holo.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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
+  
+          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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- Non focused states -->
+    <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected_holo" />
+    <item android:state_focused="false" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/tab_selected_holo" />
+
+    <!-- Focused states -->
+    <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected_focused_holo" />
+    <item android:state_focused="true" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/tab_selected_focused_holo" />
+
+    <!-- Pressed -->
+    <!--    Non focused states -->
+    <item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_holo" />
+    <item android:state_focused="false" android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_holo" />
+
+    <!--    Focused states -->
+    <item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_focused_holo" />
+    <item android:state_focused="true" android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_focused_holo" />
+</selector>
diff --git a/core/res/res/layout/tab_indicator.xml b/core/res/res/layout/tab_indicator.xml
index 71e4001..bc657c3 100644
--- a/core/res/res/layout/tab_indicator.xml
+++ b/core/res/res/layout/tab_indicator.xml
@@ -20,7 +20,6 @@
     android:layout_weight="1"
     android:layout_marginLeft="-3dip"
     android:layout_marginRight="-3dip"
-    android:orientation="vertical"
     android:background="@android:drawable/tab_indicator">
 
     <ImageView android:id="@+id/icon"
diff --git a/core/res/res/layout/tab_indicator_holo.xml b/core/res/res/layout/tab_indicator_holo.xml
new file mode 100644
index 0000000..d37476b
--- /dev/null
+++ b/core/res/res/layout/tab_indicator_holo.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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
+  
+          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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="56dip"
+    android:layout_weight="0"
+    android:layout_marginLeft="0dip"
+    android:layout_marginRight="0dip"
+    android:background="@android:drawable/tab_indicator_holo">
+
+    <View android:id="@+id/tab_indicator_left_spacer"
+        android:layout_width="16dip"
+        android:layout_height="0dip" />
+
+    <ImageView android:id="@+id/icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerVertical="true"
+        android:visibility="gone"
+        android:layout_toRightOf="@id/tab_indicator_left_spacer"
+        android:paddingRight="8dip" />
+
+    <TextView android:id="@+id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerVertical="true"
+        android:layout_toRightOf="@id/icon"
+        android:paddingLeft="0dip"
+        android:paddingRight="16dip"
+        style="?android:attr/tabWidgetStyle" />
+
+</RelativeLayout>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d5f1610..dab627c 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2137,6 +2137,8 @@
         <attr name="tabStripLeft" format="reference" />
         <!-- Drawable used to draw the right part of the strip underneath the tabs. -->
         <attr name="tabStripRight" format="reference" />
+        <!-- Layout used to organize each tab's content. -->
+        <attr name="tabLayout" format="reference" />
     </declare-styleable>
     <declare-styleable name="TextAppearance">
         <!-- Text color. -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index c441f5a..76a3c34 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -560,6 +560,12 @@
         <item name="android:textAppearance">@style/TextAppearance.Widget.TabWidget</item>
         <item name="ellipsize">marquee</item>
         <item name="singleLine">true</item>
+        <item name="android:tabStripLeft">@android:drawable/tab_bottom_left</item>
+        <item name="android:tabStripRight">@android:drawable/tab_bottom_right</item>
+        <item name="android:tabStripEnabled">true</item>
+        <item name="android:divider">@null</item>
+        <item name="android:gravity">fill_horizontal|center_vertical</item>
+        <item name="android:tabLayout">@android:layout/tab_indicator</item>
     </style>
 
     <style name="Widget.Gallery">
@@ -1070,7 +1076,7 @@
     </style>
 
     <style name="TextAppearance.Holo.Widget.TabWidget">
-        <item name="android:textSize">14sp</item>
+        <item name="android:textSize">18sp</item>
         <item name="android:textStyle">normal</item>
         <item name="android:textColor">@android:color/tab_indicator_text</item>
     </style>
@@ -1421,6 +1427,13 @@
     </style>
 
     <style name="Widget.Holo.TabWidget" parent="Widget.TabWidget">
+        <item name="android:textAppearance">@style/TextAppearance.Holo.Widget.TabWidget</item>
+        <item name="android:tabStripLeft">@null</item>
+        <item name="android:tabStripRight">@null</item>
+        <item name="android:tabStripEnabled">false</item>
+        <item name="android:divider">@null</item>
+        <item name="android:gravity">left|center_vertical</item>
+        <item name="android:tabLayout">@android:layout/tab_indicator_holo</item>
     </style>
 
     <style name="Widget.Holo.WebTextView" parent="Widget.WebTextView">
@@ -1693,7 +1706,7 @@
     <style name="Widget.Holo.Light.CompoundButton.Star" parent="Widget.CompoundButton.Star">
     </style>
 
-    <style name="Widget.Holo.Light.TabWidget" parent="Widget.TabWidget">
+    <style name="Widget.Holo.Light.TabWidget" parent="Widget.Holo.TabWidget">
     </style>
 
     <style name="Widget.Holo.Light.WebTextView" parent="Widget.WebTextView">
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index 843dddb..cf9bab12f 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -28,25 +28,10 @@
 using namespace android;
 
 #define SUCCESS 0
-#define DRM_DIRECTORY_PERMISSION 0700
-#define DRM_PLUGINS_ROOT "/data/drm/plugins"
-#define DRM_PLUGINS_NATIVE "/data/drm/plugins/native"
-#define DRM_PLUGINS_NATIVE_DATABASES "/data/drm/plugins/native/databases"
 
 void DrmManagerService::instantiate() {
     LOGV("instantiate");
-
-    int res = mkdir(DRM_PLUGINS_ROOT, DRM_DIRECTORY_PERMISSION);
-    if (SUCCESS == res || EEXIST == errno) {
-        res = mkdir(DRM_PLUGINS_NATIVE, DRM_DIRECTORY_PERMISSION);
-        if (SUCCESS == res || EEXIST == errno) {
-            res = mkdir(DRM_PLUGINS_NATIVE_DATABASES, DRM_DIRECTORY_PERMISSION);
-            if (SUCCESS == res || EEXIST == errno) {
-                defaultServiceManager()
-                    ->addService(String16("drm.drmManager"), new DrmManagerService());
-            }
-        }
-    }
+    defaultServiceManager()->addService(String16("drm.drmManager"), new DrmManagerService());
 }
 
 DrmManagerService::DrmManagerService() {
diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java
index 245c615..4f32342 100644
--- a/graphics/java/android/graphics/ColorMatrixColorFilter.java
+++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java
@@ -27,7 +27,7 @@
     public ColorMatrixColorFilter(ColorMatrix matrix) {
         final float[] colorMatrix = matrix.getArray();
         native_instance = nativeColorMatrixFilter(colorMatrix);
-        nativeColorFilter = nColorMatrixFilter(colorMatrix);
+        nativeColorFilter = nColorMatrixFilter(native_instance, colorMatrix);
     }
 
     /**
@@ -42,9 +42,9 @@
             throw new ArrayIndexOutOfBoundsException();
         }
         native_instance = nativeColorMatrixFilter(array);
-        nativeColorFilter = nColorMatrixFilter(array);
+        nativeColorFilter = nColorMatrixFilter(native_instance, array);
     }
 
     private static native int nativeColorMatrixFilter(float[] array);
-    private static native int nColorMatrixFilter(float[] array);
+    private static native int nColorMatrixFilter(int nativeFilter, float[] array);
 }
diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java
index 715ce86..c621de6 100644
--- a/graphics/java/android/graphics/LightingColorFilter.java
+++ b/graphics/java/android/graphics/LightingColorFilter.java
@@ -30,9 +30,9 @@
      */
     public LightingColorFilter(int mul, int add) {
         native_instance = native_CreateLightingFilter(mul, add);
-        nativeColorFilter = nCreateLightingFilter(mul, add);
+        nativeColorFilter = nCreateLightingFilter(native_instance, mul, add);
     }
 
     private static native int native_CreateLightingFilter(int mul, int add);
-    private static native int nCreateLightingFilter(int mul, int add);
+    private static native int nCreateLightingFilter(int nativeFilter, int mul, int add);
 }
diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java
index b02dab1..ecc7c24 100644
--- a/graphics/java/android/graphics/PorterDuffColorFilter.java
+++ b/graphics/java/android/graphics/PorterDuffColorFilter.java
@@ -26,9 +26,10 @@
      */
     public PorterDuffColorFilter(int srcColor, PorterDuff.Mode mode) {
         native_instance = native_CreatePorterDuffFilter(srcColor, mode.nativeInt);
-        nativeColorFilter = nCreatePorterDuffFilter(srcColor, mode.nativeInt);
+        nativeColorFilter = nCreatePorterDuffFilter(native_instance, srcColor, mode.nativeInt);
     }
 
     private static native int native_CreatePorterDuffFilter(int srcColor, int porterDuffMode);
-    private static native int nCreatePorterDuffFilter(int srcColor, int porterDuffMode);
+    private static native int nCreatePorterDuffFilter(int nativeFilter, int srcColor,
+            int porterDuffMode);
 }
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 6c08ce5..f8ad5cc 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -194,11 +194,15 @@
         mRS.nAllocationRead(mID, d);
     }
 
-    public void resize(int dimX) {
+    public synchronized void resize(int dimX) {
         if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
             throw new IllegalStateException("Resize only support for 1D allocations at this time.");
         }
         mRS.nAllocationResize1D(mID, dimX);
+
+        int typeID = mRS.nAllocationGetType(mID);
+        mType = new Type(typeID, mRS);
+        mType.updateFromNative();
     }
 
     /*
diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java
index 53a33e4..430789a 100644
--- a/graphics/java/android/renderscript/Script.java
+++ b/graphics/java/android/renderscript/Script.java
@@ -112,12 +112,10 @@
 
     public static class FieldBase {
         protected Element mElement;
-        protected Type mType;
         protected Allocation mAllocation;
 
         protected void init(RenderScript rs, int dimx) {
             mAllocation = Allocation.createSized(rs, mElement, dimx);
-            mType = mAllocation.getType();
         }
 
         protected FieldBase() {
@@ -128,7 +126,7 @@
         }
 
         public Type getType() {
-            return mType;
+            return mAllocation.getType();
         }
 
         public Allocation getAllocation() {
@@ -138,19 +136,6 @@
         //@Override
         public void updateAllocation() {
         }
-
-
-        //
-        /*
-        public class ScriptField_UserField
-            extends android.renderscript.Script.FieldBase {
-
-            protected
-
-        }
-
-        */
-
     }
 }
 
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 16d5bfe..dd108c0 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -377,7 +377,7 @@
 nAllocationCreateTyped(JNIEnv *_env, jobject _this, RsContext con, jint e)
 {
     LOG_API("nAllocationCreateTyped, con(%p), e(%p)", con, (RsElement)e);
-    return (jint) rsAllocationCreateTyped(con, (RsElement)e);
+    return (jint) rsaAllocationCreateTyped(con, (RsElement)e);
 }
 
 static void
@@ -428,7 +428,7 @@
         const int w = bitmap.width();
         const int h = bitmap.height();
         const void* ptr = bitmap.getPixels();
-        jint id = (jint)rsAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr);
+        jint id = (jint)rsaAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr);
         bitmap.unlockPixels();
         return id;
     }
@@ -488,7 +488,7 @@
         const int w = bitmap.width();
         const int h = bitmap.height();
         const void* ptr = bitmap.getPixels();
-        jint id = (jint)rsAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr);
+        jint id = (jint)rsaAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr);
         bitmap.unlockPixels();
         return id;
     }
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index a9cd5be..0dd9c5a 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -288,7 +288,7 @@
             }
             break;
             case SetupColorFilter: {
-                // TODO: Implement
+                renderer.setupColorFilter(getColorFilter());
             }
             break;
             case ResetShadow: {
@@ -512,7 +512,6 @@
 
 void DisplayListRenderer::resetShader() {
     addOp(DisplayList::ResetShader);
-    OpenGLRenderer::resetShader();
 }
 
 void DisplayListRenderer::setupShader(SkiaShader* shader) {
@@ -522,17 +521,15 @@
 
 void DisplayListRenderer::resetColorFilter() {
     addOp(DisplayList::ResetColorFilter);
-    OpenGLRenderer::resetColorFilter();
 }
 
 void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
-    // TODO: Implement
-    OpenGLRenderer::setupColorFilter(filter);
+    addOp(DisplayList::SetupColorFilter);
+    addColorFilter(filter);
 }
 
 void DisplayListRenderer::resetShadow() {
     addOp(DisplayList::ResetShadow);
-    OpenGLRenderer::resetShadow();
 }
 
 void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
@@ -540,7 +537,6 @@
     addFloat(radius);
     addPoint(dx, dy);
     addInt(color);
-    OpenGLRenderer::setupShadow(radius, dx, dy, color);
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index ce4cfc5..6636de6 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -135,6 +135,10 @@
         return (SkiaShader*) getInt();
     }
 
+    SkiaColorFilter* getColorFilter() {
+        return (SkiaColorFilter*) getInt();
+    }
+
     inline int getIndex() {
         return mReader.readInt();
     }
@@ -183,6 +187,7 @@
 
     Vector<SkBitmap*> mBitmapResources;
     Vector<SkiaShader*> mShaderResources;
+    Vector<SkiaColorFilter*> mFilterResources;
 
     Vector<SkPaint*> mPaints;
     Vector<SkMatrix*> mMatrices;
@@ -276,6 +281,10 @@
         return mMatrices;
     }
 
+    const Vector<SkiaColorFilter*>& getFilterResources() const {
+        return mFilterResources;
+    }
+
 private:
     inline void addOp(DisplayList::Op drawOp) {
         mWriter.writeInt(drawOp);
@@ -372,10 +381,18 @@
         caches.resourceCache.incrementRefcount(shader);
     }
 
+    inline void addColorFilter(SkiaColorFilter* colorFilter) {
+        addInt((int)colorFilter);
+        mFilterResources.add(colorFilter);
+        Caches& caches = Caches::getInstance();
+        caches.resourceCache.incrementRefcount(colorFilter);
+    }
+
     SkChunkAlloc mHeap;
 
     Vector<SkBitmap*> mBitmapResources;
     Vector<SkiaShader*> mShaderResources;
+    Vector<SkiaColorFilter*> mFilterResources;
 
     Vector<SkPaint*> mPaints;
     DefaultKeyedVector<SkPaint *, SkPaint *> mPaintMap;
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index b0fbe65..47c5d48 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -67,6 +67,11 @@
     incrementRefcount((void*)shaderResource, kShader);
 }
 
+void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
+    filterResource->getSkColorFilter()->safeRef();
+    incrementRefcount((void*)filterResource, kColorFilter);
+}
+
 void ResourceCache::decrementRefcount(void* resource) {
     ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
     if (ref == NULL) {
@@ -90,6 +95,11 @@
     decrementRefcount((void*)shaderResource);
 }
 
+void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
+    filterResource->getSkColorFilter()->safeUnref();
+    decrementRefcount((void*)filterResource);
+}
+
 void ResourceCache::recycle(SkBitmap* resource) {
     if (mCache->indexOfKey(resource) < 0) {
         // not tracking this resource; just recycle the pixel data
@@ -145,6 +155,20 @@
     }
 }
 
+void ResourceCache::destructor(SkiaColorFilter* resource) {
+    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+    if (ref == NULL) {
+        // If we're not tracking this resource, just delete it
+        delete resource;
+        return;
+    }
+    ref->destroyed = true;
+    if (ref->refCount == 0) {
+        deleteResourceReference(resource, ref);
+        return;
+    }
+}
+
 void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) {
     if (ref->recycled && ref->resourceType == kBitmap) {
         ((SkBitmap*) resource)->setPixels(NULL, NULL);
@@ -161,12 +185,20 @@
             }
             break;
             case kShader:
+            {
                 SkiaShader* shader = (SkiaShader*)resource;
                 if (Caches::hasInstance()) {
                     Caches::getInstance().gradientCache.remove(shader->getSkShader());
                 }
                 delete shader;
-                break;
+            }
+            break;
+            case kColorFilter:
+            {
+                SkiaColorFilter* filter = (SkiaColorFilter*)resource;
+                delete filter;
+            }
+            break;
         }
     }
     mCache->removeItem(resource);
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index b550367..d9b3718 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -18,6 +18,7 @@
 #define ANDROID_UI_RESOURCE_CACHE_H
 
 #include <SkBitmap.h>
+#include <SkiaColorFilter.h>
 #include <SkiaShader.h>
 #include <utils/KeyedVector.h>
 
@@ -30,6 +31,7 @@
 enum ResourceType {
     kBitmap,
     kShader,
+    kColorFilter,
 };
 
 class ResourceReference {
@@ -53,14 +55,17 @@
     ~ResourceCache();
     void incrementRefcount(SkBitmap* resource);
     void incrementRefcount(SkiaShader* resource);
+    void incrementRefcount(SkiaColorFilter* resource);
     void incrementRefcount(const void* resource, ResourceType resourceType);
     void decrementRefcount(void* resource);
     void decrementRefcount(SkBitmap* resource);
     void decrementRefcount(SkiaShader* resource);
+    void decrementRefcount(SkiaColorFilter* resource);
     void recycle(void* resource);
     void recycle(SkBitmap* resource);
     void destructor(SkBitmap* resource);
     void destructor(SkiaShader* resource);
+    void destructor(SkiaColorFilter* resource);
 private:
     void deleteResourceReference(void* resource, ResourceReference* ref);
     void incrementRefcount(void* resource, ResourceType resourceType);
diff --git a/libs/hwui/SkiaColorFilter.cpp b/libs/hwui/SkiaColorFilter.cpp
index fe57ae7..91b1c32 100644
--- a/libs/hwui/SkiaColorFilter.cpp
+++ b/libs/hwui/SkiaColorFilter.cpp
@@ -23,7 +23,8 @@
 // Base color filter
 ///////////////////////////////////////////////////////////////////////////////
 
-SkiaColorFilter::SkiaColorFilter(Type type, bool blend): mType(type), mBlend(blend) {
+SkiaColorFilter::SkiaColorFilter(SkColorFilter *skFilter, Type type, bool blend):
+        mType(type), mBlend(blend), mSkFilter(skFilter) {
 }
 
 SkiaColorFilter::~SkiaColorFilter() {
@@ -33,8 +34,8 @@
 // Color matrix filter
 ///////////////////////////////////////////////////////////////////////////////
 
-SkiaColorMatrixFilter::SkiaColorMatrixFilter(float* matrix, float* vector):
-        SkiaColorFilter(kColorMatrix, true), mMatrix(matrix), mVector(vector) {
+SkiaColorMatrixFilter::SkiaColorMatrixFilter(SkColorFilter *skFilter, float* matrix, float* vector):
+        SkiaColorFilter(skFilter, kColorMatrix, true), mMatrix(matrix), mVector(vector) {
 }
 
 SkiaColorMatrixFilter::~SkiaColorMatrixFilter() {
@@ -56,8 +57,8 @@
 // Lighting color filter
 ///////////////////////////////////////////////////////////////////////////////
 
-SkiaLightingFilter::SkiaLightingFilter(int multiply, int add):
-        SkiaColorFilter(kLighting, true) {
+SkiaLightingFilter::SkiaLightingFilter(SkColorFilter *skFilter, int multiply, int add):
+        SkiaColorFilter(skFilter, kLighting, true) {
     mMulR = ((multiply >> 16) & 0xFF) / 255.0f;
     mMulG = ((multiply >>  8) & 0xFF) / 255.0f;
     mMulB = ((multiply      ) & 0xFF) / 255.0f;
@@ -80,8 +81,8 @@
 // Blend color filter
 ///////////////////////////////////////////////////////////////////////////////
 
-SkiaBlendFilter::SkiaBlendFilter(int color, SkXfermode::Mode mode):
-        SkiaColorFilter(kBlend, true), mMode(mode) {
+SkiaBlendFilter::SkiaBlendFilter(SkColorFilter *skFilter, int color, SkXfermode::Mode mode):
+        SkiaColorFilter(skFilter, kBlend, true), mMode(mode) {
     const int alpha = (color >> 24) & 0xFF;
     mA = alpha / 255.0f;
     mR = mA * ((color >> 16) & 0xFF) / 255.0f;
diff --git a/libs/hwui/SkiaColorFilter.h b/libs/hwui/SkiaColorFilter.h
index 865b6f0..17f49f9 100644
--- a/libs/hwui/SkiaColorFilter.h
+++ b/libs/hwui/SkiaColorFilter.h
@@ -18,6 +18,7 @@
 #define ANDROID_UI_SKIA_COLOR_FILTER_H
 
 #include <GLES2/gl2.h>
+#include <SkColorFilter.h>
 
 #include "ProgramCache.h"
 #include "Extensions.h"
@@ -44,7 +45,7 @@
         kBlend,
     };
 
-    SkiaColorFilter(Type type, bool blend);
+    SkiaColorFilter(SkColorFilter *skFilter, Type type, bool blend);
     virtual ~SkiaColorFilter();
 
     virtual void describe(ProgramDescription& description, const Extensions& extensions) = 0;
@@ -58,9 +59,16 @@
         return mType;
     }
 
+    SkColorFilter *getSkColorFilter() {
+        return mSkFilter;
+    }
+
 protected:
     Type mType;
     bool mBlend;
+
+private:
+    SkColorFilter *mSkFilter;
 }; // struct SkiaColorFilter
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -71,7 +79,7 @@
  * A color filter that multiplies the source color with a matrix and adds a vector.
  */
 struct SkiaColorMatrixFilter: public SkiaColorFilter {
-    SkiaColorMatrixFilter(float* matrix, float* vector);
+    SkiaColorMatrixFilter(SkColorFilter *skFilter, float* matrix, float* vector);
     ~SkiaColorMatrixFilter();
 
     void describe(ProgramDescription& description, const Extensions& extensions);
@@ -87,7 +95,7 @@
  * another fixed value. Ignores the alpha channel of both arguments.
  */
 struct SkiaLightingFilter: public SkiaColorFilter {
-    SkiaLightingFilter(int multiply, int add);
+    SkiaLightingFilter(SkColorFilter *skFilter, int multiply, int add);
 
     void describe(ProgramDescription& description, const Extensions& extensions);
     void setupProgram(Program* program);
@@ -102,7 +110,7 @@
  * and PorterDuff blending mode.
  */
 struct SkiaBlendFilter: public SkiaColorFilter {
-    SkiaBlendFilter(int color, SkXfermode::Mode mode);
+    SkiaBlendFilter(SkColorFilter *skFilter, int color, SkXfermode::Mode mode);
 
     void describe(ProgramDescription& description, const Extensions& extensions);
     void setupProgram(Program* program);
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index d078d46..1d67329 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -290,6 +290,8 @@
 // Async commands for returning new IDS
 RsType rsaTypeCreate(RsContext, RsElement, uint32_t dimCount,
                      const RsDimension *dims, const uint32_t *vals);
+RsAllocation rsaAllocationCreateTyped(RsContext rsc, RsType vtype);
+RsAllocation rsaAllocationCreateFromBitmap(RsContext con, uint32_t w, uint32_t h, RsElement _dst, RsElement _src,  bool genMips, const void *data);
 
 
 #ifndef NO_RS_FUNCS
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index eb2942e..3e131b2 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -104,17 +104,6 @@
 	param uint32_t typeDataSize
 	}
 
-AllocationCreateTyped {
-	param RsType type
-	ret RsAllocation
-	}
-
-AllocationCreateSized {
-	param RsElement e
-	param size_t count
-	ret RsAllocation
-	}
-
 AllocationUpdateFromBitmap {
 	param RsAllocation alloc
 	param RsElement srcFmt
@@ -129,17 +118,6 @@
 	ret RsAllocation
 	}
 
-AllocationCreateFromBitmap {
-	param uint32_t width
-	param uint32_t height
-	param RsElement dstFmt
-	param RsElement srcFmt
-	param bool genMips
-	param const void * data
-	ret RsAllocation
-	}
-
-
 AllocationUploadToTexture {
 	param RsAllocation alloc
 	param bool genMipMaps
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index fc41a722..b4872e3 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -563,24 +563,6 @@
 namespace android {
 namespace renderscript {
 
-RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype)
-{
-    const Type * type = static_cast<const Type *>(vtype);
-
-    Allocation * alloc = new Allocation(rsc, type);
-    alloc->incUserRef();
-    return alloc;
-}
-
-RsAllocation rsi_AllocationCreateSized(Context *rsc, RsElement e, size_t count)
-{
-    Type * type = new Type(rsc);
-    type->setDimX(count);
-    type->setElement(static_cast<Element *>(e));
-    type->compute();
-    return rsi_AllocationCreateTyped(rsc, type);
-}
-
 void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel)
 {
     Allocation *alloc = static_cast<Allocation *>(va);
@@ -786,42 +768,6 @@
     }
 }
 
-RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src,  bool genMips, const void *data)
-{
-    const Element *src = static_cast<const Element *>(_src);
-    const Element *dst = static_cast<const Element *>(_dst);
-
-    //LOGE("%p rsi_AllocationCreateFromBitmap %i %i %i", rsc, w, h, genMips);
-    RsDimension dims[] = {RS_DIMENSION_X, RS_DIMENSION_Y, RS_DIMENSION_LOD};
-    uint32_t dimValues[] = {w, h, genMips};
-    RsType type = rsaTypeCreate(rsc, _dst, 3, dims, dimValues);
-
-    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, type);
-    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
-    if (texAlloc == NULL) {
-        LOGE("Memory allocation failure");
-        return NULL;
-    }
-
-    ElementConverter_t cvt = pickConverter(dst, src);
-    if (cvt) {
-        cvt(texAlloc->getPtr(), data, w * h);
-        if (genMips) {
-            Adapter2D adapt(rsc, texAlloc);
-            Adapter2D adapt2(rsc, texAlloc);
-            for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
-                adapt.setLOD(lod);
-                adapt2.setLOD(lod + 1);
-                mip(adapt2, adapt);
-            }
-        }
-    } else {
-        rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
-    }
-
-    return texAlloc;
-}
-
 void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes)
 {
     Allocation *a = static_cast<Allocation *>(va);
@@ -882,3 +828,49 @@
 
 }
 }
+
+RsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype)
+{
+    Context *rsc = static_cast<Context *>(con);
+    Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype));
+    alloc->incUserRef();
+    return alloc;
+}
+
+RsAllocation rsaAllocationCreateFromBitmap(RsContext con, uint32_t w, uint32_t h, RsElement _dst, RsElement _src,  bool genMips, const void *data)
+{
+    Context *rsc = static_cast<Context *>(con);
+    const Element *src = static_cast<const Element *>(_src);
+    const Element *dst = static_cast<const Element *>(_dst);
+
+    //LOGE("%p rsi_AllocationCreateFromBitmap %i %i %i", rsc, w, h, genMips);
+    RsDimension dims[] = {RS_DIMENSION_X, RS_DIMENSION_Y, RS_DIMENSION_LOD};
+    uint32_t dimValues[] = {w, h, genMips};
+    RsType type = rsaTypeCreate(rsc, _dst, 3, dims, dimValues);
+
+    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, type);
+    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
+    if (texAlloc == NULL) {
+        LOGE("Memory allocation failure");
+        return NULL;
+    }
+
+    ElementConverter_t cvt = pickConverter(dst, src);
+    if (cvt) {
+        cvt(texAlloc->getPtr(), data, w * h);
+        if (genMips) {
+            Adapter2D adapt(rsc, texAlloc);
+            Adapter2D adapt2(rsc, texAlloc);
+            for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
+                adapt.setLOD(lod);
+                adapt2.setLOD(lod + 1);
+                mip(adapt2, adapt);
+            }
+        }
+    } else {
+        rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
+    }
+
+    return texAlloc;
+}
+
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index dc021fc..096115c 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -399,6 +399,7 @@
     rsAssert(e->getFieldCount() == dataSize);
 
     for(uint32_t i = 0; i < dataSize; i ++) {
+        e->getField(i)->incUserRef();
         ids[i] = (uint32_t)e->getField(i);
         names[i] = e->getFieldName(i);
     }
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index d171a48..9e76215 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -511,10 +511,7 @@
     mRSC->mStateElement.elementBuilderAdd(gammaElem, "Gamma", 1);
     const Element *constInput = mRSC->mStateElement.elementBuilderCreate(mRSC);
 
-    Type *inputType = new Type(mRSC);
-    inputType->setElement(constInput);
-    inputType->setDimX(1);
-    inputType->compute();
+    Type *inputType = Type::getType(mRSC, constInput, 1, 0, 0, false, false);
 
     uint32_t tmp[4];
     tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
@@ -546,11 +543,7 @@
     const Element *alphaElem = Element::create(mRSC, RS_TYPE_UNSIGNED_8, RS_KIND_PIXEL_A, true, 1);
 
     // We will allocate a texture to initially hold 32 character bitmaps
-    Type *texType = new Type(mRSC);
-    texType->setElement(alphaElem);
-    texType->setDimX(1024);
-    texType->setDimY(256);
-    texType->compute();
+    Type *texType = Type::getType(mRSC, alphaElem, 1024, 256, 0, false, false);
 
     Allocation *cacheAlloc = new Allocation(mRSC, texType);
     mTextTexture.set(cacheAlloc);
@@ -578,11 +571,8 @@
 {
     // Now lets write index data
     const Element *indexElem = Element::create(mRSC, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1);
-    Type *indexType = new Type(mRSC);
     uint32_t numIndicies = mMaxNumberOfQuads * 6;
-    indexType->setDimX(numIndicies);
-    indexType->setElement(indexElem);
-    indexType->compute();
+    Type *indexType = Type::getType(mRSC, indexElem, numIndicies, 0, 0, false, false);
 
     Allocation *indexAlloc = new Allocation(mRSC, indexType);
     uint16_t *indexPtr = (uint16_t*)indexAlloc->getPtr();
@@ -612,10 +602,9 @@
     mRSC->mStateElement.elementBuilderAdd(texElem, "texture0", 1);
     const Element *vertexDataElem = mRSC->mStateElement.elementBuilderCreate(mRSC);
 
-    Type *vertexDataType = new Type(mRSC);
-    vertexDataType->setDimX(mMaxNumberOfQuads * 4);
-    vertexDataType->setElement(vertexDataElem);
-    vertexDataType->compute();
+    Type *vertexDataType = Type::getType(mRSC, vertexDataElem,
+                                         mMaxNumberOfQuads * 4,
+                                         0, 0, false, false);
 
     Allocation *vertexAlloc = new Allocation(mRSC, vertexDataType);
     mTextMeshPtr = (float*)vertexAlloc->getPtr();
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index 724172e..44dc042 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -120,8 +120,15 @@
 
 bool ObjectBase::decUserRef() const
 {
-    //LOGV("ObjectBase %p decU ref %i, %i", this, mUserRefCount, mSysRefCount);
     rsAssert(mUserRefCount > 0);
+#if RS_OBJECT_DEBUG
+    LOGV("ObjectBase %p decU ref %i, %i", this, mUserRefCount, mSysRefCount);
+    if (mUserRefCount <= 0) {
+        mStack.dump();
+    }
+#endif
+
+
     if ((android_atomic_dec(&mUserRefCount) <= 1) &&
         (android_atomic_acquire_load(&mSysRefCount) <= 0)) {
         return checkDelete(this);
diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h
index 5f03db5..5cc275a 100644
--- a/libs/rs/rsObjectBase.h
+++ b/libs/rs/rsObjectBase.h
@@ -21,9 +21,7 @@
 
 #define RS_OBJECT_DEBUG 0
 
-#if RS_OBJECT_DEBUG
-    #include <utils/CallStack.h>
-#endif
+#include <utils/CallStack.h>
 
 namespace android {
 namespace renderscript {
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index 33399d5..800854b 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -198,10 +198,7 @@
     rsc->mStateElement.elementBuilderAdd(colorElem, "Color", 1);
     const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
 
-    Type *inputType = new Type(rsc);
-    inputType->setElement(constInput);
-    inputType->setDimX(1);
-    inputType->compute();
+    Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false);
 
     uint32_t tmp[4];
     tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index d12439f..4e64008 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -257,10 +257,7 @@
     rsc->mStateElement.elementBuilderAdd(f2Elem, "texture0", 1);
     const Element *attrElem = rsc->mStateElement.elementBuilderCreate(rsc);
 
-    Type *inputType = new Type(rsc);
-    inputType->setElement(constInput);
-    inputType->setDimX(1);
-    inputType->compute();
+    Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false);
 
     String8 shaderString(RS_SHADER_INTERNAL);
     shaderString.append("varying vec4 varColor;\n");
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 82ad33e..7ef2464 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -276,20 +276,12 @@
         return NULL;
     }
 
-    Type *type = new Type(rsc);
-    type->mDimX = stream->loadU32();
-    type->mDimY = stream->loadU32();
-    type->mDimZ = stream->loadU32();
-
-    uint8_t temp = stream->loadU8();
-    type->mDimLOD = temp != 0;
-
-    temp = stream->loadU8();
-    type->mFaces = temp != 0;
-
-    type->setElement(elem);
-
-    return type;
+    uint32_t x = stream->loadU32();
+    uint32_t y = stream->loadU32();
+    uint32_t z = stream->loadU32();
+    uint8_t lod = stream->loadU8();
+    uint8_t faces = stream->loadU8();
+    return Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0 );
 }
 
 bool Type::getIsNp2() const
@@ -325,56 +317,55 @@
     return false;
 }
 
-Type * Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const
+Type * Type::getType(Context *rsc, const Element *e,
+                     uint32_t dimX, uint32_t dimY, uint32_t dimZ,
+                     bool dimLOD, bool dimFaces)
 {
     TypeState * stc = &rsc->mStateType;
+
+    ObjectBase::asyncLock();
     for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
         Type *t = stc->mTypes[ct];
-        if (t->getElement() != mElement.get()) continue;
+        if (t->getElement() != e) continue;
         if (t->getDimX() != dimX) continue;
-        if (t->getDimY() != mDimY) continue;
-        if (t->getDimZ() != mDimZ) continue;
-        if (t->getDimLOD() != mDimLOD) continue;
-        if (t->getDimFaces() != mFaces) continue;
+        if (t->getDimY() != dimY) continue;
+        if (t->getDimZ() != dimZ) continue;
+        if (t->getDimLOD() != dimLOD) continue;
+        if (t->getDimFaces() != dimFaces) continue;
         t->incUserRef();
+        ObjectBase::asyncUnlock();
         return t;
     }
+    ObjectBase::asyncUnlock();
+
 
     Type *nt = new Type(rsc);
-    nt->mElement.set(mElement);
+    nt->mElement.set(e);
     nt->mDimX = dimX;
-    nt->mDimY = mDimY;
-    nt->mDimZ = mDimZ;
-    nt->mDimLOD = mDimLOD;
-    nt->mFaces = mFaces;
+    nt->mDimY = dimY;
+    nt->mDimZ = dimZ;
+    nt->mDimLOD = dimLOD;
+    nt->mFaces = dimFaces;
     nt->compute();
+    nt->incUserRef();
+
+    ObjectBase::asyncLock();
+    stc->mTypes.push(nt);
+    ObjectBase::asyncUnlock();
+
     return nt;
 }
 
+Type * Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const
+{
+    return getType(rsc, mElement.get(), dimX,
+                   mDimY, mDimZ, mDimLOD, mFaces);
+}
+
 Type * Type::cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const
 {
-    TypeState * stc = &rsc->mStateType;
-    for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
-        Type *t = stc->mTypes[ct];
-        if (t->getElement() != mElement.get()) continue;
-        if (t->getDimX() != dimX) continue;
-        if (t->getDimY() != dimY) continue;
-        if (t->getDimZ() != mDimZ) continue;
-        if (t->getDimLOD() != mDimLOD) continue;
-        if (t->getDimFaces() != mFaces) continue;
-        t->incUserRef();
-        return t;
-    }
-
-    Type *nt = new Type(rsc);
-    nt->mElement.set(mElement);
-    nt->mDimX = dimX;
-    nt->mDimY = dimY;
-    nt->mDimZ = mDimZ;
-    nt->mDimLOD = mDimLOD;
-    nt->mFaces = mFaces;
-    nt->compute();
-    return nt;
+    return getType(rsc, mElement.get(), dimX, dimY,
+                   mDimZ, mDimLOD, mFaces);
 }
 
 
@@ -396,7 +387,7 @@
     (*typeData++) = t->getDimLOD();
     (*typeData++) = t->getDimFaces() ? 1 : 0;
     (*typeData++) = (uint32_t)t->getElement();
-
+    t->getElement()->incUserRef();
 }
 
 
@@ -430,34 +421,6 @@
         }
     }
 
-    ObjectBase::asyncLock();
-    for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
-        Type *t = stc->mTypes[ct];
-        if (t->getElement() != e) continue;
-        if (t->getDimX() != dimX) continue;
-        if (t->getDimY() != dimY) continue;
-        if (t->getDimZ() != dimZ) continue;
-        if (t->getDimLOD() != dimLOD) continue;
-        if (t->getDimFaces() != dimFaces) continue;
-        t->incUserRef();
-        ObjectBase::asyncUnlock();
-        return t;
-    }
-    ObjectBase::asyncUnlock();
-
-    Type * st = new Type(rsc);
-    st->incUserRef();
-    st->setDimX(dimX);
-    st->setDimY(dimY);
-    st->setDimZ(dimZ);
-    st->setElement(e);
-    st->setDimLOD(dimLOD);
-    st->setDimFaces(dimFaces);
-    st->compute();
-
-    ObjectBase::asyncLock();
-    stc->mTypes.push(st);
-    ObjectBase::asyncUnlock();
-    return st;
+    return Type::getType(rsc, e, dimX, dimY, dimZ, dimLOD, dimFaces);
 }
 
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 6b89413..0ca5bb6 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -28,9 +28,6 @@
 class Type : public ObjectBase
 {
 public:
-    Type(Context *);
-    virtual ~Type();
-
     Type * createTex2D(const Element *, size_t w, size_t h, bool mip);
 
 
@@ -58,15 +55,6 @@
     uint32_t getLODCount() const {return mLODCount;}
     bool getIsNp2() const;
 
-
-    void setElement(const Element *e) {mElement.set(e);}
-    void setDimX(uint32_t v) {mDimX = v;}
-    void setDimY(uint32_t v) {mDimY = v;}
-    void setDimZ(uint32_t v) {mDimZ = v;}
-    void setDimFaces(bool v) {mFaces = v;}
-    void setDimLOD(bool v) {mDimLOD = v;}
-
-
     void clear();
     void compute();
 
@@ -82,6 +70,10 @@
     Type * cloneAndResize1D(Context *rsc, uint32_t dimX) const;
     Type * cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const;
 
+    static Type * getType(Context *rsc, const Element *e,
+                      uint32_t dimX, uint32_t dimY, uint32_t dimZ,
+                      bool dimLOD, bool dimFaces);
+
 protected:
     struct LOD {
         size_t mX;
@@ -124,10 +116,13 @@
     bool isValidGLComponent(uint32_t fieldIdx);
     void makeGLComponents();
 
+
 protected:
     virtual void preDestroy();
+    virtual ~Type();
 
 private:
+    Type(Context *);
     Type(const Type &);
 };
 
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 0994980..7af6ce8 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -867,7 +867,18 @@
         return BAD_VALUE;
 
     Mutex::Autolock _l(mSurfaceLock);
+    if (mConnected == NATIVE_WINDOW_API_EGL) {
+        return INVALID_OPERATION;
+    }
+
     mBufferInfo.set(w, h, format);
+    if (format != 0) {
+        // we update the format of the surface as reported by query().
+        // this is to allow applications to change the format of a surface's
+        // buffer, and have it reflected in EGL; which is needed for
+        // EGLConfig validation.
+        mFormat = format;
+    }
     return NO_ERROR;
 }
 
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 68524c3..fcf6510 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -480,16 +480,6 @@
     }
 
     /**
-     * Sets the level of the encoder. Call this before prepare().
-     *
-     * @param encoderLevel the video encoder level.
-     * @hide
-     */
-    public void setVideoEncoderLevel(int encoderLevel) {
-        setParameter(String.format("video-param-encoder-level=%d", encoderLevel));
-    }
-
-    /**
      * Sets the auxiliary time lapse video's resolution and bitrate.
      *
      * The auxiliary video's resolution and bitrate are determined by the CamcorderProfile
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index df3c5fb..d2f3694 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -163,7 +163,9 @@
     public void setDuration(long durationMs) {

         mDurationMs = durationMs;

 

-        adjustElementsDuration();

+        adjustTransitions();

+        adjustOverlays();

+        adjustEffects();

     }

 

     /*

diff --git a/media/java/android/media/videoeditor/MediaItem.java b/media/java/android/media/videoeditor/MediaItem.java
index d9c38af..40d3619 100755
--- a/media/java/android/media/videoeditor/MediaItem.java
+++ b/media/java/android/media/videoeditor/MediaItem.java
@@ -40,13 +40,21 @@
      * clip are rendered black.

      */

     public static final int RENDERING_MODE_BLACK_BORDER = 0;

+

     /**

      * When using the RENDERING_MODE_STRETCH rendering mode video frames are

      * stretched horizontally or vertically to match the current aspect ratio of

-     * the movie.

+     * the video editor.

      */

     public static final int RENDERING_MODE_STRETCH = 1;

 

+    /**

+     * When using the RENDERING_MODE_CROPPING rendering mode video frames are

+     * scaled horizontally or vertically by preserving the original aspect

+     * ratio of the media item.

+     */

+    public static final int RENDERING_MODE_CROPPING = 2;

+

 

     // The unique id of the MediaItem

     private final String mUniqueId;

@@ -476,10 +484,9 @@
     }

 

     /**

-     * Adjust the duration of effects, overlays and transitions.

-     * This method will be called after a media item duration is changed.

+     * Adjust the duration transitions.

      */

-    protected void adjustElementsDuration() {

+    protected void adjustTransitions() {

         // Check if the duration of transitions need to be adjusted

         if (mBeginTransition != null) {

             final long maxDurationMs = mBeginTransition.getMaximumDuration();

@@ -494,31 +501,12 @@
                 mEndTransition.setDuration(maxDurationMs);

             }

         }

+    }

 

-        final List<Overlay> overlays = getAllOverlays();

-        for (Overlay overlay : overlays) {

-            // Adjust the start time if necessary

-            final long overlayStartTimeMs;

-            if (overlay.getStartTime() > getTimelineDuration()) {

-                overlayStartTimeMs = 0;

-            } else {

-                overlayStartTimeMs = overlay.getStartTime();

-            }

-

-            // Adjust the duration if necessary

-            final long overlayDurationMs;

-            if (overlayStartTimeMs + overlay.getDuration() > getTimelineDuration()) {

-                overlayDurationMs = getTimelineDuration() - overlayStartTimeMs;

-            } else {

-                overlayDurationMs = overlay.getDuration();

-            }

-

-            if (overlayStartTimeMs != overlay.getStartTime() ||

-                    overlayDurationMs != overlay.getDuration()) {

-                overlay.setStartTimeAndDuration(overlayStartTimeMs, overlayDurationMs);

-            }

-        }

-

+    /**

+     * Adjust the start time and/or duration of effects.

+     */

+    protected void adjustEffects() {

         final List<Effect> effects = getAllEffects();

         for (Effect effect : effects) {

             // Adjust the start time if necessary

@@ -543,4 +531,33 @@
             }

         }

     }

+

+    /**

+     * Adjust the start time and/or duration of overlays.

+     */

+    protected void adjustOverlays() {

+        final List<Overlay> overlays = getAllOverlays();

+        for (Overlay overlay : overlays) {

+            // Adjust the start time if necessary

+            final long overlayStartTimeMs;

+            if (overlay.getStartTime() > getTimelineDuration()) {

+                overlayStartTimeMs = 0;

+            } else {

+                overlayStartTimeMs = overlay.getStartTime();

+            }

+

+            // Adjust the duration if necessary

+            final long overlayDurationMs;

+            if (overlayStartTimeMs + overlay.getDuration() > getTimelineDuration()) {

+                overlayDurationMs = getTimelineDuration() - overlayStartTimeMs;

+            } else {

+                overlayDurationMs = overlay.getDuration();

+            }

+

+            if (overlayStartTimeMs != overlay.getStartTime() ||

+                    overlayDurationMs != overlay.getDuration()) {

+                overlay.setStartTimeAndDuration(overlayStartTimeMs, overlayDurationMs);

+            }

+        }

+    }

 }

diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java
index f71f4f4..341bf8e 100755
--- a/media/java/android/media/videoeditor/MediaVideoItem.java
+++ b/media/java/android/media/videoeditor/MediaVideoItem.java
@@ -155,7 +155,11 @@
         mBeginBoundaryTimeMs = beginMs;

         mEndBoundaryTimeMs = endMs;

 

-        adjustElementsDuration();

+        adjustTransitions();

+

+        // Note that the start and duration of any effects and overlays are

+        // not adjusted nor are they automatically removed if they fall

+        // outside the new boundaries.

     }

 

     /**

diff --git a/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp b/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
index 703b41e..e14fb95 100644
--- a/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
@@ -112,7 +112,12 @@
 
     mAnchorTimeUs = 0;
     mNumFramesOutput = 0;
-    mNumFramesLeftOnPage = 0;
+
+    // If the source never limits the number of valid frames contained
+    // in the input data, we'll assume that all of the decoded frames are
+    // valid.
+    mNumFramesLeftOnPage = -1;
+
     mStarted = true;
 
     return OK;
@@ -193,12 +198,14 @@
         }
     }
 
-    if (numFrames > mNumFramesLeftOnPage) {
-        LOGV("discarding %d frames at end of page",
-             numFrames - mNumFramesLeftOnPage);
-        numFrames = mNumFramesLeftOnPage;
+    if (mNumFramesLeftOnPage >= 0) {
+        if (numFrames > mNumFramesLeftOnPage) {
+            LOGV("discarding %d frames at end of page",
+                 numFrames - mNumFramesLeftOnPage);
+            numFrames = mNumFramesLeftOnPage;
+        }
+        mNumFramesLeftOnPage -= numFrames;
     }
-    mNumFramesLeftOnPage -= numFrames;
 
     out->set_range(0, numFrames * sizeof(int16_t) * mNumChannels);
 
@@ -241,6 +248,7 @@
     int32_t numPageSamples;
     if (inputBuffer->meta_data()->findInt32(
                 kKeyValidSamples, &numPageSamples)) {
+        CHECK(numPageSamples >= 0);
         mNumFramesLeftOnPage = numPageSamples;
     }
 
diff --git a/native/android/native_window.cpp b/native/android/native_window.cpp
index bada078..7f92eec 100644
--- a/native/android/native_window.cpp
+++ b/native/android/native_window.cpp
@@ -58,8 +58,8 @@
 }
 
 int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width,
-        int32_t height) {
-    native_window_set_buffers_geometry(window, width, height, 0);
+        int32_t height, int32_t format) {
+    native_window_set_buffers_geometry(window, width, height, format);
     return 0;
 }
 
diff --git a/native/include/android/native_window.h b/native/include/android/native_window.h
index ad03d0e..f3d7550 100644
--- a/native/include/android/native_window.h
+++ b/native/include/android/native_window.h
@@ -96,7 +96,7 @@
  * For all of these parameters, if 0 is supplied then the window's base
  * value will come back in force.
  */
-int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width, int32_t height);
+int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width, int32_t height, int32_t format);
 
 /**
  * Lock the window's next drawing surface for writing.
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index e38b9cc..e44c485 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -833,6 +833,9 @@
     static bool mask(GLint reqValue, GLint confValue) {
         return (confValue & reqValue) == reqValue;
     }
+    static bool ignore(GLint reqValue, GLint confValue) {
+        return true;
+    }
 };
 
 // ----------------------------------------------------------------------------
@@ -1060,11 +1063,11 @@
         { EGL_CONFIG_CAVEAT,              config_management_t::exact   },
         { EGL_CONFIG_ID,                  config_management_t::exact   },
         { EGL_LEVEL,                      config_management_t::exact   },
-        { EGL_MAX_PBUFFER_HEIGHT,         config_management_t::exact   },
-        { EGL_MAX_PBUFFER_PIXELS,         config_management_t::exact   },
-        { EGL_MAX_PBUFFER_WIDTH,          config_management_t::exact   },
+        { EGL_MAX_PBUFFER_HEIGHT,         config_management_t::ignore   },
+        { EGL_MAX_PBUFFER_PIXELS,         config_management_t::ignore   },
+        { EGL_MAX_PBUFFER_WIDTH,          config_management_t::ignore   },
         { EGL_NATIVE_RENDERABLE,          config_management_t::exact   },
-        { EGL_NATIVE_VISUAL_ID,           config_management_t::exact   },
+        { EGL_NATIVE_VISUAL_ID,           config_management_t::ignore   },
         { EGL_NATIVE_VISUAL_TYPE,         config_management_t::exact   },
         { EGL_SAMPLES,                    config_management_t::exact   },
         { EGL_SAMPLE_BUFFERS,             config_management_t::exact   },
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
index 10b52f2..7ee3c19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
@@ -116,7 +116,7 @@
         mClipping = clipping;
         if (mClipping != null) {
             Bitmap icon = mClipping.getIcon();
-            mDescription.setText(mClipping.getLabel());
+            mDescription.setText(mClipping.getDescription().getLabel());
             if (icon != null) {
                 mPreviewIcon.setImageBitmap(icon);
                 mPreviewIcon.setVisibility(View.VISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
index 7234557..fff70bc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
@@ -648,7 +648,6 @@
                     if (mVT == null) break;
                     mVT.addMovement(event);
                     mVT.computeCurrentVelocity(1000);
-                    Slog.d("ClockTouchListener", "dy=" + mVT.getYVelocity());
                     if (mVT.getYVelocity() < -200 && mSystemPanel.getVisibility() == View.GONE) {
                         mHandler.removeMessages(MSG_OPEN_SYSTEM_PANEL);
                         mHandler.sendEmptyMessage(MSG_OPEN_SYSTEM_PANEL);
diff --git a/services/java/com/android/server/ClipboardService.java b/services/java/com/android/server/ClipboardService.java
index bdf313c..30ea48c 100644
--- a/services/java/com/android/server/ClipboardService.java
+++ b/services/java/com/android/server/ClipboardService.java
@@ -115,7 +115,7 @@
 
     public ClipDescription getPrimaryClipDescription() {
         synchronized (this) {
-            return new ClipDescription(mPrimaryClip);
+            return mPrimaryClip.getDescription();
         }
     }
 
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 4f75366..210fe8a 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -102,6 +102,8 @@
 
     private final LockList mLocks = new LockList();
     // some wifi lock statistics
+    private int mFullHighPerfLocksAcquired;
+    private int mFullHighPerfLocksReleased;
     private int mFullLocksAcquired;
     private int mFullLocksReleased;
     private int mScanLocksAcquired;
@@ -872,9 +874,19 @@
         mWifiStateMachine.startWpsPbc(bssid);
     }
 
-    public void startWpsPin(String bssid, int apPin) {
+    public void startWpsWithPinFromAccessPoint(String bssid, int apPin) {
         enforceChangePermission();
-        mWifiStateMachine.startWpsPin(bssid, apPin);
+        mWifiStateMachine.startWpsWithPinFromAccessPoint(bssid, apPin);
+    }
+
+    public int startWpsWithPinFromDevice(String bssid) {
+        enforceChangePermission();
+        if (mChannel != null) {
+            return mWifiStateMachine.syncStartWpsWithPinFromDevice(mChannel, bssid);
+        } else {
+            Slog.e(TAG, "mChannel is not initialized");
+            return -1;
+        }
     }
 
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -1030,12 +1042,15 @@
         boolean wifiEnabled = getPersistedWifiEnabled();
         boolean airplaneMode = isAirplaneModeOn() && !mAirplaneModeOverwridden.get();
         boolean lockHeld = mLocks.hasLocks();
-        int strongestLockMode;
+        int strongestLockMode = WifiManager.WIFI_MODE_FULL;
         boolean wifiShouldBeEnabled = wifiEnabled && !airplaneMode;
         boolean wifiShouldBeStarted = !mDeviceIdle || lockHeld;
-        if (mDeviceIdle && lockHeld) {
+
+        if (lockHeld) {
             strongestLockMode = mLocks.getStrongestLockMode();
-        } else {
+        }
+        /* If device is not idle, lockmode cannot be scan only */
+        if (!mDeviceIdle && strongestLockMode == WifiManager.WIFI_MODE_SCAN_ONLY) {
             strongestLockMode = WifiManager.WIFI_MODE_FULL;
         }
 
@@ -1057,6 +1072,8 @@
                 mWifiStateMachine.setDriverStart(true);
                 mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
                         System.currentTimeMillis() + scanMs, scanMs, mScanIntent);
+                mWifiStateMachine.setHighPerfModeEnabled(strongestLockMode
+                        == WifiManager.WIFI_MODE_FULL_HIGH_PERF);
             } else {
                 mWifiStateMachine.requestCmWakeLock();
                 mWifiStateMachine.setDriverStart(false);
@@ -1135,8 +1152,10 @@
         }
         pw.println();
         pw.println("Locks acquired: " + mFullLocksAcquired + " full, " +
+                mFullHighPerfLocksAcquired + " full high perf, " +
                 mScanLocksAcquired + " scan");
         pw.println("Locks released: " + mFullLocksReleased + " full, " +
+                mFullHighPerfLocksReleased + " full high perf, " +
                 mScanLocksReleased + " scan");
         pw.println();
         pw.println("Locks held:");
@@ -1174,11 +1193,15 @@
             if (mList.isEmpty()) {
                 return WifiManager.WIFI_MODE_FULL;
             }
-            for (WifiLock l : mList) {
-                if (l.mMode == WifiManager.WIFI_MODE_FULL) {
-                    return WifiManager.WIFI_MODE_FULL;
-                }
+
+            if (mFullHighPerfLocksAcquired > mFullHighPerfLocksReleased) {
+                return WifiManager.WIFI_MODE_FULL_HIGH_PERF;
             }
+
+            if (mFullLocksAcquired > mFullLocksReleased) {
+                return WifiManager.WIFI_MODE_FULL;
+            }
+
             return WifiManager.WIFI_MODE_SCAN_ONLY;
         }
 
@@ -1225,7 +1248,11 @@
 
     public boolean acquireWifiLock(IBinder binder, int lockMode, String tag, WorkSource ws) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
-        if (lockMode != WifiManager.WIFI_MODE_FULL && lockMode != WifiManager.WIFI_MODE_SCAN_ONLY) {
+        if (lockMode != WifiManager.WIFI_MODE_FULL &&
+                lockMode != WifiManager.WIFI_MODE_SCAN_ONLY &&
+                lockMode != WifiManager.WIFI_MODE_FULL_HIGH_PERF) {
+            Slog.e(TAG, "Illegal argument, lockMode= " + lockMode);
+            if (DBG) throw new IllegalArgumentException("lockMode=" + lockMode);
             return false;
         }
         if (ws != null && ws.size() == 0) {
@@ -1246,6 +1273,7 @@
     private void noteAcquireWifiLock(WifiLock wifiLock) throws RemoteException {
         switch(wifiLock.mMode) {
             case WifiManager.WIFI_MODE_FULL:
+            case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
                 mBatteryStats.noteFullWifiLockAcquiredFromSource(wifiLock.mWorkSource);
                 break;
             case WifiManager.WIFI_MODE_SCAN_ONLY:
@@ -1257,6 +1285,7 @@
     private void noteReleaseWifiLock(WifiLock wifiLock) throws RemoteException {
         switch(wifiLock.mMode) {
             case WifiManager.WIFI_MODE_FULL:
+            case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
                 mBatteryStats.noteFullWifiLockReleasedFromSource(wifiLock.mWorkSource);
                 break;
             case WifiManager.WIFI_MODE_SCAN_ONLY:
@@ -1277,6 +1306,10 @@
             case WifiManager.WIFI_MODE_FULL:
                 ++mFullLocksAcquired;
                 break;
+            case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
+                ++mFullHighPerfLocksAcquired;
+                break;
+
             case WifiManager.WIFI_MODE_SCAN_ONLY:
                 ++mScanLocksAcquired;
                 break;
@@ -1346,6 +1379,9 @@
                     case WifiManager.WIFI_MODE_FULL:
                         ++mFullLocksReleased;
                         break;
+                    case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
+                        ++mFullHighPerfLocksReleased;
+                        break;
                     case WifiManager.WIFI_MODE_SCAN_ONLY:
                         ++mScanLocksReleased;
                         break;
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 9bc24d2..c29e4a9 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -569,7 +569,7 @@
         void broadcastDragStartedLw(final float touchX, final float touchY) {
             // Cache a base-class instance of the clip metadata so that parceling
             // works correctly in calling out to the apps.
-            mDataDescription = new ClipDescription(mData);
+            mDataDescription = mData.getDescription();
             mNotifiedWindows.clear();
             mDragInProgress = true;
 
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index cee8546..8551b0f 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -203,13 +203,9 @@
                 }
             }
             if (xliffDepth == 0 && pseudolocalize) {
-#ifdef ENABLE_PSEUDOLOCALIZE
                 std::string orig(String8(text).string());
                 std::string pseudo = pseudolocalize_string(orig);
                 curString.append(String16(String8(pseudo.c_str())));
-#else
-                assert(false);
-#endif
             } else {
                 if (isFormatted && hasSubstitutionErrors(fileName, inXml, text) != NO_ERROR) {
                     return UNKNOWN_ERROR;
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index f760d27..720f6ac 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -108,6 +108,8 @@
 
     void startWpsPbc(String bssid);
 
-    void startWpsPin(String bssid, int apPin);
+    void startWpsWithPinFromAccessPoint(String bssid, int apPin);
+
+    int startWpsWithPinFromDevice(String bssid);
 }
 
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index be5fab4..04b3891 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -361,10 +361,11 @@
     }
 
     /**
-     * Start WPS pin method configuration
+     * Start WPS pin method configuration with pin obtained
+     * from the access point
      */
-    static boolean startWpsPin(String bssid, int apPin) {
-        if (WifiNative.startWpsPinCommand(bssid, apPin)) {
+    static boolean startWpsWithPinFromAccessPoint(String bssid, int apPin) {
+        if (WifiNative.startWpsWithPinFromAccessPointCommand(bssid, apPin)) {
             /* WPS leaves all networks disabled */
             markAllNetworksDisabled();
             return true;
@@ -374,6 +375,21 @@
     }
 
     /**
+     * Start WPS pin method configuration with pin obtained
+     * from the device
+     */
+    static int startWpsWithPinFromDevice(String bssid) {
+        int pin = WifiNative.startWpsWithPinFromDeviceCommand(bssid);
+        /* WPS leaves all networks disabled */
+        if (pin != -1) {
+            markAllNetworksDisabled();
+        } else {
+            Log.e(TAG, "Failed to start WPS pin method configuration");
+        }
+        return pin;
+    }
+
+    /**
      * Start WPS push button configuration
      */
     static boolean startWpsPbc(String bssid) {
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 0b3a78266..356a0bd 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -339,6 +339,16 @@
     public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
 
     /**
+     * In this Wi-Fi lock mode, Wi-Fi will behave as in the mode
+     * {@link #WIFI_MODE_FULL} but it operates at high performance
+     * at the expense of power. This mode should be used
+     * only when the wifi connection needs to have minimum loss and low
+     * latency as it can impact the battery life.
+     * @hide
+     */
+    public static final int WIFI_MODE_FULL_HIGH_PERF = 3;
+
+    /**
      * In this Wi-Fi lock mode, Wi-Fi will be kept active,
      * and will behave normally, i.e., it will attempt to automatically
      * establish a connection to a remembered access point that is
@@ -1050,19 +1060,36 @@
 
     /**
      * Start Wi-fi Protected Setup pin method configuration
+     * with pin obtained from the access point
      *
      * @param bssid BSSID of the access point
      * @param apPin PIN issued by the access point
      *
      * @hide
      */
-    public void startWpsPin(String bssid, int apPin) {
+    public void startWpsWithPinFromAccessPoint(String bssid, int apPin) {
         try {
-            mService.startWpsPin(bssid, apPin);
+            mService.startWpsWithPinFromAccessPoint(bssid, apPin);
         } catch (RemoteException e) { }
     }
 
     /**
+     * Start Wi-fi Protected Setup pin method configuration
+     * with pin obtained from the device
+     *
+     * @param bssid BSSID of the access point
+     * @return pin generated by device
+     * @hide
+     */
+    public int startWpsWithPinFromDevice(String bssid) {
+        try {
+            return mService.startWpsWithPinFromDevice(bssid);
+        } catch (RemoteException e) {
+            return -1;
+        }
+    }
+
+    /**
      * Allows an application to keep the Wi-Fi radio awake.
      * Normally the Wi-Fi radio may turn off when the user has not used the device in a while.
      * Acquiring a WifiLock will keep the radio on until the lock is released.  Multiple 
@@ -1244,8 +1271,8 @@
     /**
      * Creates a new WifiLock.
      *
-     * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL} and
-     * {@link #WIFI_MODE_SCAN_ONLY} for descriptions of the types of Wi-Fi locks.
+     * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL},
+     * and {@link #WIFI_MODE_SCAN_ONLY} for descriptions of the types of Wi-Fi locks.
      * @param tag a tag for the WifiLock to identify it in debugging messages.  This string is 
      *            never shown to the user under normal conditions, but should be descriptive 
      *            enough to identify your application and the specific WifiLock within it, if it
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 1251a25..3d8157c 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -153,12 +153,16 @@
 
     public native static boolean startWpsPbcCommand(String bssid);
 
-    public native static boolean startWpsPinCommand(String bssid, int apPin);
+    public native static boolean startWpsWithPinFromAccessPointCommand(String bssid, int apPin);
+
+    public native static int startWpsWithPinFromDeviceCommand(String bssid);
 
     public native static boolean doDhcpRequest(DhcpInfo results);
 
     public native static String getDhcpError();
 
+    public native static boolean setSuspendOptimizationsCommand(boolean enabled);
+
     /**
      * Wait for the supplicant to send an event, returning the event string.
      * @return the event string sent by the supplicant.
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index e3deeb3..6bd67cc 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -246,11 +246,20 @@
     private static final int CMD_RECONNECT                        = 75;
     /* Reassociate to a network */
     private static final int CMD_REASSOCIATE                      = 76;
-    /* Set power mode
-     * POWER_MODE_ACTIVE
-     * POWER_MODE_AUTO
+    /* Controls power mode and suspend mode optimizations
+     *
+     * When high perf mode is enabled, power mode is set to
+     * POWER_MODE_ACTIVE and suspend mode optimizations are disabled
+     *
+     * When high perf mode is disabled, power mode is set to
+     * POWER_MODE_AUTO and suspend mode optimizations are enabled
+     *
+     * Suspend mode optimizations include:
+     * - packet filtering
+     * - turn off roaming
+     * - DTIM wake up settings
      */
-    private static final int CMD_SET_POWER_MODE                   = 77;
+    private static final int CMD_SET_HIGH_PERF_MODE               = 77;
     /* Set bluetooth co-existence
      * BLUETOOTH_COEXISTENCE_MODE_ENABLED
      * BLUETOOTH_COEXISTENCE_MODE_DISABLED
@@ -301,9 +310,10 @@
      * supplicant config.
      */
     private static final int CMD_FORGET_NETWORK                   = 92;
-    /* Start Wi-Fi protected setup */
-    private static final int CMD_START_WPS                        = 93;
-
+    /* Start Wi-Fi protected setup push button configuration */
+    private static final int CMD_START_WPS_PBC                    = 93;
+    /* Start Wi-Fi protected setup pin method configuration */
+    private static final int CMD_START_WPS_PIN                    = 94;
     /**
      * Interval in milliseconds between polling for connection
      * status items that are not sent via asynchronous events.
@@ -334,8 +344,8 @@
      */
     private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
 
-    private static final int DRIVER_POWER_MODE_ACTIVE = 1;
-    private static final int DRIVER_POWER_MODE_AUTO = 0;
+    private static final int POWER_MODE_ACTIVE = 1;
+    private static final int POWER_MODE_AUTO = 0;
 
     /* Default parent state */
     private HierarchicalState mDefaultState = new DefaultState();
@@ -787,11 +797,18 @@
     }
 
     public void startWpsPbc(String bssid) {
-        sendMessage(obtainMessage(CMD_START_WPS, bssid));
+        sendMessage(obtainMessage(CMD_START_WPS_PBC, bssid));
     }
 
-    public void startWpsPin(String bssid, int apPin) {
-        sendMessage(obtainMessage(CMD_START_WPS, apPin, 0, bssid));
+    public void startWpsWithPinFromAccessPoint(String bssid, int apPin) {
+        sendMessage(obtainMessage(CMD_START_WPS_PIN, apPin, 0, bssid));
+    }
+
+    public int syncStartWpsWithPinFromDevice(AsyncChannel channel, String bssid) {
+        Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS_PIN, bssid);
+        int result = resultMsg.arg1;
+        resultMsg.recycle();
+        return result;
     }
 
     public void enableRssiPolling(boolean enabled) {
@@ -848,13 +865,13 @@
     }
 
     /**
-     * Set power mode
-     * @param mode
-     *     DRIVER_POWER_MODE_AUTO
-     *     DRIVER_POWER_MODE_ACTIVE
+     * Set high performance mode of operation.
+     * Enabling would set active power mode and disable suspend optimizations;
+     * disabling would set auto power mode and enable suspend optimizations
+     * @param enable true if enable, false otherwise
      */
-    public void setPowerMode(int mode) {
-        sendMessage(obtainMessage(CMD_SET_POWER_MODE, mode, 0));
+    public void setHighPerfModeEnabled(boolean enable) {
+        sendMessage(obtainMessage(CMD_SET_HIGH_PERF_MODE, enable ? 1 : 0, 0));
     }
 
     /**
@@ -1261,6 +1278,21 @@
         return null;
     }
 
+    private void setHighPerfModeEnabledNative(boolean enable) {
+        if(!WifiNative.setSuspendOptimizationsCommand(!enable)) {
+            Log.e(TAG, "set suspend optimizations failed!");
+        }
+        if (enable) {
+            if (!WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE)) {
+                Log.e(TAG, "set power mode active failed!");
+            }
+        } else {
+            if (!WifiNative.setPowerModeCommand(POWER_MODE_AUTO)) {
+                Log.e(TAG, "set power mode auto failed!");
+            }
+        }
+    }
+
     private void configureLinkProperties() {
         if (WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
             mLinkProperties = WifiConfigStore.getLinkProperties(mLastNetworkId);
@@ -1646,7 +1678,7 @@
                 case CMD_CLEAR_BLACKLIST:
                 case CMD_SET_SCAN_MODE:
                 case CMD_SET_SCAN_TYPE:
-                case CMD_SET_POWER_MODE:
+                case CMD_SET_HIGH_PERF_MODE:
                 case CMD_SET_BLUETOOTH_COEXISTENCE:
                 case CMD_SET_BLUETOOTH_SCAN_MODE:
                 case CMD_SET_NUM_ALLOWED_CHANNELS:
@@ -1654,7 +1686,8 @@
                 case CMD_CONNECT_NETWORK:
                 case CMD_SAVE_NETWORK:
                 case CMD_FORGET_NETWORK:
-                case CMD_START_WPS:
+                case CMD_START_WPS_PBC:
+                case CMD_START_WPS_PIN:
                     break;
                 default:
                     Log.e(TAG, "Error! unhandled message" + message);
@@ -1747,7 +1780,7 @@
                 case CMD_STOP_DRIVER:
                 case CMD_SET_SCAN_MODE:
                 case CMD_SET_SCAN_TYPE:
-                case CMD_SET_POWER_MODE:
+                case CMD_SET_HIGH_PERF_MODE:
                 case CMD_SET_BLUETOOTH_COEXISTENCE:
                 case CMD_SET_BLUETOOTH_SCAN_MODE:
                 case CMD_SET_NUM_ALLOWED_CHANNELS:
@@ -1875,7 +1908,7 @@
                 case CMD_STOP_DRIVER:
                 case CMD_SET_SCAN_MODE:
                 case CMD_SET_SCAN_TYPE:
-                case CMD_SET_POWER_MODE:
+                case CMD_SET_HIGH_PERF_MODE:
                 case CMD_SET_BLUETOOTH_COEXISTENCE:
                 case CMD_SET_BLUETOOTH_SCAN_MODE:
                 case CMD_SET_NUM_ALLOWED_CHANNELS:
@@ -1972,7 +2005,7 @@
                 case CMD_STOP_DRIVER:
                 case CMD_SET_SCAN_MODE:
                 case CMD_SET_SCAN_TYPE:
-                case CMD_SET_POWER_MODE:
+                case CMD_SET_HIGH_PERF_MODE:
                 case CMD_SET_BLUETOOTH_COEXISTENCE:
                 case CMD_SET_BLUETOOTH_SCAN_MODE:
                 case CMD_SET_NUM_ALLOWED_CHANNELS:
@@ -2129,7 +2162,7 @@
                 case NETWORK_DISCONNECTION_EVENT:
                 case PASSWORD_MAY_BE_INCORRECT_EVENT:
                 case CMD_SET_SCAN_TYPE:
-                case CMD_SET_POWER_MODE:
+                case CMD_SET_HIGH_PERF_MODE:
                 case CMD_SET_BLUETOOTH_COEXISTENCE:
                 case CMD_SET_BLUETOOTH_SCAN_MODE:
                 case CMD_SET_NUM_ALLOWED_CHANNELS:
@@ -2183,8 +2216,8 @@
                         WifiNative.setScanModeCommand(false);
                     }
                     break;
-                case CMD_SET_POWER_MODE:
-                    WifiNative.setPowerModeCommand(message.arg1);
+                case CMD_SET_HIGH_PERF_MODE:
+                    setHighPerfModeEnabledNative(message.arg1 == 1);
                     break;
                 case CMD_SET_BLUETOOTH_COEXISTENCE:
                     WifiNative.setBluetoothCoexistenceModeCommand(message.arg1);
@@ -2247,7 +2280,7 @@
                 case CMD_START_DRIVER:
                 case CMD_STOP_DRIVER:
                 case CMD_SET_SCAN_TYPE:
-                case CMD_SET_POWER_MODE:
+                case CMD_SET_HIGH_PERF_MODE:
                 case CMD_SET_BLUETOOTH_COEXISTENCE:
                 case CMD_SET_BLUETOOTH_SCAN_MODE:
                 case CMD_SET_NUM_ALLOWED_CHANNELS:
@@ -2395,17 +2428,11 @@
                     /* Expect a disconnection from the old connection */
                     transitionTo(mDisconnectingState);
                     break;
-                case CMD_START_WPS:
+                case CMD_START_WPS_PBC:
                     String bssid = (String) message.obj;
-                    int apPin = message.arg1;
-                    boolean success;
-                    if (apPin != 0) {
-                        /* WPS pin method configuration */
-                        success = WifiConfigStore.startWpsPin(bssid, apPin);
-                    } else {
-                        /* WPS push button configuration */
-                        success = WifiConfigStore.startWpsPbc(bssid);
-                    }
+                    /* WPS push button configuration */
+                    boolean success = WifiConfigStore.startWpsPbc(bssid);
+
                     /* During WPS setup, all other networks are disabled. After
                      * a successful connect a new config is created in the supplicant.
                      *
@@ -2422,6 +2449,24 @@
                         transitionTo(mDisconnectingState);
                     }
                     break;
+                case CMD_START_WPS_PIN:
+                    bssid = (String) message.obj;
+                    int apPin = message.arg1;
+                    int pin;
+                    if (apPin != 0) {
+                        /* WPS pin from access point */
+                        success = WifiConfigStore.startWpsWithPinFromAccessPoint(bssid, apPin);
+                    } else {
+                        pin = WifiConfigStore.startWpsWithPinFromDevice(bssid);
+                        success = (pin != -1);
+                        mReplyChannel.replyToMessage(message, CMD_START_WPS_PIN, pin);
+                    }
+                    if (success) {
+                        mWpsStarted = true;
+                        /* Expect a disconnection from the old connection */
+                        transitionTo(mDisconnectingState);
+                    }
+                    break;
                 case SCAN_RESULTS_EVENT:
                     /* Set the scan setting back to "connect" mode */
                     WifiNative.setScanResultHandlingCommand(CONNECT_MODE);
@@ -2484,7 +2529,7 @@
             if (!mUseStaticIp) {
                 mDhcpThread = null;
                 mModifiedBluetoothCoexistenceMode = false;
-                mPowerMode = DRIVER_POWER_MODE_AUTO;
+                mPowerMode = POWER_MODE_AUTO;
 
                 if (shouldDisableCoexistenceMode()) {
                     /*
@@ -2514,10 +2559,10 @@
                 if (mPowerMode < 0) {
                   // Handle the case where supplicant driver does not support
                   // getPowerModeCommand.
-                    mPowerMode = DRIVER_POWER_MODE_AUTO;
+                    mPowerMode = POWER_MODE_AUTO;
                 }
-                if (mPowerMode != DRIVER_POWER_MODE_ACTIVE) {
-                    WifiNative.setPowerModeCommand(DRIVER_POWER_MODE_ACTIVE);
+                if (mPowerMode != POWER_MODE_ACTIVE) {
+                    WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE);
                 }
 
                 Log.d(TAG, "DHCP request started");
@@ -2618,6 +2663,10 @@
               case CMD_RECONFIGURE_IP:
                   deferMessage(message);
                   break;
+                  /* Defer any power mode changes since we must keep active power mode at DHCP */
+              case CMD_SET_HIGH_PERF_MODE:
+                  deferMessage(message);
+                  break;
               default:
                 return NOT_HANDLED;
           }
@@ -2629,7 +2678,7 @@
       public void exit() {
           /* reset power state & bluetooth coexistence if on DHCP */
           if (!mUseStaticIp) {
-              if (mPowerMode != DRIVER_POWER_MODE_ACTIVE) {
+              if (mPowerMode != POWER_MODE_ACTIVE) {
                   WifiNative.setPowerModeCommand(mPowerMode);
               }