Merge "Fix a few issues with sensors reference-counting"
diff --git a/api/13.xml b/api/13.xml
index b8b11fe..ff279e1 100644
--- a/api/13.xml
+++ b/api/13.xml
@@ -117527,6 +117527,173 @@
 >
 </field>
 </class>
+<class name="HttpResponseCache"
+ extends="java.net.ResponseCache"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="java.io.Closeable">
+</implements>
+<method name="close"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="delete"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="flush"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="get"
+ return="java.net.CacheResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uri" type="java.net.URI">
+</parameter>
+<parameter name="requestMethod" type="java.lang.String">
+</parameter>
+<parameter name="requestHeaders" type="java.util.Map&lt;java.lang.String, java.util.List&lt;java.lang.String&gt;&gt;">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="getHitCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getInstalled"
+ return="android.net.http.HttpResponseCache"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getNetworkCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getRequestCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="install"
+ return="android.net.http.HttpResponseCache"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="directory" type="java.io.File">
+</parameter>
+<parameter name="maxSize" type="long">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="maxSize"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="put"
+ return="java.net.CacheRequest"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uri" type="java.net.URI">
+</parameter>
+<parameter name="urlConnection" type="java.net.URLConnection">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="size"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
 <class name="SslCertificate"
  extends="java.lang.Object"
  abstract="false"
diff --git a/api/current.txt b/api/current.txt
index fdef20f..7dcb714 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8331,6 +8331,7 @@
     method public android.graphics.Region getTransparentRegion();
     method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public void invalidateSelf();
+    method public boolean isLayoutRtlSelf();
     method public boolean isStateful();
     method public final boolean isVisible();
     method public void jumpToCurrentState();
@@ -8361,6 +8362,10 @@
     method public abstract void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
   }
 
+  public static abstract interface Drawable.Callback2 implements android.graphics.drawable.Drawable.Callback {
+    method public abstract boolean isLayoutRtl(android.graphics.drawable.Drawable);
+  }
+
   public static abstract class Drawable.ConstantState {
     ctor public Drawable.ConstantState();
     method public abstract int getChangingConfigurations();
@@ -11164,6 +11169,21 @@
     field public static long DEFAULT_SYNC_MIN_GZIP_BYTES;
   }
 
+  public final class HttpResponseCache extends java.net.ResponseCache implements java.io.Closeable {
+    method public void close() throws java.io.IOException;
+    method public void delete() throws java.io.IOException;
+    method public void flush();
+    method public java.net.CacheResponse get(java.net.URI, java.lang.String, java.util.Map<java.lang.String, java.util.List<java.lang.String>>) throws java.io.IOException;
+    method public int getHitCount();
+    method public static android.net.http.HttpResponseCache getInstalled();
+    method public int getNetworkCount();
+    method public int getRequestCount();
+    method public static android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException;
+    method public long maxSize();
+    method public java.net.CacheRequest put(java.net.URI, java.net.URLConnection) throws java.io.IOException;
+    method public long size();
+  }
+
   public class SslCertificate {
     ctor public deprecated SslCertificate(java.lang.String, java.lang.String, java.lang.String, java.lang.String);
     ctor public deprecated SslCertificate(java.lang.String, java.lang.String, java.util.Date, java.util.Date);
@@ -20121,14 +20141,17 @@
     method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect);
     method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect);
     method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect);
+    method public static int getAbsoluteGravity(int, boolean);
     method public static boolean isHorizontal(int);
     method public static boolean isVertical(int);
+    field public static final int AFTER = 8388613; // 0x800005
     field public static final int AXIS_CLIP = 8; // 0x8
     field public static final int AXIS_PULL_AFTER = 4; // 0x4
     field public static final int AXIS_PULL_BEFORE = 2; // 0x2
     field public static final int AXIS_SPECIFIED = 1; // 0x1
     field public static final int AXIS_X_SHIFT = 0; // 0x0
     field public static final int AXIS_Y_SHIFT = 4; // 0x4
+    field public static final int BEFORE = 8388611; // 0x800003
     field public static final int BOTTOM = 80; // 0x50
     field public static final int CENTER = 17; // 0x11
     field public static final int CENTER_HORIZONTAL = 1; // 0x1
@@ -20143,6 +20166,8 @@
     field public static final int HORIZONTAL_GRAVITY_MASK = 7; // 0x7
     field public static final int LEFT = 3; // 0x3
     field public static final int NO_GRAVITY = 0; // 0x0
+    field public static final int RELATIVE_HORIZONTAL_DIRECTION = 8388608; // 0x800000
+    field public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = 8388615; // 0x800007
     field public static final int RIGHT = 5; // 0x5
     field public static final int TOP = 48; // 0x30
     field public static final int VERTICAL_GRAVITY_MASK = 112; // 0x70
@@ -21121,7 +21146,7 @@
     method public void recycle();
   }
 
-  public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
+  public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback2 android.view.KeyEvent.Callback {
     ctor public View(android.content.Context);
     ctor public View(android.content.Context, android.util.AttributeSet);
     ctor public View(android.content.Context, android.util.AttributeSet, int);
@@ -21307,6 +21332,7 @@
     method public boolean isInTouchMode();
     method public boolean isLayoutRequested();
     method public boolean isLayoutRtl();
+    method public boolean isLayoutRtl(android.graphics.drawable.Drawable);
     method public boolean isLongClickable();
     method public boolean isOpaque();
     method protected boolean isPaddingOffsetRequired();
diff --git a/core/java/android/net/http/HttpResponseCache.java b/core/java/android/net/http/HttpResponseCache.java
new file mode 100644
index 0000000..b5d64e4
--- /dev/null
+++ b/core/java/android/net/http/HttpResponseCache.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.http;
+
+import android.content.Context;
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
+import java.net.HttpURLConnection;
+import java.net.ResponseCache;
+import java.net.URI;
+import java.net.URLConnection;
+import java.util.List;
+import java.util.Map;
+import javax.net.ssl.HttpsURLConnection;
+import libcore.io.DiskLruCache;
+import libcore.io.IoUtils;
+import org.apache.http.impl.client.DefaultHttpClient;
+
+/**
+ * Caches HTTP and HTTPS responses to the filesystem so they may be reused,
+ * saving time and bandwidth. This class supports {@link HttpURLConnection} and
+ * {@link HttpsURLConnection}; there is no platform-provided cache for {@link
+ * DefaultHttpClient} or {@link AndroidHttpClient}.
+ *
+ * <h3>Installing an HTTP response cache</h3>
+ * Enable caching of all of your application's HTTP requests by installing the
+ * cache at application startup. For example, this code installs a 10 MiB cache
+ * in the {@link Context#getCacheDir() application-specific cache directory} of
+ * the filesystem}: <pre>   {@code
+ *   protected void onCreate(Bundle savedInstanceState) {
+ *       ...
+ *
+ *       try {
+ *           File httpCacheDir = new File(context.getCacheDir(), "http");
+ *           long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
+ *           HttpResponseCache.install(httpCacheDir, httpCacheSize);
+ *       } catch (IOException e) {
+ *           Log.i(TAG, "HTTP response cache installation failed:" + e);
+ *       }
+ *   }
+ *
+ *   protected void onStop() {
+ *       ...
+ *
+ *       HttpResponseCache cache = HttpResponseCache.getInstalled();
+ *       if (cache != null) {
+ *           cache.flush();
+ *       }
+ *   }}</pre>
+ * This cache will evict entries as necessary to keep its size from exceeding
+ * 10 MiB. The best cache size is application specific and depends on the size
+ * and frequency of the files being downloaded. Increasing the limit may improve
+ * the hit rate, but it may also just waste filesystem space!
+ *
+ * <p>For some applications it may be preferable to create the cache in the
+ * external storage directory. Although it often has more free space, external
+ * storage is optional and&#8212;even if available&#8212;can disappear during
+ * use. Retrieve the external cache directory using {@link Context#getExternalCacheDir()}. If this method
+ * returns null, your application should fall back to either not caching or
+ * caching on non-external storage. If the external storage is removed during
+ * use, the cache hit rate will drop to zero and ongoing cache reads will fail.
+ *
+ * <p>Flushing the cache forces its data to the filesystem. This ensures that
+ * all responses written to the cache will be readable the next time the
+ * activity starts.
+ *
+ * <h3>Cache Optimization</h3>
+ * To measure cache effectiveness, this class tracks three statistics:
+ * <ul>
+ *     <li><strong>{@link #getRequestCount() Request Count:}</strong> the number
+ *         of HTTP requests issued since this cache was created.
+ *     <li><strong>{@link #getNetworkCount() Network Count:}</strong> the
+ *         number of those requests that required network use.
+ *     <li><strong>{@link #getHitCount() Hit Count:}</strong> the number of
+ *         those requests whose responses were served by the cache.
+ * </ul>
+ * Sometimes a request will result in a conditional cache hit. If the cache
+ * contains a stale copy of the response, the client will issue a conditional
+ * {@code GET}. The server will then send either the updated response if it has
+ * changed, or a short 'not modified' response if the client's copy is still
+ * valid. Such responses increment both the network count and hit count.
+ *
+ * <p>The best way to improve the cache hit rate is by configuring the web
+ * server to return cacheable responses. Although this client honors all <a
+ * href="http://www.ietf.org/rfc/rfc2616.txt">HTTP/1.1 (RFC 2068)</a> cache
+ * headers, it doesn't cache partial responses.
+ *
+ * <h3>Force a Network Response</h3>
+ * In some situations, such as after a user clicks a 'refresh' button, it may be
+ * necessary to skip the cache, and fetch data directly from the server. To force
+ * a full refresh, add the {@code no-cache} directive: <pre>   {@code
+ *         connection.addRequestProperty("Cache-Control", "no-cache");
+ * }</pre>
+ * If it is only necessary to force a cached response to be validated by the
+ * server, use the more efficient {@code max-age=0} instead: <pre>   {@code
+ *         connection.addRequestProperty("Cache-Control", "max-age=0");
+ * }</pre>
+ *
+ * <h3>Force a Cache Response</h3>
+ * Sometimes you'll want to show resources if they are available immediately,
+ * but not otherwise. This can be used so your application can show
+ * <i>something</i> while waiting for the latest data to be downloaded. To
+ * restrict a request to locally-cached resources, add the {@code
+ * only-if-cached} directive: <pre>   {@code
+ *     try {
+ *         connection.addRequestProperty("Cache-Control", "only-if-cached");
+ *         InputStream cached = connection.getInputStream();
+ *         // the resource was cached! show it
+ *     } catch (FileNotFoundException e) {
+ *         // the resource was not cached
+ *     }
+ * }</pre>
+ * This technique works even better in situations where a stale response is
+ * better than no response. To permit stale cached responses, use the {@code
+ * max-stale} directive with the maximum staleness in seconds: <pre>   {@code
+ *         int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
+ *         connection.addRequestProperty("Cache-Control", "max-stale=" + maxStale);
+ * }</pre>
+ */
+public final class HttpResponseCache extends ResponseCache implements Closeable {
+
+    private final libcore.net.http.HttpResponseCache delegate;
+
+    private HttpResponseCache(File directory, long maxSize) throws IOException {
+        this.delegate = new libcore.net.http.HttpResponseCache(directory, maxSize);
+    }
+
+    /**
+     * Returns the currently-installed {@code HttpResponseCache}, or null if
+     * there is no cache installed or it is not a {@code HttpResponseCache}.
+     */
+    public static HttpResponseCache getInstalled() {
+        ResponseCache installed = ResponseCache.getDefault();
+        return installed instanceof HttpResponseCache ? (HttpResponseCache) installed : null;
+    }
+
+    /**
+     * Creates a new HTTP response cache and {@link ResponseCache#setDefault
+     * sets it} as the system default cache.
+     *
+     * @param directory the directory to hold cache data.
+     * @param maxSize the maximum size of the cache in bytes.
+     * @return the newly-installed cache
+     * @throws IOException if {@code directory} cannot be used for this cache.
+     *     Most applications should respond to this exception by logging a
+     *     warning.
+     */
+    public static HttpResponseCache install(File directory, long maxSize) throws IOException {
+        HttpResponseCache installed = getInstalled();
+        if (installed != null) {
+            // don't close and reopen if an equivalent cache is already installed
+            DiskLruCache installedCache = installed.delegate.getCache();
+            if (installedCache.getDirectory().equals(directory)
+                    && installedCache.maxSize() == maxSize
+                    && !installedCache.isClosed()) {
+                return installed;
+            } else {
+                IoUtils.closeQuietly(installed);
+            }
+        }
+
+        HttpResponseCache result = new HttpResponseCache(directory, maxSize);
+        ResponseCache.setDefault(result);
+        return result;
+    }
+
+    @Override public CacheResponse get(URI uri, String requestMethod,
+            Map<String, List<String>> requestHeaders) throws IOException {
+        return delegate.get(uri, requestMethod, requestHeaders);
+    }
+
+    @Override public CacheRequest put(URI uri, URLConnection urlConnection) throws IOException {
+        return delegate.put(uri, urlConnection);
+    }
+
+    /**
+     * Returns the number of bytes currently being used to store the values in
+     * this cache. This may be greater than the {@link #maxSize} if a background
+     * deletion is pending.
+     */
+    public long size() {
+        return delegate.getCache().size();
+    }
+
+    /**
+     * Returns the maximum number of bytes that this cache should use to store
+     * its data.
+     */
+    public long maxSize() {
+        return delegate.getCache().maxSize();
+    }
+
+    /**
+     * Force buffered operations to the filesystem. This ensures that responses
+     * written to the cache will be available the next time the cache is opened,
+     * even if this process is killed.
+     */
+    public void flush() {
+        try {
+            delegate.getCache().flush(); // TODO: fix flush() to not throw?
+        } catch (IOException ignored) {
+        }
+    }
+
+    /**
+     * Returns the number of HTTP requests that required the network to either
+     * supply a response or validate a locally cached response.
+     */
+    public int getNetworkCount() {
+        return delegate.getNetworkCount();
+    }
+
+    /**
+     * Returns the number of HTTP requests whose response was provided by the
+     * cache. This may include conditional {@code GET} requests that were
+     * validated over the network.
+     */
+    public int getHitCount() {
+        return delegate.getHitCount();
+    }
+
+    /**
+     * Returns the total number of HTTP requests that were made. This includes
+     * both client requests and requests that were made on the client's behalf
+     * to handle a redirects and retries.
+     */
+    public int getRequestCount() {
+        return delegate.getRequestCount();
+    }
+
+    /**
+     * Uninstalls the cache and releases any active resources. Stored contents
+     * will remain on the filesystem.
+     */
+    @Override public void close() throws IOException {
+        if (ResponseCache.getDefault() == this) {
+            ResponseCache.setDefault(null);
+        }
+        delegate.getCache().close();
+    }
+
+    /**
+     * Uninstalls the cache and deletes all of its stored contents.
+     */
+    public void delete() throws IOException {
+        if (ResponseCache.getDefault() == this) {
+            ResponseCache.setDefault(null);
+        }
+        delegate.getCache().delete();
+    }
+}
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index 746d3df..fe215fd 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -163,6 +163,18 @@
      *                must not be null
      */
     public NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload) {
+        /* New NDEF records created by applications will have FLAG_MB|FLAG_ME
+         * set by default; when multiple records are stored in a
+         * {@link NdefMessage}, these flags will be corrected when the {@link NdefMessage}
+         * is serialized to bytes.
+         */
+        this(tnf, type, id, payload, (byte)(FLAG_MB|FLAG_ME));
+    }
+
+    /**
+     * @hide
+     */
+    /*package*/ NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload, byte flags) {
         /* check arguments */
         if ((type == null) || (id == null) || (payload == null)) {
             throw new IllegalArgumentException("Illegal null argument");
@@ -172,9 +184,6 @@
             throw new IllegalArgumentException("TNF out of range " + tnf);
         }
 
-        /* generate flag */
-        byte flags = FLAG_MB | FLAG_ME;
-
         /* Determine if it is a short record */
         if(payload.length < 0xFF) {
             flags |= FLAG_SR;
@@ -258,6 +267,7 @@
     }
 
     public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mFlags);
         dest.writeInt(mTnf);
         dest.writeInt(mType.length);
         dest.writeByteArray(mType);
@@ -270,6 +280,7 @@
     public static final Parcelable.Creator<NdefRecord> CREATOR =
             new Parcelable.Creator<NdefRecord>() {
         public NdefRecord createFromParcel(Parcel in) {
+            byte flags = (byte)in.readInt();
             short tnf = (short)in.readInt();
             int typeLength = in.readInt();
             byte[] type = new byte[typeLength];
@@ -281,7 +292,7 @@
             byte[] payload = new byte[payloadLength];
             in.readByteArray(payload);
 
-            return new NdefRecord(tnf, type, id, payload);
+            return new NdefRecord(tnf, type, id, payload, flags);
         }
         public NdefRecord[] newArray(int size) {
             return new NdefRecord[size];
@@ -290,4 +301,4 @@
 
     private native int parseNdefRecord(byte[] data);
     private native byte[] generate(short flags, short tnf, byte[] type, byte[] id, byte[] data);
-}
\ No newline at end of file
+}
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 5e1be21..b6d1594 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -472,11 +472,15 @@
         
         final View layout = layoutInflater.inflate(mLayoutResId, parent, false); 
         
-        if (mWidgetLayoutResId != 0) {
-            final ViewGroup widgetFrame = (ViewGroup)layout.findViewById(com.android.internal.R.id.widget_frame);
-            layoutInflater.inflate(mWidgetLayoutResId, widgetFrame);
+        final ViewGroup widgetFrame = (ViewGroup) layout
+                .findViewById(com.android.internal.R.id.widget_frame);
+        if (widgetFrame != null) {
+            if (mWidgetLayoutResId != 0) {
+                layoutInflater.inflate(mWidgetLayoutResId, widgetFrame);
+            } else {
+                widgetFrame.setVisibility(View.GONE);
+            }
         }
-
         return layout;
     }
     
@@ -514,14 +518,18 @@
         }
         
         ImageView imageView = (ImageView) view.findViewById(com.android.internal.R.id.icon);
-        if (imageView != null && (mIconResId != 0 || mIcon != null)) {
-            if (mIcon == null) {
-                mIcon = getContext().getResources().getDrawable(mIconResId);
+        if (imageView != null) {
+            if (mIconResId != 0 || mIcon != null) {
+                if (mIcon == null) {
+                    mIcon = getContext().getResources().getDrawable(mIconResId);
+                }
+                if (mIcon != null) {
+                    imageView.setImageDrawable(mIcon);
+                }
             }
-            if (mIcon != null) {
-                imageView.setImageDrawable(mIcon);
-            }
+            imageView.setVisibility(mIcon != null ? View.VISIBLE : View.GONE);
         }
+
         if (mShouldDisableView) {
             setEnabledStateOnViews(view, isEnabled());
         }
@@ -633,6 +641,7 @@
     public void setIcon(Drawable icon) {
         if ((icon == null && mIcon != null) || (icon != null && mIcon != icon)) {
             mIcon = icon;
+
             notifyChanged();
         }
     }
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 15d5898..14e7bed 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -18,9 +18,6 @@
 
 import com.android.internal.util.XmlUtils;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
 import android.app.ActionBar;
 import android.app.Fragment;
 import android.app.FragmentBreadCrumbs;
@@ -44,8 +41,8 @@
 import android.util.Xml;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
+import android.view.View.OnClickListener;
 import android.widget.AbsListView;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
@@ -58,6 +55,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 /**
  * This is the base class for an activity to show a hierarchy of preferences
  * to the user.  Prior to {@link android.os.Build.VERSION_CODES#HONEYCOMB}
@@ -503,12 +503,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        if (getResources().getConfiguration().isLayoutSizeAtLeast(
-                Configuration.SCREENLAYOUT_SIZE_LARGE)) {
-            setContentView(com.android.internal.R.layout.preference_list_content_large);
-        } else {
-            setContentView(com.android.internal.R.layout.preference_list_content);
-        }
+        setContentView(com.android.internal.R.layout.preference_list_content);
 
         mListFooter = (FrameLayout)findViewById(com.android.internal.R.id.list_footer);
         mPrefsContainer = (ViewGroup) findViewById(com.android.internal.R.id.prefs_frame);
@@ -585,12 +580,7 @@
         } else {
             // If there are no headers, we are in the old "just show a screen
             // of preferences" mode.
-            if (getResources().getConfiguration().isLayoutSizeAtLeast(
-                    Configuration.SCREENLAYOUT_SIZE_LARGE)) {
-                setContentView(com.android.internal.R.layout.preference_list_content_single_large);
-            } else {
-                setContentView(com.android.internal.R.layout.preference_list_content_single);
-            }
+            setContentView(com.android.internal.R.layout.preference_list_content_single);
             mListFooter = (FrameLayout) findViewById(com.android.internal.R.id.list_footer);
             mPrefsContainer = (ViewGroup) findViewById(com.android.internal.R.id.prefs);
             mPreferenceManager = new PreferenceManager(this, FIRST_REQUEST_CODE);
@@ -674,17 +664,9 @@
      * enough.
      */
     public boolean onIsMultiPane() {
-        Configuration config = getResources().getConfiguration();
-        if ((config.screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK)
-                == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
-            return true;
-        }
-        if ((config.screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK)
-                == Configuration.SCREENLAYOUT_SIZE_LARGE
-                && config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
-            return true;
-        }
-        return false;
+        boolean preferMultiPane = getResources().getBoolean(
+                com.android.internal.R.bool.preferences_prefer_dual_pane);
+        return preferMultiPane;
     }
 
     /**
diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java
index 7511e14..9d46b7a 100644
--- a/core/java/android/preference/PreferenceFragment.java
+++ b/core/java/android/preference/PreferenceFragment.java
@@ -152,14 +152,8 @@
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
-        if (getResources().getConfiguration().isLayoutSizeAtLeast(
-                Configuration.SCREENLAYOUT_SIZE_LARGE)) {
-            return inflater.inflate(com.android.internal.R.layout.preference_list_fragment_large,
-                    container, false);
-        } else {
-            return inflater.inflate(com.android.internal.R.layout.preference_list_fragment,
-                    container, false);
-        }
+        return inflater.inflate(com.android.internal.R.layout.preference_list_fragment, container,
+                false);
     }
 
     @Override
diff --git a/core/java/android/text/MeasuredText.java b/core/java/android/text/MeasuredText.java
index 761c271..a81be09 100644
--- a/core/java/android/text/MeasuredText.java
+++ b/core/java/android/text/MeasuredText.java
@@ -16,14 +16,14 @@
 
 package android.text;
 
-import com.android.internal.util.ArrayUtils;
-
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.text.style.MetricAffectingSpan;
 import android.text.style.ReplacementSpan;
 import android.util.Log;
 
+import com.android.internal.util.ArrayUtils;
+
 /**
  * @hide
  */
@@ -187,6 +187,7 @@
             w[mPos] = wid;
             for (int i = mPos + 1, e = mPos + len; i < e; i++)
                 w[i] = 0;
+            mPos += len;
         }
 
         if (fm != null) {
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 0f8097a..f5249611 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -43,6 +43,8 @@
  * @hide
  */
 class TextLine {
+    private static final boolean DEBUG = false;
+
     private TextPaint mPaint;
     private CharSequence mText;
     private int mStart;
@@ -56,7 +58,7 @@
     private Spanned mSpanned;
     private final TextPaint mWorkPaint = new TextPaint();
 
-    private static TextLine[] cached = new TextLine[3];
+    private static final TextLine[] sCached = new TextLine[3];
 
     /**
      * Returns a new TextLine from the shared pool.
@@ -65,17 +67,19 @@
      */
     static TextLine obtain() {
         TextLine tl;
-        synchronized (cached) {
-            for (int i = cached.length; --i >= 0;) {
-                if (cached[i] != null) {
-                    tl = cached[i];
-                    cached[i] = null;
+        synchronized (sCached) {
+            for (int i = sCached.length; --i >= 0;) {
+                if (sCached[i] != null) {
+                    tl = sCached[i];
+                    sCached[i] = null;
                     return tl;
                 }
             }
         }
         tl = new TextLine();
-        Log.v("TLINE", "new: " + tl);
+        if (DEBUG) {
+            Log.v("TLINE", "new: " + tl);
+        }
         return tl;
     }
 
@@ -90,10 +94,10 @@
         tl.mText = null;
         tl.mPaint = null;
         tl.mDirections = null;
-        synchronized(cached) {
-            for (int i = 0; i < cached.length; ++i) {
-                if (cached[i] == null) {
-                    cached[i] = tl;
+        synchronized(sCached) {
+            for (int i = 0; i < sCached.length; ++i) {
+                if (sCached[i] == null) {
+                    sCached[i] = tl;
                     break;
                 }
             }
@@ -175,11 +179,11 @@
     void draw(Canvas c, float x, int top, int y, int bottom) {
         if (!mHasTabs) {
             if (mDirections == Layout.DIRS_ALL_LEFT_TO_RIGHT) {
-                drawRun(c, 0, 0, mLen, false, x, top, y, bottom, false);
+                drawRun(c, 0, mLen, false, x, top, y, bottom, false);
                 return;
             }
             if (mDirections == Layout.DIRS_ALL_RIGHT_TO_LEFT) {
-                drawRun(c, 0, 0, mLen, true, x, top, y, bottom, false);
+                drawRun(c, 0, mLen, true, x, top, y, bottom, false);
                 return;
             }
         }
@@ -216,7 +220,7 @@
                 }
 
                 if (j == runLimit || codept == '\t' || bm != null) {
-                    h += drawRun(c, i, segstart, j, runIsRtl, x+h, top, y, bottom,
+                    h += drawRun(c, segstart, j, runIsRtl, x+h, top, y, bottom,
                             i != lastRunIndex || j != mLen);
 
                     if (codept == '\t') {
@@ -275,10 +279,10 @@
 
         if (!mHasTabs) {
             if (mDirections == Layout.DIRS_ALL_LEFT_TO_RIGHT) {
-                return measureRun(0, 0, offset, mLen, false, fmi);
+                return measureRun(0, offset, mLen, false, fmi);
             }
             if (mDirections == Layout.DIRS_ALL_RIGHT_TO_LEFT) {
-                return measureRun(0, 0, offset, mLen, true, fmi);
+                return measureRun(0, offset, mLen, true, fmi);
             }
         }
 
@@ -315,14 +319,14 @@
 
                     boolean advance = (mDir == Layout.DIR_RIGHT_TO_LEFT) == runIsRtl;
                     if (inSegment && advance) {
-                        return h += measureRun(i, segstart, offset, j, runIsRtl, fmi);
+                        return h += measureRun(segstart, offset, j, runIsRtl, fmi);
                     }
 
-                    float w = measureRun(i, segstart, j, j, runIsRtl, fmi);
+                    float w = measureRun(segstart, j, j, runIsRtl, fmi);
                     h += advance ? w : -w;
 
                     if (inSegment) {
-                        return h += measureRun(i, segstart, offset, j, runIsRtl, null);
+                        return h += measureRun(segstart, offset, j, runIsRtl, null);
                     }
 
                     if (codept == '\t') {
@@ -353,8 +357,8 @@
     /**
      * Draws a unidirectional (but possibly multi-styled) run of text.
      *
+     *
      * @param c the canvas to draw on
-     * @param runIndex the index of this directional run
      * @param start the line-relative start
      * @param limit the line-relative limit
      * @param runIsRtl true if the run is right-to-left
@@ -366,25 +370,25 @@
      * @return the signed width of the run, based on the paragraph direction.
      * Only valid if needWidth is true.
      */
-    private float drawRun(Canvas c, int runIndex, int start,
+    private float drawRun(Canvas c, int start,
             int limit, boolean runIsRtl, float x, int top, int y, int bottom,
             boolean needWidth) {
 
         if ((mDir == Layout.DIR_LEFT_TO_RIGHT) == runIsRtl) {
-            float w = -measureRun(runIndex, start, limit, limit, runIsRtl, null);
-            handleRun(runIndex, start, limit, limit, runIsRtl, c, x + w, top,
+            float w = -measureRun(start, limit, limit, runIsRtl, null);
+            handleRun(start, limit, limit, runIsRtl, c, x + w, top,
                     y, bottom, null, false);
             return w;
         }
 
-        return handleRun(runIndex, start, limit, limit, runIsRtl, c, x, top,
+        return handleRun(start, limit, limit, runIsRtl, c, x, top,
                 y, bottom, null, needWidth);
     }
 
     /**
      * Measures a unidirectional (but possibly multi-styled) run of text.
      *
-     * @param runIndex the run index
+     *
      * @param start the line-relative start of the run
      * @param offset the offset to measure to, between start and limit inclusive
      * @param limit the line-relative limit of the run
@@ -394,10 +398,9 @@
      * @return the signed width from the start of the run to the leading edge
      * of the character at offset, based on the run (not paragraph) direction
      */
-    private float measureRun(int runIndex, int start,
-            int offset, int limit, boolean runIsRtl, FontMetricsInt fmi) {
-        return handleRun(runIndex, start, offset, limit, runIsRtl, null,
-                0, 0, 0, 0, fmi, true);
+    private float measureRun(int start, int offset, int limit, boolean runIsRtl,
+            FontMetricsInt fmi) {
+        return handleRun(start, offset, limit, runIsRtl, null, 0, 0, 0, 0, fmi, true);
     }
 
     /**
@@ -751,9 +754,9 @@
     /**
      * Utility function for measuring and rendering a replacement.
      *
+     *
      * @param replacement the replacement
      * @param wp the work paint
-     * @param runIndex the run index
      * @param start the start of the run
      * @param limit the limit of the run
      * @param runIsRtl true if the run is right-to-left
@@ -768,7 +771,7 @@
      * valid if needWidth is true
      */
     private float handleReplacement(ReplacementSpan replacement, TextPaint wp,
-            int runIndex, int start, int limit, boolean runIsRtl, Canvas c,
+            int start, int limit, boolean runIsRtl, Canvas c,
             float x, int top, int y, int bottom, FontMetricsInt fmi,
             boolean needWidth) {
 
@@ -796,7 +799,7 @@
      * Utility function for handling a unidirectional run.  The run must not
      * contain tabs or emoji but can contain styles.
      *
-     * @param runIndex the run index
+     *
      * @param start the line-relative start of the run
      * @param measureLimit the offset to measure to, between start and limit inclusive
      * @param limit the limit of the run
@@ -811,7 +814,7 @@
      * @return the signed width of the run based on the run direction; only
      * valid if needWidth is true
      */
-    private float handleRun(int runIndex, int start, int measureLimit,
+    private float handleRun(int start, int measureLimit,
             int limit, boolean runIsRtl, Canvas c, float x, int top, int y,
             int bottom, FontMetricsInt fmi, boolean needWidth) {
 
@@ -859,7 +862,7 @@
                     }
 
                     if (replacement != null) {
-                        x += handleReplacement(replacement, wp, runIndex, i,
+                        x += handleReplacement(replacement, wp, i,
                                 mlimit, runIsRtl, c, x, top, y, bottom, fmi,
                                 needWidth || mlimit < measureLimit);
                         continue;
diff --git a/core/java/android/view/Gravity.java b/core/java/android/view/Gravity.java
index cf79638..176c487 100644
--- a/core/java/android/view/Gravity.java
+++ b/core/java/android/view/Gravity.java
@@ -80,9 +80,12 @@
     /** Flag to clip the edges of the object to its container along the
      *  horizontal axis. */
     public static final int CLIP_HORIZONTAL = AXIS_CLIP<<AXIS_X_SHIFT;
-    
+
+    /** Raw bit controlling whether the horizontal direction is relative (before/after) or not. */
+    public static final int RELATIVE_HORIZONTAL_DIRECTION = 0x00800000;
+
     /**
-     * Binary mask to get the horizontal gravity of a gravity.
+     * Binary mask to get the absolute horizontal gravity of a gravity.
      */
     public static final int HORIZONTAL_GRAVITY_MASK = (AXIS_SPECIFIED |
             AXIS_PULL_BEFORE | AXIS_PULL_AFTER) << AXIS_X_SHIFT;
@@ -106,8 +109,19 @@
      */
     public static final int DISPLAY_CLIP_HORIZONTAL = 0x01000000;
     
+    /** Push object to x-axis position before its container, not changing its size. */
+    public static final int BEFORE = RELATIVE_HORIZONTAL_DIRECTION | LEFT;
+
+    /** Push object to x-axis position after its container, not changing its size. */
+    public static final int AFTER = RELATIVE_HORIZONTAL_DIRECTION | RIGHT;
+
     /**
-     * Apply a gravity constant to an object.
+     * Binary mask for the horizontal gravity and script specific direction bit.
+     */
+    public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = BEFORE | AFTER;
+
+    /**
+     * Apply a gravity constant to an object. This suppose that the layout direction is LTR.
      * 
      * @param gravity The desired placement of the object, as defined by the
      *                constants in this class.
@@ -119,12 +133,33 @@
      * @param outRect Receives the computed frame of the object in its
      *                container.
      */
-    public static void apply(int gravity, int w, int h, Rect container,
-                             Rect outRect) {
+    public static void apply(int gravity, int w, int h, Rect container, Rect outRect) {
         apply(gravity, w, h, container, 0, 0, outRect);
     }
 
     /**
+     * Apply a gravity constant to an object and take care if layout direction is RTL or not.
+     *
+     * @param gravity The desired placement of the object, as defined by the
+     *                constants in this class.
+     * @param w The horizontal size of the object.
+     * @param h The vertical size of the object.
+     * @param container The frame of the containing space, in which the object
+     *                  will be placed.  Should be large enough to contain the
+     *                  width and height of the object.
+     * @param outRect Receives the computed frame of the object in its
+     *                container.
+     * @param isRtl Whether the layout is right-to-left.
+     *
+     * @hide
+     */
+    public static void apply(int gravity, int w, int h, Rect container,
+            Rect outRect, boolean isRtl) {
+        int absGravity = getAbsoluteGravity(gravity, isRtl);
+        apply(absGravity, w, h, container, 0, 0, outRect);
+    }
+
+    /**
      * Apply a gravity constant to an object.
      * 
      * @param gravity The desired placement of the object, as defined by the
@@ -146,7 +181,7 @@
      *                container.
      */
     public static void apply(int gravity, int w, int h, Rect container,
-                             int xAdj, int yAdj, Rect outRect) {
+            int xAdj, int yAdj, Rect outRect) {
         switch (gravity&((AXIS_PULL_BEFORE|AXIS_PULL_AFTER)<<AXIS_X_SHIFT)) {
             case 0:
                 outRect.left = container.left
@@ -301,6 +336,54 @@
      * @return true if the supplied gravity has an horizontal pull
      */
     public static boolean isHorizontal(int gravity) {
-        return gravity > 0 && (gravity & HORIZONTAL_GRAVITY_MASK) != 0;
+        return gravity > 0 && (gravity & RELATIVE_HORIZONTAL_GRAVITY_MASK) != 0;
+    }
+
+    /**
+     * <p>Convert script specific gravity to absolute horizontal value.</p>
+     *
+     * if horizontal direction is LTR, then BEFORE will set LEFT and AFTER will set RIGHT.
+     * if horizontal direction is RTL, then BEFORE will set RIGHT and AFTER will set LEFT.
+     *
+     * If no horizontal direction is found, then just add LEFT to the existing gravity
+     *
+     * @param gravity The gravity to convert to absolute (horizontal) values.
+     * @param isRtl Whether the layout is right-to-left.
+     * @return gravity converted to absolute (horizontal) values.
+     */
+    public static int getAbsoluteGravity(int gravity, boolean isRtl) {
+        int result = gravity;
+        // Set default gravity, if no horizontal gravity is specified
+        if ((result & HORIZONTAL_GRAVITY_MASK) == 0) {
+            result |= Gravity.LEFT;
+        }
+        // If layout is script specific and gravity is horizontal relative (BEFORE or AFTER)
+        if ((result & RELATIVE_HORIZONTAL_DIRECTION) > 0) {
+            if ((result & Gravity.BEFORE) == Gravity.BEFORE) {
+                // Remove the BEFORE bit
+                result &= ~BEFORE;
+                if (isRtl) {
+                    // Set the RIGHT bit
+                    result |= RIGHT;
+                } else {
+                    // Set the LEFT bit
+                    result |= LEFT;
+                }
+            } else if ((result & Gravity.AFTER) == Gravity.AFTER) {
+                // Remove the AFTER bit
+                result &= ~AFTER;
+                if (isRtl) {
+                    // Set the LEFT bit
+                    result |= LEFT;
+                } else {
+                    // Set the RIGHT bit
+                    result |= RIGHT;
+                }
+            }
+            // Don't need the script specific bit any more, so remove it as we are converting to
+            // absolute values (LEFT or RIGHT)
+            result &= ~RELATIVE_HORIZONTAL_DIRECTION;
+        }
+        return result;
     }
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e54046d..017e5e3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -631,7 +631,7 @@
  *
  * @see android.view.ViewGroup
  */
-public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
+public class View implements Drawable.Callback2, KeyEvent.Callback, AccessibilityEventSource {
     private static final boolean DBG = false;
 
     /**
@@ -10238,6 +10238,15 @@
         }
     }
 
+     /**
+     * Check if a given Drawable is in RTL layout direction.
+     *
+     * @param who the recipient of the action
+     */
+    public boolean isLayoutRtl(Drawable who) {
+        return (who == mBGDrawable) && isLayoutRtl();
+    }
+
     /**
      * If your view subclass is displaying its own Drawable objects, it should
      * override this function and return true for any Drawable it is
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 9395d5c..a1ddd08 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -77,8 +77,8 @@
             implements Parcelable {
         /**
          * X position for this window.  With the default gravity it is ignored.
-         * When using {@link Gravity#LEFT} or {@link Gravity#RIGHT} it provides
-         * an offset from the given edge.
+         * When using {@link Gravity#LEFT} or {@link Gravity#BEFORE} or {@link Gravity#RIGHT} or
+         * {@link Gravity#AFTER} it provides an offset from the given edge.
          */
         @ViewDebug.ExportedProperty
         public int x;
diff --git a/core/java/android/webkit/DataLoader.java b/core/java/android/webkit/DataLoader.java
index 235dc5be..e8d9069 100644
--- a/core/java/android/webkit/DataLoader.java
+++ b/core/java/android/webkit/DataLoader.java
@@ -22,7 +22,7 @@
 
 import java.io.ByteArrayInputStream;
 
-import org.apache.harmony.luni.util.Base64;
+import libcore.io.Base64;
 
 /**
  * This class is a concrete implementation of StreamLoader that uses the
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 7f4f103..a480b84 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -1173,7 +1173,7 @@
                 imeOptions |= EditorInfo.IME_ACTION_SEARCH;
                 break;
             case EMAIL:
-                inputType = EditorInfo.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
+                inputType |= EditorInfo.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
                 imeOptions |= EditorInfo.IME_ACTION_GO;
                 break;
             case NUMBER:
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index f4300a5..680bb7d 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2572,17 +2572,6 @@
     }
 
     @Override
-    public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
-        // Add a record for ourselves as well.
-        AccessibilityEvent record = AccessibilityEvent.obtain();
-        // Set the class since it is not populated in #dispatchPopulateAccessibilityEvent
-        record.setClassName(getClass().getName());
-        child.dispatchPopulateAccessibilityEvent(record);
-        event.appendRecord(record);
-        return true;
-    }
-
-    @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         return false;
     }
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 14ea853..c4d05e9 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -887,14 +887,28 @@
         // We first get a chance to populate the event.
         onPopulateAccessibilityEvent(event);
 
+        return false;
+    }
+
+    @Override
+    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
         // We send selection events only from AdapterView to avoid
         // generation of such event for each child.
         View selectedView = getSelectedView();
         if (selectedView != null) {
-            return selectedView.dispatchPopulateAccessibilityEvent(event);
+            selectedView.dispatchPopulateAccessibilityEvent(event);
         }
+    }
 
-        return false;
+    @Override
+    public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
+        // Add a record for ourselves as well.
+        AccessibilityEvent record = AccessibilityEvent.obtain();
+        // Set the class since it is not populated in #dispatchPopulateAccessibilityEvent
+        record.setClassName(getClass().getName());
+        child.dispatchPopulateAccessibilityEvent(record);
+        event.appendRecord(record);
+        return true;
     }
 
     @Override
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 0659063..2a1398d 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -115,7 +115,7 @@
     }
 
     /**
-     * Describes how the foreground is positioned. Defaults to FILL.
+     * Describes how the foreground is positioned. Defaults to BEFORE and TOP.
      *
      * @param foregroundGravity See {@link android.view.Gravity}
      *
@@ -124,8 +124,8 @@
     @android.view.RemotableViewMethod
     public void setForegroundGravity(int foregroundGravity) {
         if (mForegroundGravity != foregroundGravity) {
-            if ((foregroundGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) {
-                foregroundGravity |= Gravity.LEFT;
+            if ((foregroundGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
+                foregroundGravity |= Gravity.BEFORE;
             }
 
             if ((foregroundGravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
@@ -364,7 +364,7 @@
                     gravity = DEFAULT_CHILD_GRAVITY;
                 }
 
-                final int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+                final int horizontalGravity = Gravity.getAbsoluteGravity(gravity, isLayoutRtl());
                 final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
 
                 switch (horizontalGravity) {
@@ -436,7 +436,7 @@
                 }
 
                 Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
-                        foreground.getIntrinsicHeight(), selfBounds, overlayBounds);
+                        foreground.getIntrinsicHeight(), selfBounds, overlayBounds, isLayoutRtl());
                 foreground.setBounds(overlayBounds);
             }
             
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 0383b5c..732cedc 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1408,19 +1408,20 @@
         int childLeft;
         final int childTop = flow ? y : y - h;
 
-        switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
-        case Gravity.LEFT:
-            childLeft = childrenLeft;
-            break;
-        case Gravity.CENTER_HORIZONTAL:
-            childLeft = childrenLeft + ((mColumnWidth - w) / 2);
-            break;
-        case Gravity.RIGHT:
-            childLeft = childrenLeft + mColumnWidth - w;
-            break;
-        default:
-            childLeft = childrenLeft;
-            break;
+        final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity,isLayoutRtl());
+        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+            case Gravity.LEFT:
+                childLeft = childrenLeft;
+                break;
+            case Gravity.CENTER_HORIZONTAL:
+                childLeft = childrenLeft + ((mColumnWidth - w) / 2);
+                break;
+            case Gravity.RIGHT:
+                childLeft = childrenLeft + mColumnWidth - w;
+                break;
+            default:
+                childLeft = childrenLeft;
+                break;
         }
 
         if (needToMeasure) {
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index d8068f9..4b870ec 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -187,6 +187,11 @@
     }
 
     @Override
+    public boolean isLayoutRtl(Drawable dr) {
+        return (dr == mDrawable) ? isLayoutRtl() : super.isLayoutRtl(dr);
+    }
+
+    @Override
     protected boolean onSetAlpha(int alpha) {
         if (getBackground() == null) {
             int scale = alpha + (alpha >> 7);
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 6f30452..8d449e0 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -110,6 +110,8 @@
             @ViewDebug.IntToString(from = Gravity.BOTTOM,            to = "BOTTOM"),
             @ViewDebug.IntToString(from = Gravity.LEFT,              to = "LEFT"),
             @ViewDebug.IntToString(from = Gravity.RIGHT,             to = "RIGHT"),
+            @ViewDebug.IntToString(from = Gravity.BEFORE,            to = "BEFORE"),
+            @ViewDebug.IntToString(from = Gravity.AFTER,             to = "AFTER"),
             @ViewDebug.IntToString(from = Gravity.CENTER_VERTICAL,   to = "CENTER_VERTICAL"),
             @ViewDebug.IntToString(from = Gravity.FILL_VERTICAL,     to = "FILL_VERTICAL"),
             @ViewDebug.IntToString(from = Gravity.CENTER_HORIZONTAL, to = "CENTER_HORIZONTAL"),
@@ -117,7 +119,7 @@
             @ViewDebug.IntToString(from = Gravity.CENTER,            to = "CENTER"),
             @ViewDebug.IntToString(from = Gravity.FILL,              to = "FILL")
         })
-    private int mGravity = Gravity.LEFT | Gravity.TOP;
+    private int mGravity = Gravity.BEFORE | Gravity.TOP;
 
     @ViewDebug.ExportedProperty(category = "measurement")
     private int mTotalLength;
@@ -1394,7 +1396,7 @@
         final int count = getVirtualChildCount();
 
         final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
-        final int minorGravity = mGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+        final int minorGravity = mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
 
         switch (majorGravity) {
            case Gravity.BOTTOM:
@@ -1428,7 +1430,7 @@
                 if (gravity < 0) {
                     gravity = minorGravity;
                 }
-
+                gravity = Gravity.getAbsoluteGravity(gravity, isLayoutRtl());
                 switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
                     case Gravity.CENTER_HORIZONTAL:
                         childLeft = paddingLeft + ((childSpace - childWidth) / 2)
@@ -1483,7 +1485,7 @@
 
         final int count = getVirtualChildCount();
 
-        final int majorGravity = mGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+        final int majorGravity = mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
         final int minorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
 
         final boolean baselineAligned = mBaselineAligned;
@@ -1491,7 +1493,7 @@
         final int[] maxAscent = mMaxAscent;
         final int[] maxDescent = mMaxDescent;
 
-        switch (majorGravity) {
+        switch (Gravity.getAbsoluteGravity(majorGravity, isLayoutRtl())) {
             case Gravity.RIGHT:
                 // mTotalLength contains the padding already
                 childLeft = mPaddingLeft + mRight - mLeft - mTotalLength;
@@ -1630,8 +1632,8 @@
     @android.view.RemotableViewMethod
     public void setGravity(int gravity) {
         if (mGravity != gravity) {
-            if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) {
-                gravity |= Gravity.LEFT;
+            if ((gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
+                gravity |= Gravity.BEFORE;
             }
 
             if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
@@ -1645,9 +1647,9 @@
 
     @android.view.RemotableViewMethod
     public void setHorizontalGravity(int horizontalGravity) {
-        final int gravity = horizontalGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
-        if ((mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != gravity) {
-            mGravity = (mGravity & ~Gravity.HORIZONTAL_GRAVITY_MASK) | gravity;
+        final int gravity = horizontalGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
+        if ((mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) != gravity) {
+            mGravity = (mGravity & ~Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) | gravity;
             requestLayout();
         }
     }
@@ -1724,6 +1726,8 @@
             @ViewDebug.IntToString(from = Gravity.BOTTOM,            to = "BOTTOM"),
             @ViewDebug.IntToString(from = Gravity.LEFT,              to = "LEFT"),
             @ViewDebug.IntToString(from = Gravity.RIGHT,             to = "RIGHT"),
+            @ViewDebug.IntToString(from = Gravity.BEFORE,            to = "BEFORE"),
+            @ViewDebug.IntToString(from = Gravity.AFTER,             to = "AFTER"),
             @ViewDebug.IntToString(from = Gravity.CENTER_VERTICAL,   to = "CENTER_VERTICAL"),
             @ViewDebug.IntToString(from = Gravity.FILL_VERTICAL,     to = "FILL_VERTICAL"),
             @ViewDebug.IntToString(from = Gravity.CENTER_HORIZONTAL, to = "CENTER_HORIZONTAL"),
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 30374af..ed9114a 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -916,6 +916,12 @@
     }
 
     @Override
+    public boolean isLayoutRtl(Drawable who) {
+        return (who == mProgressDrawable || who == mIndeterminateDrawable) ?
+            isLayoutRtl() : super.isLayoutRtl(who);
+    }
+
+    @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         updateDrawableBounds(w, h);
     }
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 9069283..acd8539 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -16,32 +16,32 @@
 
 package android.widget;
 
-import com.android.internal.R;
-
 import android.content.Context;
-import android.content.res.TypedArray;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.util.SparseArray;
-import android.util.Poolable;
 import android.util.Pool;
-import android.util.Pools;
+import android.util.Poolable;
 import android.util.PoolableManager;
-import static android.util.Log.d;
+import android.util.Pools;
+import android.util.SparseArray;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.RemoteViews.RemoteView;
+import com.android.internal.R;
 
+import java.util.ArrayList;
 import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.SortedSet;
 import java.util.TreeSet;
-import java.util.LinkedList;
-import java.util.HashSet;
-import java.util.ArrayList;
+
+import static android.util.Log.d;
 
 /**
  * A Layout where the positions of the children can be described in relation to each other or to the
@@ -221,8 +221,8 @@
     @android.view.RemotableViewMethod
     public void setGravity(int gravity) {
         if (mGravity != gravity) {
-            if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) {
-                gravity |= Gravity.LEFT;
+            if ((gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
+                gravity |= Gravity.BEFORE;
             }
 
             if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
@@ -236,9 +236,9 @@
 
     @android.view.RemotableViewMethod
     public void setHorizontalGravity(int horizontalGravity) {
-        final int gravity = horizontalGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
-        if ((mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != gravity) {
-            mGravity = (mGravity & ~Gravity.HORIZONTAL_GRAVITY_MASK) | gravity;
+        final int gravity = horizontalGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
+        if ((mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) != gravity) {
+            mGravity = (mGravity & ~Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) | gravity;
             requestLayout();
         }
     }
@@ -339,7 +339,7 @@
         mHasBaselineAlignedChild = false;
 
         View ignore = null;
-        int gravity = mGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+        int gravity = mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
         final boolean horizontalGravity = gravity != Gravity.LEFT && gravity != 0;
         gravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
         final boolean verticalGravity = gravity != Gravity.TOP && gravity != 0;
@@ -494,7 +494,8 @@
                     height - mPaddingBottom);
 
             final Rect contentBounds = mContentBounds;
-            Gravity.apply(mGravity, right - left, bottom - top, selfBounds, contentBounds);
+            Gravity.apply(mGravity, right - left, bottom - top, selfBounds, contentBounds,
+                    isLayoutRtl());
 
             final int horizontalOffset = contentBounds.left - left;
             final int verticalOffset = contentBounds.top - top;
diff --git a/core/java/android/widget/TableRow.java b/core/java/android/widget/TableRow.java
index b612004..5f20c85 100644
--- a/core/java/android/widget/TableRow.java
+++ b/core/java/android/widget/TableRow.java
@@ -224,7 +224,8 @@
                 final int childWidth = child.getMeasuredWidth();
                 lp.mOffset[LayoutParams.LOCATION_NEXT] = columnWidth - childWidth;
 
-                switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+                final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, isLayoutRtl());
+                switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
                     case Gravity.LEFT:
                         // don't offset on X axis
                         break;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3875765..a73a6cf 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -2093,8 +2093,8 @@
      * @attr ref android.R.styleable#TextView_gravity
      */
     public void setGravity(int gravity) {
-        if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) {
-            gravity |= Gravity.LEFT;
+        if ((gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
+            gravity |= Gravity.BEFORE;
         }
         if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
             gravity |= Gravity.TOP;
@@ -2102,8 +2102,8 @@
 
         boolean newLayout = false;
 
-        if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) !=
-            (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK)) {
+        if ((gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) !=
+            (mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK)) {
             newLayout = true;
         }
 
@@ -4142,6 +4142,17 @@
     }
 
     @Override
+    public boolean isLayoutRtl(Drawable who) {
+        if (who == null) return false;
+        final TextView.Drawables drawables = mDrawables;
+        if (who == drawables.mDrawableLeft || who == drawables.mDrawableRight ||
+            who == drawables.mDrawableTop || who == drawables.mDrawableBottom) {
+            return isLayoutRtl();
+        }
+        return super.isLayoutRtl(who);
+    }
+
+    @Override
     protected boolean onSetAlpha(int alpha) {
         // Alpha is supported if and only if the drawing can be done in one pass.
         // TODO text with spans with a background color currently do not respect this alpha.
@@ -4380,9 +4391,10 @@
             canvas.translate(compoundPaddingLeft, extendedPaddingTop + voffsetText);
         }
 
+        final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, isLayoutRtl());
         if (mEllipsize == TextUtils.TruncateAt.MARQUEE) {
             if (!mSingleLine && getLineCount() == 1 && canMarquee() &&
-                    (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != Gravity.LEFT) {
+                    (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != Gravity.LEFT) {
                 canvas.translate(mLayout.getLineRight(0) - (mRight - mLeft -
                         getCompoundPaddingLeft() - getCompoundPaddingRight()), 0.0f);
             }
@@ -5528,7 +5540,8 @@
         }
 
         Layout.Alignment alignment;
-        switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+        final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, isLayoutRtl());
+        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
             case Gravity.CENTER_HORIZONTAL:
                 alignment = Layout.Alignment.ALIGN_CENTER;
                 break;
@@ -7563,7 +7576,8 @@
                     return 0.0f;
                 }
             } else if (getLineCount() == 1) {
-                switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+                final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, isLayoutRtl());
+                switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
                     case Gravity.LEFT:
                         return 0.0f;
                     case Gravity.RIGHT:
@@ -7586,7 +7600,8 @@
                 final Marquee marquee = mMarquee;
                 return (marquee.mMaxFadeScroll - marquee.mScroll) / getHorizontalFadingEdgeLength();
             } else if (getLineCount() == 1) {
-                switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+                final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, isLayoutRtl());
+                switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
                     case Gravity.LEFT:
                         final int textWidth = (mRight - mLeft) - getCompoundPaddingLeft() -
                                 getCompoundPaddingRight();
@@ -8527,6 +8542,14 @@
                     String[] suggestions = suggestionInfo.suggestionSpan.getSuggestions();
                     suggestions[suggestionInfo.suggestionIndex] = originalText;
 
+                    // Notify source IME of the suggestion pick
+                    if (!TextUtils.isEmpty(
+                            suggestionInfo.suggestionSpan.getNotificationTargetClassName())) {
+                        InputMethodManager imm = InputMethodManager.peekInstance();
+                        imm.notifySuggestionPicked(suggestionInfo.suggestionSpan, originalText,
+                                suggestionInfo.suggestionIndex);
+                    }
+
                     // Restore previous SuggestionSpans
                     final int lengthDifference = suggestion.length() - (spanEnd - spanStart);
                     for (int i = 0; i < length; i++) {
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 183cfbd..6cfeb87 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -176,6 +176,8 @@
             }
             mActionView.setEmbeddedTabView(mTabScrollView);
         }
+        mActionView.setCollapsable(!mHasEmbeddedTabs &&
+                getNavigationMode() == NAVIGATION_MODE_TABS);
 
         TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.ActionBar);
         mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
@@ -307,7 +309,9 @@
             selectTab(null);
         }
         mTabs.clear();
-        mTabScrollView.removeAllTabs();
+        if (mTabScrollView != null) {
+            mTabScrollView.removeAllTabs();
+        }
         mSavedTabPosition = INVALID_POSITION;
     }
 
@@ -887,6 +891,7 @@
                 }
                 break;
         }
+        mActionView.setCollapsable(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
     }
 
     @Override
diff --git a/core/java/com/android/internal/view/menu/IconMenuItemView.java b/core/java/com/android/internal/view/menu/IconMenuItemView.java
index afa8a01..c337a5d 100644
--- a/core/java/com/android/internal/view/menu/IconMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/IconMenuItemView.java
@@ -282,7 +282,7 @@
         getLineBounds(0, tmpRect);
         mPositionIconAvailable.set(0, 0, getWidth(), tmpRect.top);
         Gravity.apply(Gravity.CENTER_VERTICAL | Gravity.LEFT, mIcon.getIntrinsicWidth(), mIcon
-                .getIntrinsicHeight(), mPositionIconAvailable, mPositionIconOutput);
+                .getIntrinsicHeight(), mPositionIconAvailable, mPositionIconOutput, isLayoutRtl());
         mIcon.setBounds(mPositionIconOutput);
     }
 
diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java
index f1618e1..1726390 100644
--- a/core/java/com/android/internal/widget/ActionBarContainer.java
+++ b/core/java/com/android/internal/widget/ActionBarContainer.java
@@ -96,13 +96,26 @@
     @Override
     public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        int nonTabHeight = 0;
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child == mTabContainer) {
+                continue;
+            }
+
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            nonTabHeight = Math.max(nonTabHeight,
+                    child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
+        }
+
         if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
             final int mode = MeasureSpec.getMode(heightMeasureSpec);
             if (mode == MeasureSpec.AT_MOST) {
-                final int measuredHeight = getMeasuredHeight();
                 final int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
                 setMeasuredDimension(getMeasuredWidth(),
-                        Math.min(measuredHeight + mTabContainer.getMeasuredHeight(), maxHeight));
+                        Math.min(nonTabHeight + mTabContainer.getMeasuredHeight(), maxHeight));
             }
         }
     }
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index ff04735..31897ef 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -111,6 +111,7 @@
     private boolean mSplitActionBar;
     private boolean mUserTitle;
     private boolean mIncludeTabs;
+    private boolean mIsCollapsable;
 
     private MenuBuilder mOptionsMenu;
     
@@ -305,8 +306,9 @@
         if (mMenuPresenter == null) {
             mMenuPresenter = new ActionMenuPresenter();
             mMenuPresenter.setCallback(cb);
-            builder.addMenuPresenter(mMenuPresenter);
         }
+        builder.addMenuPresenter(mMenuPresenter);
+
         final ActionMenuView menuView = (ActionMenuView) mMenuPresenter.getMenuView(this);
         final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
                 LayoutParams.MATCH_PARENT);
@@ -629,8 +631,30 @@
         mContextView = view;
     }
 
+    public void setCollapsable(boolean collapsable) {
+        mIsCollapsable = collapsable;
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int childCount = getChildCount();
+        if (mIsCollapsable) {
+            int visibleChildren = 0;
+            for (int i = 0; i < childCount; i++) {
+                final View child = getChildAt(i);
+                if (child.getVisibility() != GONE &&
+                        !(child == mMenuView && mMenuView.getChildCount() == 0)) {
+                    visibleChildren++;
+                }
+            }
+
+            if (visibleChildren == 0) {
+                // No size for an empty action bar when collapsable.
+                setMeasuredDimension(0, 0);
+                return;
+            }
+        }
+
         int widthMode = MeasureSpec.getMode(widthMeasureSpec);
         if (widthMode != MeasureSpec.EXACTLY) {
             throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
@@ -761,8 +785,7 @@
 
         if (mContentHeight <= 0) {
             int measuredHeight = 0;
-            final int count = getChildCount();
-            for (int i = 0; i < count; i++) {
+            for (int i = 0; i < childCount; i++) {
                 View v = getChildAt(i);
                 int paddedViewHeight = v.getMeasuredHeight() + verticalPadding;
                 if (paddedViewHeight > measuredHeight) {
@@ -791,6 +814,11 @@
         final int y = getPaddingTop();
         final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
 
+        if (contentHeight <= 0) {
+            // Nothing to do if we can't see anything.
+            return;
+        }
+
         if (mHomeLayout.getVisibility() != GONE) {
             x += positionChild(mHomeLayout, x, y, contentHeight);
         }
diff --git a/core/java/com/android/internal/widget/TextProgressBar.java b/core/java/com/android/internal/widget/TextProgressBar.java
index aee7b76..e113dd8 100644
--- a/core/java/com/android/internal/widget/TextProgressBar.java
+++ b/core/java/com/android/internal/widget/TextProgressBar.java
@@ -86,7 +86,8 @@
             
             // Check if Chronometer should move with with ProgressBar 
             mChronometerFollow = (params.width == ViewGroup.LayoutParams.WRAP_CONTENT);
-            mChronometerGravity = (mChronometer.getGravity() & Gravity.HORIZONTAL_GRAVITY_MASK);
+            mChronometerGravity = (mChronometer.getGravity() &
+                    Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK);
             
         } else if (childId == PROGRESSBAR_ID && child instanceof ProgressBar) {
             mProgressBar = (ProgressBar) child;
diff --git a/core/jni/android_nfc_NdefMessage.cpp b/core/jni/android_nfc_NdefMessage.cpp
index 9beef2a..d9b64aa 100644
--- a/core/jni/android_nfc_NdefMessage.cpp
+++ b/core/jni/android_nfc_NdefMessage.cpp
@@ -86,7 +86,7 @@
     if (records_array == NULL)
         goto end;
 
-    ctor = e->GetMethodID(record_cls, "<init>", "(S[B[B[B)V");
+    ctor = e->GetMethodID(record_cls, "<init>", "(S[B[B[BB)V");
 
     for (i = 0; i < num_of_records; i++) {
         jbyteArray type, id, payload;
@@ -128,7 +128,7 @@
                 (jbyte *)record.PayloadData);
 
         new_record = e->NewObject(record_cls, ctor,
-                (jshort)record.Tnf, type, id, payload);
+                (jshort)record.Tnf, type, id, payload, (jbyte)record.Flags);
 
         e->SetObjectArrayElement(records_array, i, new_record);
 
diff --git a/core/jni/android_nfc_NdefRecord.cpp b/core/jni/android_nfc_NdefRecord.cpp
index a7a80c8..e8cc4c6 100644
--- a/core/jni/android_nfc_NdefRecord.cpp
+++ b/core/jni/android_nfc_NdefRecord.cpp
@@ -91,7 +91,7 @@
     jint ret = -1;
     phFriNfc_NdefRecord_t record;
 
-    jfieldID mType, mId, mPayload, mTnf;
+    jfieldID mType, mId, mPayload, mTnf, mFlags;
     jbyteArray type = NULL;
     jbyteArray id = NULL;
     jbyteArray payload = NULL;
@@ -142,10 +142,15 @@
     if (payload == NULL) {
         goto clean_and_return;
     }
+
     e->SetByteArrayRegion(payload, 0, record.PayloadLength,
             (jbyte *)record.PayloadData);
     e->SetObjectField(o, mPayload, payload);
 
+    /* Set flags field */
+    mFlags = e->GetFieldID(record_cls, "mFlags", "B");
+    e->SetIntField(o, mFlags, record.Flags);
+
     ret = 0;
 
 clean_and_return:
diff --git a/core/res/res/layout/preference_list_content_large.xml b/core/res/res/layout-sw600dp/preference_list_content.xml
similarity index 78%
rename from core/res/res/layout/preference_list_content_large.xml
rename to core/res/res/layout-sw600dp/preference_list_content.xml
index 14d188e..5a345c6 100644
--- a/core/res/res/layout/preference_list_content_large.xml
+++ b/core/res/res/layout-sw600dp/preference_list_content.xml
@@ -2,7 +2,7 @@
 <!--
 /* //device/apps/common/assets/res/layout/list_content.xml
 **
-** Copyright 2011, The Android Open Source Project
+** Copyright 2006, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
@@ -27,6 +27,8 @@
         android:orientation="horizontal"
         android:layout_width="match_parent"
         android:layout_height="0px"
+        android:layout_marginTop="@dimen/preference_screen_top_margin"
+        android:layout_marginBottom="@dimen/preference_screen_bottom_margin"
         android:layout_weight="1">
 
         <LinearLayout
@@ -36,14 +38,15 @@
             android:layout_height="match_parent"
             android:layout_marginRight="@dimen/preference_screen_side_margin_negative"
             android:layout_marginLeft="@dimen/preference_screen_side_margin"
-            android:layout_marginTop="32dp"
-            android:layout_marginBottom="32dp"
-            android:layout_weight="10">
+            android:layout_weight="@integer/preferences_left_pane_weight">
 
             <ListView android:id="@android:id/list"
                 android:layout_width="match_parent"
                 android:layout_height="0px"
                 android:layout_weight="1"
+                android:paddingTop="16dp"
+                android:paddingBottom="16dp"
+
                 android:drawSelectorOnTop="false"
                 android:cacheColorHint="@android:color/transparent"
                 android:listPreferredItemHeight="48dp"
@@ -60,39 +63,22 @@
                 android:id="@+id/prefs_frame"
                 android:layout_width="0px"
                 android:layout_height="match_parent"
-                android:layout_weight="20"
+                android:layout_weight="@integer/preferences_right_pane_weight"
                 android:layout_marginLeft="@dimen/preference_screen_side_margin"
                 android:layout_marginRight="@dimen/preference_screen_side_margin"
-                android:layout_marginTop="16dp"
-                android:layout_marginBottom="16dp"
                 android:background="?attr/detailsElementBackground"
                 android:orientation="vertical"
                 android:visibility="gone" >
 
-            <!-- Breadcrumb inserted here -->
-            <android.app.FragmentBreadCrumbs
-                android:id="@android:id/title"
-                android:layout_height="72dip"
-                android:layout_width="match_parent"
-                android:paddingTop="16dip"
-                android:paddingBottom="8dip"
-                android:gravity="center_vertical|left"
-                android:layout_marginLeft="48dip"
-                android:layout_marginRight="48dip"
-                />
+            <!-- Breadcrumb inserted here, in certain screen sizes. In others, it will be an
+                empty layout or just padding, and PreferenceActivity will put the breadcrumbs in
+                the action bar. -->
+            <include layout="@layout/breadcrumbs_in_fragment" />
 
-            <ImageView
-                    android:layout_width="match_parent"
-                    android:layout_height="1dip"
-                    android:paddingLeft="32dip"
-                    android:paddingRight="32dip"
-                    android:src="#404040"
-                />
             <android.preference.PreferenceFrameLayout android:id="@+id/prefs"
                     android:layout_width="match_parent"
                     android:layout_height="0dip"
                     android:layout_weight="1"
-                    android:layout_marginTop="-1dip"
                 />
         </LinearLayout>
     </LinearLayout>
diff --git a/core/res/res/layout/preference_list_content_single_large.xml b/core/res/res/layout-w600dp/preference_list_content_single.xml
similarity index 100%
rename from core/res/res/layout/preference_list_content_single_large.xml
rename to core/res/res/layout-w600dp/preference_list_content_single.xml
diff --git a/core/res/res/layout-xlarge/breadcrumbs_in_fragment.xml b/core/res/res/layout-xlarge/breadcrumbs_in_fragment.xml
new file mode 100644
index 0000000..384c4fe
--- /dev/null
+++ b/core/res/res/layout-xlarge/breadcrumbs_in_fragment.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:layout_marginLeft="@dimen/preference_fragment_padding_side"
+        android:layout_marginRight="@dimen/preference_fragment_padding_side"
+    >
+    <android.app.FragmentBreadCrumbs
+            android:id="@android:id/title"
+            android:layout_height="72dip"
+            android:layout_width="match_parent"
+            android:paddingTop="16dip"
+            android:paddingBottom="8dip"
+            android:gravity="center_vertical|left"
+        />
+
+    <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="1dip"
+            android:src="#404040"
+        />
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/breadcrumbs_in_fragment.xml b/core/res/res/layout/breadcrumbs_in_fragment.xml
new file mode 100644
index 0000000..98fffb7
--- /dev/null
+++ b/core/res/res/layout/breadcrumbs_in_fragment.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<!-- This layout disables breadcrumbs in the fragment area and causes PreferenceActivity to
+    put the breadcrumbs in the action bar. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_height="@dimen/preference_fragment_padding_side"
+        android:layout_width="match_parent">
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/locale_picker_item.xml b/core/res/res/layout/locale_picker_item.xml
index b63f5ab..19c0dee 100644
--- a/core/res/res/layout/locale_picker_item.xml
+++ b/core/res/res/layout/locale_picker_item.xml
@@ -20,11 +20,14 @@
     android:layout_width="match_parent"
     android:gravity="center_vertical"
     android:minHeight="?android:attr/listPreferredItemHeight"
-    android:padding="5dip">
+    android:paddingLeft="16dp"
+    android:paddingTop="8dp"
+    android:paddingBottom="8dp"
+    android:paddingRight="16dp">
 
     <TextView android:id="@+id/locale"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:textAppearance="?android:attr/textAppearanceMedium"
     />
 </LinearLayout >
diff --git a/core/res/res/layout/preference_category_holo.xml b/core/res/res/layout/preference_category_holo.xml
index 5fe8b28..a4e20d2 100644
--- a/core/res/res/layout/preference_category_holo.xml
+++ b/core/res/res/layout/preference_category_holo.xml
@@ -18,5 +18,5 @@
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
     style="?android:attr/listSeparatorTextViewStyle"
     android:id="@+android:id/title"
-    android:paddingLeft="32dp"
+    android:paddingLeft="16dp"
 />
diff --git a/core/res/res/layout/preference_child_holo.xml b/core/res/res/layout/preference_child_holo.xml
index 2e70d77..06c846b 100644
--- a/core/res/res/layout/preference_child_holo.xml
+++ b/core/res/res/layout/preference_child_holo.xml
@@ -26,7 +26,7 @@
     <LinearLayout
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:minWidth="@dimen/preference_widget_width"
+        android:minWidth="@dimen/preference_icon_minWidth"
         android:gravity="center"
         android:orientation="horizontal">
         <ImageView
@@ -40,6 +40,7 @@
     <RelativeLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginLeft="32dip"
         android:layout_marginRight="6dip"
         android:layout_marginTop="6dip"
         android:layout_marginBottom="6dip"
diff --git a/core/res/res/layout/preference_holo.xml b/core/res/res/layout/preference_holo.xml
index c448f64..e5ed33c 100644
--- a/core/res/res/layout/preference_holo.xml
+++ b/core/res/res/layout/preference_holo.xml
@@ -27,21 +27,23 @@
     <LinearLayout
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:minWidth="@dimen/preference_widget_width"
         android:gravity="center"
+        android:minWidth="@dimen/preference_icon_minWidth"
         android:orientation="horizontal">
         <ImageView
             android:id="@+android:id/icon"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center"
+            android:minWidth="48dp"
             />
     </LinearLayout>
 
     <RelativeLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginRight="6dip"
+        android:layout_marginLeft="16dip"
+        android:layout_marginRight="8dip"
         android:layout_marginTop="6dip"
         android:layout_marginBottom="6dip"
         android:layout_weight="1">
diff --git a/core/res/res/layout/preference_information_holo.xml b/core/res/res/layout/preference_information_holo.xml
index d6cc063..d15cd7b 100644
--- a/core/res/res/layout/preference_information_holo.xml
+++ b/core/res/res/layout/preference_information_holo.xml
@@ -24,13 +24,24 @@
     android:gravity="center_vertical"
     android:paddingRight="?android:attr/scrollbarSize">
 
-    <View
-        android:layout_width="@dimen/preference_widget_width"
-        android:layout_height="match_parent" />
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:minWidth="@dimen/preference_icon_minWidth"
+        android:gravity="center"
+        android:orientation="horizontal">
+        <ImageView
+            android:id="@+android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            />
+    </LinearLayout>
 
     <RelativeLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginLeft="16dip"
         android:layout_marginRight="6sp"
         android:layout_marginTop="6sp"
         android:layout_marginBottom="6sp"
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index 925b715..82b3a4c 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -27,6 +27,8 @@
         android:orientation="horizontal"
         android:layout_width="match_parent"
         android:layout_height="0px"
+        android:layout_marginTop="@dimen/preference_screen_top_margin"
+        android:layout_marginBottom="@dimen/preference_screen_bottom_margin"
         android:layout_weight="1">
 
         <LinearLayout
@@ -36,12 +38,14 @@
             android:layout_height="match_parent"
             android:layout_marginRight="@dimen/preference_screen_side_margin_negative"
             android:layout_marginLeft="@dimen/preference_screen_side_margin"
-            android:layout_weight="10">
+            android:layout_weight="@integer/preferences_left_pane_weight">
 
             <ListView android:id="@android:id/list"
                 android:layout_width="match_parent"
                 android:layout_height="0px"
                 android:layout_weight="1"
+                android:paddingTop="16dp"
+                android:paddingBottom="16dp"
                 android:drawSelectorOnTop="false"
                 android:cacheColorHint="@android:color/transparent"
                 android:listPreferredItemHeight="48dp"
@@ -58,15 +62,21 @@
                 android:id="@+id/prefs_frame"
                 android:layout_width="0px"
                 android:layout_height="match_parent"
-                android:layout_weight="20"
+                android:layout_weight="@integer/preferences_right_pane_weight"
+                android:layout_marginLeft="@dimen/preference_screen_side_margin"
+                android:layout_marginRight="@dimen/preference_screen_side_margin"
                 android:orientation="vertical"
                 android:visibility="gone" >
 
+            <!-- Breadcrumb inserted here, in certain screen sizes. In others, it will be an
+                empty layout or just padding, and PreferenceActivity will put the breadcrumbs in
+                the action bar. -->
+            <include layout="@layout/breadcrumbs_in_fragment" />
+
             <android.preference.PreferenceFrameLayout android:id="@+id/prefs"
                     android:layout_width="match_parent"
                     android:layout_height="0dip"
                     android:layout_weight="1"
-                    android:layout_marginTop="-1dip"
                 />
         </LinearLayout>
     </LinearLayout>
diff --git a/core/res/res/layout/preference_list_fragment.xml b/core/res/res/layout/preference_list_fragment.xml
index 4044371..986536e 100644
--- a/core/res/res/layout/preference_list_fragment.xml
+++ b/core/res/res/layout/preference_list_fragment.xml
@@ -28,6 +28,10 @@
         android:layout_width="match_parent"
         android:layout_height="0px"
         android:layout_weight="1"
+        android:paddingTop="0dip"
+        android:paddingBottom="@dimen/preference_fragment_padding_bottom"
+        android:paddingLeft="@dimen/preference_fragment_padding_side"
+        android:paddingRight="@dimen/preference_fragment_padding_side"
         android:clipToPadding="false"
         android:drawSelectorOnTop="false"
         android:cacheColorHint="@android:color/transparent"
diff --git a/core/res/res/layout/preference_list_fragment_large.xml b/core/res/res/layout/preference_list_fragment_large.xml
deleted file mode 100644
index cde84ff..0000000
--- a/core/res/res/layout/preference_list_fragment_large.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:background="@android:color/transparent"
-    android:layout_removeBorders="true">
-
-    <ListView android:id="@android:id/list"
-        android:layout_width="match_parent"
-        android:layout_height="0px"
-        android:layout_weight="1"
-        android:paddingTop="0dip"
-        android:paddingBottom="48dip"
-        android:paddingLeft="32dip"
-        android:paddingRight="32dip"
-        android:clipToPadding="false"
-        android:drawSelectorOnTop="false"
-        android:cacheColorHint="@android:color/transparent"
-        android:scrollbarAlwaysDrawVerticalTrack="true" />
-
-    <RelativeLayout android:id="@+id/button_bar"
-        android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:layout_weight="0"
-        android:background="@android:drawable/bottom_bar"
-        android:visibility="gone">
-
-        <Button android:id="@+id/back_button"
-            android:layout_width="150dip"
-            android:layout_height="wrap_content"
-            android:layout_margin="5dip"
-            android:layout_alignParentLeft="true"
-            android:drawableLeft="@drawable/ic_btn_back"
-            android:drawablePadding="3dip"
-            android:text="@string/back_button_label"
-        />
-        <LinearLayout
-            android:orientation="horizontal"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentRight="true">
-
-            <Button android:id="@+id/skip_button"
-                android:layout_width="150dip"
-                android:layout_height="wrap_content"
-                android:layout_margin="5dip"
-                android:text="@string/skip_button_label"
-                android:visibility="gone"
-            />
-
-            <Button android:id="@+id/next_button"
-                android:layout_width="150dip"
-                android:layout_height="wrap_content"
-                android:layout_margin="5dip"
-                android:drawableRight="@drawable/ic_btn_next"
-                android:drawablePadding="3dip"
-                android:text="@string/next_button_label"
-            />
-        </LinearLayout>
-    </RelativeLayout>
-</LinearLayout>
diff --git a/core/res/res/layout/search_view.xml b/core/res/res/layout/search_view.xml
index face8b2..99fdf5b 100644
--- a/core/res/res/layout/search_view.xml
+++ b/core/res/res/layout/search_view.xml
@@ -33,8 +33,8 @@
         android:layout_gravity="center_vertical"
         android:layout_marginBottom="2dip"
         android:drawablePadding="0dip"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="?android:attr/textColorPrimaryInverse"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textColor="?android:attr/textColorPrimary"
         android:visibility="gone"
     />
 
diff --git a/core/res/res/values-h720dp/dimens.xml b/core/res/res/values-h720dp/dimens.xml
index 7f43946..c09cb5b 100644
--- a/core/res/res/values-h720dp/dimens.xml
+++ b/core/res/res/values-h720dp/dimens.xml
@@ -21,4 +21,10 @@
     <dimen name="alert_dialog_title_height">54dip</dimen>
     <!-- Dialog button bar height -->
     <dimen name="alert_dialog_button_bar_height">54dip</dimen>
+    <!-- Preference fragment padding, bottom -->
+    <dimen name="preference_fragment_padding_bottom">16dp</dimen>
+    <!-- Preference activity top margin -->
+    <dimen name="preference_screen_top_margin">16dp</dimen>
+    <!-- Preference activity bottom margin -->
+    <dimen name="preference_screen_bottom_margin">16dp</dimen>
 </resources>
diff --git a/core/res/res/values-land/dimens.xml b/core/res/res/values-land/dimens.xml
index 8def578..dbaad13 100644
--- a/core/res/res/values-land/dimens.xml
+++ b/core/res/res/values-land/dimens.xml
@@ -25,8 +25,8 @@
     <dimen name="password_keyboard_key_height_numeric">60dip</dimen>
     <!-- Default correction for the space key in the password keyboard -->
     <dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
-    <dimen name="preference_screen_side_margin">96dp</dimen>
-    <dimen name="preference_screen_side_margin_negative">-100dp</dimen>
+    <dimen name="preference_screen_side_margin">16dp</dimen>
+    <dimen name="preference_screen_side_margin_negative">-20dp</dimen>
     <dimen name="preference_widget_width">72dp</dimen>
 
     <!-- Default height of an action bar. -->
diff --git a/core/res/res/values-large/styles.xml b/core/res/res/values-large/styles.xml
index 96a8c84..5206d7c 100644
--- a/core/res/res/values-large/styles.xml
+++ b/core/res/res/values-large/styles.xml
@@ -15,10 +15,11 @@
 -->
 
 <resources>
-    <style name="Widget.Holo.PreferenceFrameLayout">
-        <item name="android:borderTop">0dip</item>
-        <item name="android:borderBottom">48dip</item>
-        <item name="android:borderLeft">32dip</item>
-        <item name="android:borderRight">32dip</item>
+    <style name="PreferencePanel">
+        <item name="android:layout_marginLeft">@dimen/preference_screen_side_margin</item>
+        <item name="android:layout_marginRight">@dimen/preference_screen_side_margin</item>
+        <item name="android:layout_marginTop">48dip</item>
+        <item name="android:layout_marginBottom">48dip</item>
+        <item name="android:background">?attr/detailsElementBackground</item>
     </style>
 </resources>
diff --git a/core/res/res/values-sw600dp/bools.xml b/core/res/res/values-sw600dp/bools.xml
new file mode 100644
index 0000000..734031f
--- /dev/null
+++ b/core/res/res/values-sw600dp/bools.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <bool name="preferences_prefer_dual_pane">true</bool>
+</resources>
diff --git a/core/res/res/values-w1280dp/dimens.xml b/core/res/res/values-w1280dp/dimens.xml
new file mode 100644
index 0000000..e67b3a9
--- /dev/null
+++ b/core/res/res/values-w1280dp/dimens.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <dimen name="preference_screen_side_margin">96dp</dimen>
+    <dimen name="preference_screen_side_margin_negative">-100dp</dimen>
+    <dimen name="preference_widget_width">64dp</dimen>
+    <!-- Preference fragment padding, bottom -->
+    <dimen name="preference_fragment_padding_bottom">48dp</dimen>
+    <!-- Preference fragment padding, sides -->
+    <dimen name="preference_fragment_padding_side">48dp</dimen>
+    <!-- Padding to the left of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingLeft">48dp</dimen>
+    <!-- Padding to the right of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingRight">48dp</dimen>
+</resources>
+
diff --git a/core/res/res/values-w720dp/dimens.xml b/core/res/res/values-w720dp/dimens.xml
new file mode 100644
index 0000000..ec1195e
--- /dev/null
+++ b/core/res/res/values-w720dp/dimens.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <!-- Preference fragment padding, sides -->
+    <dimen name="preference_fragment_padding_side">32dp</dimen>
+    <!-- Padding to the left of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingLeft">32dp</dimen>
+    <!-- Padding to the right of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingRight">32dp</dimen>
+    <!-- Weight of the left pane in a multi-pane preference layout. -->
+    <integer name="preferences_left_pane_weight">1</integer>
+    <!-- Weight of the right pane in a multi-pane preference layout. So the split is 1:2 -->
+    <integer name="preferences_right_pane_weight">2</integer>
+    <!-- Minimum space to allocate to the left of a preference item for an icon.
+        This helps in aligning titles when some items have icons and some don't. When space is
+        at a premium, we don't pre-allocate any space. -->
+    <dimen name="preference_icon_minWidth">48dp</dimen>
+</resources>
diff --git a/core/res/res/values-xlarge/styles.xml b/core/res/res/values-xlarge/styles.xml
index a39d9d6..7515c98 100644
--- a/core/res/res/values-xlarge/styles.xml
+++ b/core/res/res/values-xlarge/styles.xml
@@ -51,13 +51,5 @@
         <item name="android:gravity">left|center_vertical</item>
         <item name="android:tabLayout">@android:layout/tab_indicator_holo_large</item>
     </style>
-    
-    <style name="PreferencePanel">
-        <item name="android:layout_marginLeft">@dimen/preference_screen_side_margin</item>
-        <item name="android:layout_marginRight">@dimen/preference_screen_side_margin</item>
-        <item name="android:layout_marginTop">48dip</item>
-        <item name="android:layout_marginBottom">48dip</item>
-        <item name="android:background">?attr/detailsElementBackground</item>
-    </style>
 </resources>
 
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f854e93..b82a2d2 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1128,6 +1128,10 @@
              The clip will be based on the horizontal gravity: a left gravity will clip the right
              edge, a right gravity will clip the left edge, and neither will clip both edges. -->
         <flag name="clip_horizontal" value="0x08" />
+        <!-- Push object to the beginning of its container, not changing its size. -->
+        <flag name="before" value="0x00800003" />
+        <!-- Push object to the end of its container, not changing its size. -->
+        <flag name="after" value="0x00800005" />
     </attr>
 
     <!-- Controls whether links such as urls and email addresses are
@@ -1184,6 +1188,10 @@
              The clip will be based on the horizontal gravity: a left gravity will clip the right
              edge, a right gravity will clip the left edge, and neither will clip both edges. -->
         <flag name="clip_horizontal" value="0x08" />
+        <!-- Push object to the beginning of its container, not changing its size. -->
+        <flag name="before" value="0x00800003" />
+        <!-- Push object to the end of its container, not changing its size. -->
+        <flag name="after" value="0x00800005" />
     </attr>
 
     <!-- Standard orientation constant. -->
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index 8e27be4..9d6309d 100644
--- a/core/res/res/values/bools.xml
+++ b/core/res/res/values/bools.xml
@@ -1,23 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
+
 <resources>
     <bool name="allow_action_menu_item_text_with_icon">false</bool>
     <bool name="action_bar_embed_tabs">false</bool>
     <bool name="split_action_bar_is_narrow">true</bool>
+    <bool name="preferences_prefer_dual_pane">false</bool>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 3f4010b..f5de1d2 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -57,9 +57,28 @@
     <dimen name="preference_screen_side_margin">0dp</dimen>
     <!-- Preference activity side margins negative-->
     <dimen name="preference_screen_side_margin_negative">0dp</dimen>
+    <!-- Preference activity top margin -->
+    <dimen name="preference_screen_top_margin">0dp</dimen>
+    <!-- Preference activity bottom margin -->
+    <dimen name="preference_screen_bottom_margin">0dp</dimen>
     <!-- Preference widget area width (to the left of the text) -->
-    <dimen name="preference_widget_width">8dp</dimen>
-
+    <dimen name="preference_widget_width">48dp</dimen>
+    <!-- Preference fragment padding, bottom -->
+    <dimen name="preference_fragment_padding_bottom">0dp</dimen>
+    <!-- Preference fragment padding, sides -->
+    <dimen name="preference_fragment_padding_side">0dp</dimen>
+    <!-- Weight of the left pane in a multi-pane preference layout. -->
+    <integer name="preferences_left_pane_weight">4</integer>
+    <!-- Weight of the right pane in a multi-pane preference layout. So the split is 40:60 -->
+    <integer name="preferences_right_pane_weight">6</integer>
+    <!-- Padding to the left of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingLeft">0dp</dimen>
+    <!-- Padding to the right of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingRight">0dp</dimen>
+    <!-- Minimum space to allocate to the left of a preference item for an icon.
+        This helps in aligning titles when some items have icons and some don't. When space is
+        at a premium, we don't pre-allocate any space. -->
+    <dimen name="preference_icon_minWidth">0dp</dimen>
     <!-- The platform's desired minimum size for a dialog's width when it
          is along the major axis (that is the screen is landscape).  This may
          be either a fraction or a dimension. -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index e95094f0..0635528 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1466,7 +1466,7 @@
         <item name="divider">?android:attr/dividerVertical</item>
         <item name="showDividers">middle</item>
         <item name="dividerPadding">8dip</item>
-        <item name="background">@android:drawable/btn_group_holo_dark</item>
+        <item name="background">@null</item>
     </style>
 
     <style name="Holo.SegmentedButton" parent="SegmentedButton">
@@ -1875,7 +1875,6 @@
     </style>
 
     <style name="Holo.Light.ButtonBar" parent="Holo.ButtonBar">
-        <item name="android:background">@android:drawable/btn_group_holo_light</item>
     </style>
 
     <style name="Holo.Light.ButtonBar.AlertDialog">
@@ -2219,9 +2218,9 @@
 
     <style name="Widget.Holo.PreferenceFrameLayout">
         <item name="android:borderTop">0dip</item>
-        <item name="android:borderBottom">0dip</item>
-        <item name="android:borderLeft">0dip</item>
-        <item name="android:borderRight">0dip</item>
+        <item name="android:borderBottom">@dimen/preference_fragment_padding_side</item>
+        <item name="android:borderLeft">@dimen/preference_fragment_padding_side</item>
+        <item name="android:borderRight">@dimen/preference_fragment_padding_side</item>
     </style>
 
     <!-- Pointer styles -->
diff --git a/core/tests/coretests/src/android/net/http/AbstractProxyTest.java b/core/tests/coretests/src/android/net/http/AbstractProxyTest.java
index 2fb833c..ee89414 100644
--- a/core/tests/coretests/src/android/net/http/AbstractProxyTest.java
+++ b/core/tests/coretests/src/android/net/http/AbstractProxyTest.java
@@ -36,6 +36,7 @@
 import tests.http.MockResponse;
 import tests.http.MockWebServer;
 import tests.http.RecordedRequest;
+import tests.http.SocketPolicy;
 
 public abstract class AbstractProxyTest extends TestCase {
 
@@ -148,10 +149,9 @@
         TestSSLContext testSSLContext = TestSSLContext.create();
 
         server.useHttps(testSSLContext.serverContext.getSocketFactory(), true);
-        MockResponse connectResponse = new MockResponse()
-                .setResponseCode(200);
-        connectResponse.getHeaders().clear();
-        server.enqueue(connectResponse);
+        server.enqueue(new MockResponse()
+                .setSocketPolicy(SocketPolicy.UPGRADE_TO_SSL_AT_END)
+                .clearHeaders());
         server.enqueue(new MockResponse()
                 .setResponseCode(200)
                 .setBody("this response comes via a secure proxy"));
diff --git a/core/tests/coretests/src/android/net/http/HttpResponseCacheTest.java b/core/tests/coretests/src/android/net/http/HttpResponseCacheTest.java
new file mode 100644
index 0000000..4d65588
--- /dev/null
+++ b/core/tests/coretests/src/android/net/http/HttpResponseCacheTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.http;
+
+import java.io.File;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
+import java.net.ResponseCache;
+import java.net.URI;
+import java.net.URLConnection;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import junit.framework.TestCase;
+
+public final class HttpResponseCacheTest extends TestCase {
+
+    private File cacheDir;
+
+    @Override public void setUp() throws Exception {
+        super.setUp();
+        String tmp = System.getProperty("java.io.tmpdir");
+        cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID());
+    }
+
+    @Override protected void tearDown() throws Exception {
+        ResponseCache.setDefault(null);
+        super.tearDown();
+    }
+
+    public void testInstall() throws Exception {
+        HttpResponseCache installed = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        assertNotNull(installed);
+        assertSame(installed, ResponseCache.getDefault());
+        assertSame(installed, HttpResponseCache.getDefault());
+    }
+
+    public void testSecondEquivalentInstallDoesNothing() throws Exception {
+        HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        HttpResponseCache another = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        assertSame(first, another);
+    }
+
+    public void testInstallClosesPreviouslyInstalled() throws Exception {
+        HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        HttpResponseCache another = HttpResponseCache.install(cacheDir, 8 * 1024 * 1024);
+        assertNotSame(first, another);
+        try {
+            first.flush();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testGetInstalledWithWrongTypeInstalled() {
+        ResponseCache.setDefault(new ResponseCache() {
+            @Override public CacheResponse get(URI uri, String requestMethod,
+                    Map<String, List<String>> requestHeaders) {
+                return null;
+            }
+            @Override public CacheRequest put(URI uri, URLConnection connection) {
+                return null;
+            }
+        });
+        assertNull(HttpResponseCache.getInstalled());
+    }
+
+    public void testCloseCloses() throws Exception {
+        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        cache.close();
+        try {
+            cache.flush();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testCloseUninstalls() throws Exception {
+        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        cache.close();
+        assertNull(ResponseCache.getDefault());
+    }
+
+    public void testDeleteUninstalls() throws Exception {
+        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        cache.delete();
+        assertNull(ResponseCache.getDefault());
+    }
+}
diff --git a/core/tests/coretests/src/android/view/GravityTest.java b/core/tests/coretests/src/android/view/GravityTest.java
new file mode 100644
index 0000000..010127f
--- /dev/null
+++ b/core/tests/coretests/src/android/view/GravityTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+public class GravityTest extends AndroidTestCase {
+
+    @SmallTest
+    public void testGetAbsoluteGravity() throws Exception {
+        assertOneGravity(Gravity.LEFT, Gravity.LEFT, false);
+        assertOneGravity(Gravity.LEFT, Gravity.LEFT, true);
+
+        assertOneGravity(Gravity.RIGHT, Gravity.RIGHT, false);
+        assertOneGravity(Gravity.RIGHT, Gravity.RIGHT, true);
+
+        assertOneGravity(Gravity.TOP|Gravity.LEFT, Gravity.TOP, false);
+        assertOneGravity(Gravity.TOP|Gravity.LEFT, Gravity.TOP, true);
+
+        assertOneGravity(Gravity.BOTTOM|Gravity.LEFT, Gravity.BOTTOM, false);
+        assertOneGravity(Gravity.BOTTOM|Gravity.LEFT, Gravity.BOTTOM, true);
+
+        assertOneGravity(Gravity.CENTER_VERTICAL|Gravity.LEFT, Gravity.CENTER_VERTICAL, false);
+        assertOneGravity(Gravity.CENTER_VERTICAL|Gravity.LEFT, Gravity.CENTER_VERTICAL, true);
+
+        assertOneGravity(Gravity.CENTER_HORIZONTAL, Gravity.CENTER_HORIZONTAL, false);
+        assertOneGravity(Gravity.CENTER_HORIZONTAL, Gravity.CENTER_HORIZONTAL, true);
+
+        assertOneGravity(Gravity.CENTER, Gravity.CENTER, false);
+        assertOneGravity(Gravity.CENTER, Gravity.CENTER, true);
+
+        assertOneGravity(Gravity.FILL_VERTICAL|Gravity.LEFT, Gravity.FILL_VERTICAL, false);
+        assertOneGravity(Gravity.FILL_VERTICAL|Gravity.LEFT, Gravity.FILL_VERTICAL, true);
+
+        assertOneGravity(Gravity.FILL_HORIZONTAL, Gravity.FILL_HORIZONTAL, false);
+        assertOneGravity(Gravity.FILL_HORIZONTAL, Gravity.FILL_HORIZONTAL, true);
+
+        assertOneGravity(Gravity.FILL, Gravity.FILL, false);
+        assertOneGravity(Gravity.FILL, Gravity.FILL, true);
+
+        assertOneGravity(Gravity.CLIP_HORIZONTAL|Gravity.LEFT, Gravity.CLIP_HORIZONTAL, false);
+        assertOneGravity(Gravity.CLIP_HORIZONTAL|Gravity.LEFT, Gravity.CLIP_HORIZONTAL, true);
+
+        assertOneGravity(Gravity.CLIP_VERTICAL|Gravity.LEFT, Gravity.CLIP_VERTICAL, false);
+        assertOneGravity(Gravity.CLIP_VERTICAL|Gravity.LEFT, Gravity.CLIP_VERTICAL, true);
+
+        assertOneGravity(Gravity.LEFT, Gravity.BEFORE, false);
+        assertOneGravity(Gravity.RIGHT, Gravity.BEFORE, true);
+
+        assertOneGravity(Gravity.RIGHT, Gravity.AFTER, false);
+        assertOneGravity(Gravity.LEFT, Gravity.AFTER, true);
+    }
+
+    private void assertOneGravity(int expected, int initial, boolean isRtl) {
+        assertEquals(expected, Gravity.getAbsoluteGravity(initial, isRtl));
+    }
+}
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index c9c9fd7..311f024 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -387,7 +387,7 @@
             if (shader == null) {
                 if (mApplyGravity) {
                     Gravity.apply(state.mGravity, mBitmapWidth, mBitmapHeight,
-                            getBounds(), mDstRect);
+                            getBounds(), mDstRect, isLayoutRtlSelf());
                     mApplyGravity = false;
                 }
                 canvas.drawBitmap(bitmap, null, mDstRect, state.mPaint);
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index b333e01..83020aa 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -209,7 +209,7 @@
         if ((mClipState.mOrientation & VERTICAL) != 0) {
             h -= (h - ih) * (10000 - level) / 10000;
         }
-        Gravity.apply(mClipState.mGravity, w, h, bounds, r);
+        Gravity.apply(mClipState.mGravity, w, h, bounds, r, isLayoutRtlSelf());
 
         if (w > 0 && h > 0) {
             canvas.save();
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 159f371e..8994efc 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -288,6 +288,18 @@
     }
 
     /**
+     * Implement this interface if you want to create an drawable that is RTL aware
+     */
+    public static interface Callback2 extends Callback {
+        /**
+         * A Drawable can call this to know whether the <var>who</var> is in RTL layout direction.
+         *
+         * @param who The drawable being unscheduled.
+         */
+        public boolean isLayoutRtl(Drawable who);
+    }
+
+    /**
      * Bind a {@link Callback} object to this Drawable.  Required for clients
      * that want to support animated drawables.
      *
@@ -364,6 +376,18 @@
     }
 
     /**
+     * Use the current {@link android.graphics.drawable.Drawable.Callback2} implementation to know
+     * if this Drawable is having a layout in RTL direction.
+     */
+    public boolean isLayoutRtlSelf() {
+        final Callback callback = getCallback();
+        if (callback == null || !(callback instanceof Callback2)) {
+            return false;
+        }
+        return ((Callback2) callback).isLayoutRtl(this);
+    }
+
+    /**
      * Specify an alpha value for the drawable. 0 means fully transparent, and
      * 255 means fully opaque.
      */
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index a7ed0d0..cbe1f2d 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -221,7 +221,7 @@
             final int ih = min ? mScaleState.mDrawable.getIntrinsicHeight() : 0;
             h -= (int) ((h - ih) * (10000 - level) * mScaleState.mScaleHeight / 10000);
         }
-        Gravity.apply(mScaleState.mGravity, w, h, bounds, r);
+        Gravity.apply(mScaleState.mGravity, w, h, bounds, r, isLayoutRtlSelf());
 
         if (w > 0 && h > 0) {
             mScaleState.mDrawable.setBounds(r.left, r.top, r.right, r.bottom);
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h
index cda2be0..401638a 100644
--- a/include/media/AudioEffect.h
+++ b/include/media/AudioEffect.h
@@ -23,7 +23,7 @@
 #include <media/IAudioFlinger.h>
 #include <media/IEffect.h>
 #include <media/IEffectClient.h>
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
 #include <media/AudioSystem.h>
 
 #include <utils/RefBase.h>
@@ -298,7 +298,7 @@
      */
             int32_t     id() const { return mId; }
 
-    /* Returns a descriptor for the effect (see effect_descriptor_t in EffectApi.h).
+    /* Returns a descriptor for the effect (see effect_descriptor_t in audio_effect.h).
      */
             effect_descriptor_t descriptor() const;
 
@@ -324,7 +324,7 @@
      *
      * Parameters:
      *      param:  pointer to effect_param_t structure containing the parameter
-     *          and its value (See EffectApi.h).
+     *          and its value (See audio_effect.h).
      * Returned status (from utils/Errors.h) can be:
      *  - NO_ERROR: successful operation.
      *  - INVALID_OPERATION: the application does not have control of the effect engine.
@@ -340,7 +340,7 @@
      *
      * Parameters:
      *      param:  pointer to effect_param_t structure containing the parameter
-     *          and its value (See EffectApi.h).
+     *          and its value (See audio_effect.h).
      *
      * Returned status (from utils/Errors.h) can be:
      *  - NO_ERROR: successful operation.
@@ -368,7 +368,7 @@
      *
      * Parameters:
      *      param:  pointer to effect_param_t structure containing the parameter
-     *          and the returned value (See EffectApi.h).
+     *          and the returned value (See audio_effect.h).
      *
      * Returned status (from utils/Errors.h) can be:
      *  - NO_ERROR: successful operation.
@@ -379,7 +379,7 @@
      virtual status_t   getParameter(effect_param_t *param);
 
      /* Sends a command and receives a response to/from effect engine.
-      *     See EffectApi.h for details on effect command() function, valid command codes
+      *     See audio_effect.h for details on effect command() function, valid command codes
       *     and formats.
       */
      virtual status_t command(uint32_t cmdCode,
diff --git a/include/media/EffectApi.h b/include/media/EffectApi.h
deleted file mode 100644
index a5ad846..0000000
--- a/include/media/EffectApi.h
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_EFFECTAPI_H_
-#define ANDROID_EFFECTAPI_H_
-
-#include <errno.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-/////////////////////////////////////////////////
-//      Effect control interface
-/////////////////////////////////////////////////
-
-// The effect control interface is exposed by each effect engine implementation. It consists of
-// a set of functions controlling the configuration, activation and process of the engine.
-// The functions are grouped in a structure of type effect_interface_s:
-//    struct effect_interface_s {
-//        effect_process_t process;
-//        effect_command_t command;
-//    };
-
-
-// effect_interface_t: Effect control interface handle.
-// The effect_interface_t serves two purposes regarding the implementation of the effect engine:
-// - 1 it is the address of a pointer to an effect_interface_s structure where the functions
-// of the effect control API for a particular effect are located.
-// - 2 it is the address of the context of a particular effect instance.
-// A typical implementation in the effect library would define a structure as follows:
-// struct effect_module_s {
-//        const struct effect_interface_s *itfe;
-//        effect_config_t config;
-//        effect_context_t context;
-// }
-// The implementation of EffectCreate() function would then allocate a structure of this
-// type and return its address as effect_interface_t
-typedef struct effect_interface_s **effect_interface_t;
-
-
-// Effect API version 1.0
-#define EFFECT_API_VERSION 0x0100 // Format 0xMMmm MM: Major version, mm: minor version
-
-// Maximum length of character strings in structures defines by this API.
-#define EFFECT_STRING_LEN_MAX 64
-
-//
-//--- Effect descriptor structure effect_descriptor_t
-//
-
-// Unique effect ID (can be generated from the following site:
-//  http://www.itu.int/ITU-T/asn1/uuid.html)
-// This format is used for both "type" and "uuid" fields of the effect descriptor structure.
-// - When used for effect type and the engine is implementing and effect corresponding to a standard
-// OpenSL ES interface, this ID must be the one defined in OpenSLES_IID.h for that interface.
-// - When used as uuid, it should be a unique UUID for this particular implementation.
-typedef struct effect_uuid_s {
-    uint32_t timeLow;
-    uint16_t timeMid;
-    uint16_t timeHiAndVersion;
-    uint16_t clockSeq;
-    uint8_t node[6];
-} effect_uuid_t;
-
-// NULL UUID definition (matches SL_IID_NULL_)
-#define EFFECT_UUID_INITIALIZER { 0xec7178ec, 0xe5e1, 0x4432, 0xa3f4, \
-                                  { 0x46, 0x57, 0xe6, 0x79, 0x52, 0x10 } }
-static const effect_uuid_t EFFECT_UUID_NULL_ = EFFECT_UUID_INITIALIZER;
-const effect_uuid_t * const EFFECT_UUID_NULL = &EFFECT_UUID_NULL_;
-const char * const EFFECT_UUID_NULL_STR = "ec7178ec-e5e1-4432-a3f4-4657e6795210";
-
-// The effect descriptor contains necessary information to facilitate the enumeration of the effect
-// engines present in a library.
-typedef struct effect_descriptor_s {
-    effect_uuid_t type;     // UUID of to the OpenSL ES interface implemented by this effect
-    effect_uuid_t uuid;     // UUID for this particular implementation
-    uint16_t apiVersion;    // Version of the effect API implemented: matches EFFECT_API_VERSION
-    uint32_t flags;         // effect engine capabilities/requirements flags (see below)
-    uint16_t cpuLoad;       // CPU load indication (see below)
-    uint16_t memoryUsage;   // Data Memory usage (see below)
-    char    name[EFFECT_STRING_LEN_MAX];   // human readable effect name
-    char    implementor[EFFECT_STRING_LEN_MAX];    // human readable effect implementor name
-} effect_descriptor_t;
-
-// CPU load and memory usage indication: each effect implementation must provide an indication of
-// its CPU and memory usage for the audio effect framework to limit the number of effects
-// instantiated at a given time on a given platform.
-// The CPU load is expressed in 0.1 MIPS units as estimated on an ARM9E core (ARMv5TE) with 0 WS.
-// The memory usage is expressed in KB and includes only dynamically allocated memory
-
-// Definitions for flags field of effect descriptor.
-//  +---------------------------+-----------+-----------------------------------
-//  | description               | bits      | values
-//  +---------------------------+-----------+-----------------------------------
-//  | connection mode           | 0..1      | 0 insert: after track process
-//  |                           |           | 1 auxiliary: connect to track auxiliary
-//  |                           |           |  output and use send level
-//  |                           |           | 2 replace: replaces track process function;
-//  |                           |           |   must implement SRC, volume and mono to stereo.
-//  |                           |           | 3 reserved
-//  +---------------------------+-----------+-----------------------------------
-//  | insertion preference      | 2..4      | 0 none
-//  |                           |           | 1 first of the chain
-//  |                           |           | 2 last of the chain
-//  |                           |           | 3 exclusive (only effect in the insert chain)
-//  |                           |           | 4..7 reserved
-//  +---------------------------+-----------+-----------------------------------
-//  | Volume management         | 5..6      | 0 none
-//  |                           |           | 1 implements volume control
-//  |                           |           | 2 requires volume indication
-//  |                           |           | 3 reserved
-//  +---------------------------+-----------+-----------------------------------
-//  | Device indication         | 7..8      | 0 none
-//  |                           |           | 1 requires device updates
-//  |                           |           | 2..3 reserved
-//  +---------------------------+-----------+-----------------------------------
-//  | Sample input mode         | 9..10     | 0 direct: process() function or EFFECT_CMD_CONFIGURE
-//  |                           |           |   command must specify a buffer descriptor
-//  |                           |           | 1 provider: process() function uses the
-//  |                           |           |   bufferProvider indicated by the
-//  |                           |           |   EFFECT_CMD_CONFIGURE command to request input.
-//  |                           |           |   buffers.
-//  |                           |           | 2 both: both input modes are supported
-//  |                           |           | 3 reserved
-//  +---------------------------+-----------+-----------------------------------
-//  | Sample output mode        | 11..12    | 0 direct: process() function or EFFECT_CMD_CONFIGURE
-//  |                           |           |   command must specify a buffer descriptor
-//  |                           |           | 1 provider: process() function uses the
-//  |                           |           |   bufferProvider indicated by the
-//  |                           |           |   EFFECT_CMD_CONFIGURE command to request output
-//  |                           |           |   buffers.
-//  |                           |           | 2 both: both output modes are supported
-//  |                           |           | 3 reserved
-//  +---------------------------+-----------+-----------------------------------
-//  | Hardware acceleration     | 13..15    | 0 No hardware acceleration
-//  |                           |           | 1 non tunneled hw acceleration: the process() function
-//  |                           |           |   reads the samples, send them to HW accelerated
-//  |                           |           |   effect processor, reads back the processed samples
-//  |                           |           |   and returns them to the output buffer.
-//  |                           |           | 2 tunneled hw acceleration: the process() function is
-//  |                           |           |   transparent. The effect interface is only used to
-//  |                           |           |   control the effect engine. This mode is relevant for
-//  |                           |           |   global effects actually applied by the audio
-//  |                           |           |   hardware on the output stream.
-//  +---------------------------+-----------+-----------------------------------
-//  | Audio Mode indication     | 16..17    | 0 none
-//  |                           |           | 1 requires audio mode updates
-//  |                           |           | 2..3 reserved
-//  +---------------------------+-----------+-----------------------------------
-
-// Insert mode
-#define EFFECT_FLAG_TYPE_MASK           0x00000003
-#define EFFECT_FLAG_TYPE_INSERT         0x00000000
-#define EFFECT_FLAG_TYPE_AUXILIARY      0x00000001
-#define EFFECT_FLAG_TYPE_REPLACE        0x00000002
-
-// Insert preference
-#define EFFECT_FLAG_INSERT_MASK         0x0000001C
-#define EFFECT_FLAG_INSERT_ANY          0x00000000
-#define EFFECT_FLAG_INSERT_FIRST        0x00000004
-#define EFFECT_FLAG_INSERT_LAST         0x00000008
-#define EFFECT_FLAG_INSERT_EXCLUSIVE    0x0000000C
-
-
-// Volume control
-#define EFFECT_FLAG_VOLUME_MASK         0x00000060
-#define EFFECT_FLAG_VOLUME_CTRL         0x00000020
-#define EFFECT_FLAG_VOLUME_IND          0x00000040
-#define EFFECT_FLAG_VOLUME_NONE         0x00000000
-
-// Device indication
-#define EFFECT_FLAG_DEVICE_MASK         0x00000180
-#define EFFECT_FLAG_DEVICE_IND          0x00000080
-#define EFFECT_FLAG_DEVICE_NONE         0x00000000
-
-// Sample input modes
-#define EFFECT_FLAG_INPUT_MASK          0x00000600
-#define EFFECT_FLAG_INPUT_DIRECT        0x00000000
-#define EFFECT_FLAG_INPUT_PROVIDER      0x00000200
-#define EFFECT_FLAG_INPUT_BOTH          0x00000400
-
-// Sample output modes
-#define EFFECT_FLAG_OUTPUT_MASK          0x00001800
-#define EFFECT_FLAG_OUTPUT_DIRECT        0x00000000
-#define EFFECT_FLAG_OUTPUT_PROVIDER      0x00000800
-#define EFFECT_FLAG_OUTPUT_BOTH          0x00001000
-
-// Hardware acceleration mode
-#define EFFECT_FLAG_HW_ACC_MASK          0x00006000
-#define EFFECT_FLAG_HW_ACC_SIMPLE        0x00002000
-#define EFFECT_FLAG_HW_ACC_TUNNEL        0x00004000
-
-// Audio mode indication
-#define EFFECT_FLAG_AUDIO_MODE_MASK      0x00018000
-#define EFFECT_FLAG_AUDIO_MODE_IND       0x00008000
-#define EFFECT_FLAG_AUDIO_MODE_NONE      0x00000000
-
-// Forward definition of type audio_buffer_t
-typedef struct audio_buffer_s audio_buffer_t;
-
-////////////////////////////////////////////////////////////////////////////////
-//
-//    Function:       process
-//
-//    Description:    Effect process function. Takes input samples as specified
-//          (count and location) in input buffer descriptor and output processed
-//          samples as specified in output buffer descriptor. If the buffer descriptor
-//          is not specified the function must use either the buffer or the
-//          buffer provider function installed by the EFFECT_CMD_CONFIGURE command.
-//          The effect framework will call the process() function after the EFFECT_CMD_ENABLE
-//          command is received and until the EFFECT_CMD_DISABLE is received. When the engine
-//          receives the EFFECT_CMD_DISABLE command it should turn off the effect gracefully
-//          and when done indicate that it is OK to stop calling the process() function by
-//          returning the -ENODATA status.
-//
-//    NOTE: the process() function implementation should be "real-time safe" that is
-//      it should not perform blocking calls: malloc/free, sleep, read/write/open/close,
-//      pthread_cond_wait/pthread_mutex_lock...
-//
-//    Input:
-//          effect_interface_t: handle to the effect interface this function
-//              is called on.
-//          inBuffer:   buffer descriptor indicating where to read samples to process.
-//              If NULL, use the configuration passed by EFFECT_CMD_CONFIGURE command.
-//
-//          inBuffer:   buffer descriptor indicating where to write processed samples.
-//              If NULL, use the configuration passed by EFFECT_CMD_CONFIGURE command.
-//
-//    Output:
-//        returned value:    0 successful operation
-//                          -ENODATA the engine has finished the disable phase and the framework
-//                                  can stop calling process()
-//                          -EINVAL invalid interface handle or
-//                                  invalid input/output buffer description
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_process_t)(effect_interface_t self,
-                                    audio_buffer_t *inBuffer,
-                                    audio_buffer_t *outBuffer);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-//    Function:       command
-//
-//    Description:    Send a command and receive a response to/from effect engine.
-//
-//    Input:
-//          effect_interface_t: handle to the effect interface this function
-//              is called on.
-//          cmdCode:    command code: the command can be a standardized command defined in
-//              effect_command_e (see below) or a proprietary command.
-//          cmdSize:    size of command in bytes
-//          pCmdData:   pointer to command data
-//          pReplyData: pointer to reply data
-//
-//    Input/Output:
-//          replySize: maximum size of reply data as input
-//                      actual size of reply data as output
-//
-//    Output:
-//          returned value: 0       successful operation
-//                          -EINVAL invalid interface handle or
-//                                  invalid command/reply size or format according to command code
-//              The return code should be restricted to indicate problems related to the this
-//              API specification. Status related to the execution of a particular command should be
-//              indicated as part of the reply field.
-//
-//          *pReplyData updated with command response
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_command_t)(effect_interface_t self,
-                                    uint32_t cmdCode,
-                                    uint32_t cmdSize,
-                                    void *pCmdData,
-                                    uint32_t *replySize,
-                                    void *pReplyData);
-
-
-// Effect control interface definition
-struct effect_interface_s {
-    effect_process_t process;
-    effect_command_t command;
-};
-
-
-//
-//--- Standardized command codes for command() function
-//
-enum effect_command_e {
-   EFFECT_CMD_INIT,                 // initialize effect engine
-   EFFECT_CMD_CONFIGURE,            // configure effect engine (see effect_config_t)
-   EFFECT_CMD_RESET,                // reset effect engine
-   EFFECT_CMD_ENABLE,               // enable effect process
-   EFFECT_CMD_DISABLE,              // disable effect process
-   EFFECT_CMD_SET_PARAM,            // set parameter immediately (see effect_param_t)
-   EFFECT_CMD_SET_PARAM_DEFERRED,   // set parameter deferred
-   EFFECT_CMD_SET_PARAM_COMMIT,     // commit previous set parameter deferred
-   EFFECT_CMD_GET_PARAM,            // get parameter
-   EFFECT_CMD_SET_DEVICE,           // set audio device (see audio_device_e)
-   EFFECT_CMD_SET_VOLUME,           // set volume
-   EFFECT_CMD_SET_AUDIO_MODE,       // set the audio mode (normal, ring, ...)
-   EFFECT_CMD_FIRST_PROPRIETARY = 0x10000 // first proprietary command code
-};
-
-//==================================================================================================
-// command: EFFECT_CMD_INIT
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Initialize effect engine: All configurations return to default
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 0
-//  data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_CONFIGURE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Apply new audio parameters configurations for input and output buffers
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(effect_config_t)
-//  data: effect_config_t
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_RESET
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Reset the effect engine. Keep configuration but resets state and buffer content
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 0
-//  data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: 0
-//  data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_ENABLE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Enable the process. Called by the framework before the first call to process()
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 0
-//  data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_DISABLE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Disable the process. Called by the framework after the last call to process()
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 0
-//  data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_SET_PARAM
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Set a parameter and apply it immediately
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(effect_param_t) + size of param and value
-//  data: effect_param_t + param + value. See effect_param_t definition below for value offset
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_SET_PARAM_DEFERRED
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Set a parameter but apply it only when receiving EFFECT_CMD_SET_PARAM_COMMIT command
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(effect_param_t) + size of param and value
-//  data: effect_param_t + param + value. See effect_param_t definition below for value offset
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: 0
-//  data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_SET_PARAM_COMMIT
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Apply all previously received EFFECT_CMD_SET_PARAM_DEFERRED commands
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 0
-//  data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_GET_PARAM
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Get a parameter value
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(effect_param_t) + size of param
-//  data: effect_param_t + param
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(effect_param_t) + size of param and value
-//  data: effect_param_t + param + value. See effect_param_t definition below for value offset
-//==================================================================================================
-// command: EFFECT_CMD_SET_DEVICE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Set the rendering device the audio output path is connected to. See audio_device_e for device
-//  values.
-//  The effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this
-//  command when the device changes
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(uint32_t)
-//  data: audio_device_e
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: 0
-//  data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_SET_VOLUME
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Set and get volume. Used by audio framework to delegate volume control to effect engine.
-//  The effect implementation must set EFFECT_FLAG_VOLUME_IND or EFFECT_FLAG_VOLUME_CTRL flag in
-//  its descriptor to receive this command before every call to process() function
-//  If EFFECT_FLAG_VOLUME_CTRL flag is set in the effect descriptor, the effect engine must return
-//  the volume that should be applied before the effect is processed. The overall volume (the volume
-//  actually applied by the effect engine multiplied by the returned value) should match the value
-//  indicated in the command.
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: n * sizeof(uint32_t)
-//  data: volume for each channel defined in effect_config_t for output buffer expressed in
-//      8.24 fixed point format
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: n * sizeof(uint32_t) / 0
-//  data: - if EFFECT_FLAG_VOLUME_CTRL is set in effect descriptor:
-//              volume for each channel defined in effect_config_t for output buffer expressed in
-//              8.24 fixed point format
-//        - if EFFECT_FLAG_VOLUME_CTRL is not set in effect descriptor:
-//              N/A
-//  It is legal to receive a null pointer as pReplyData in which case the effect framework has
-//  delegated volume control to another effect
-//==================================================================================================
-// command: EFFECT_CMD_SET_AUDIO_MODE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Set the audio mode. The effect implementation must set EFFECT_FLAG_AUDIO_MODE_IND flag in its
-//  descriptor to receive this command when the audio mode changes.
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(uint32_t)
-//  data: audio_mode_e
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: 0
-//  data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_FIRST_PROPRIETARY
-//--------------------------------------------------------------------------------------------------
-// description:
-//  All proprietary effect commands must use command codes above this value. The size and format of
-//  command and response fields is free in this case
-//==================================================================================================
-
-
-// Audio buffer descriptor used by process(), bufferProvider() functions and buffer_config_t
-// structure. Multi-channel audio is always interleaved. The channel order is from LSB to MSB with
-// regard to the channel mask definition in audio_channels_e e.g :
-// Stereo: left, right
-// 5 point 1: front left, front right, front center, low frequency, back left, back right
-// The buffer size is expressed in frame count, a frame being composed of samples for all
-// channels at a given time. Frame size for unspecified format (AUDIO_FORMAT_OTHER) is 8 bit by
-// definition
-struct audio_buffer_s {
-    size_t   frameCount;        // number of frames in buffer
-    union {
-        void*       raw;        // raw pointer to start of buffer
-        int32_t*    s32;        // pointer to signed 32 bit data at start of buffer
-        int16_t*    s16;        // pointer to signed 16 bit data at start of buffer
-        uint8_t*    u8;         // pointer to unsigned 8 bit data at start of buffer
-    };
-};
-
-// The buffer_provider_s structure contains functions that can be used
-// by the effect engine process() function to query and release input
-// or output audio buffer.
-// The getBuffer() function is called to retrieve a buffer where data
-// should read from or written to by process() function.
-// The releaseBuffer() function MUST be called when the buffer retrieved
-// with getBuffer() is not needed anymore.
-// The process function should use the buffer provider mechanism to retrieve
-// input or output buffer if the inBuffer or outBuffer passed as argument is NULL
-// and the buffer configuration (buffer_config_t) given by the EFFECT_CMD_CONFIGURE
-// command did not specify an audio buffer.
-
-typedef int32_t (* buffer_function_t)(void *cookie, audio_buffer_t *buffer);
-
-typedef struct buffer_provider_s {
-    buffer_function_t getBuffer;       // retrieve next buffer
-    buffer_function_t releaseBuffer;   // release used buffer
-    void       *cookie;                // for use by client of buffer provider functions
-} buffer_provider_t;
-
-
-// The buffer_config_s structure specifies the input or output audio format
-// to be used by the effect engine. It is part of the effect_config_t
-// structure that defines both input and output buffer configurations and is
-// passed by the EFFECT_CMD_CONFIGURE command.
-typedef struct buffer_config_s {
-    audio_buffer_t  buffer;     // buffer for use by process() function if not passed explicitly
-    uint32_t   samplingRate;    // sampling rate
-    uint32_t   channels;        // channel mask (see audio_channels_e)
-    buffer_provider_t bufferProvider;   // buffer provider
-    uint8_t    format;          // Audio format  (see audio_format_e)
-    uint8_t    accessMode;      // read/write or accumulate in buffer (effect_buffer_access_e)
-    uint16_t   mask;            // indicates which of the above fields is valid
-} buffer_config_t;
-
-// Sample format
-enum audio_format_e {
-    SAMPLE_FORMAT_PCM_S15,   // PCM signed 16 bits
-    SAMPLE_FORMAT_PCM_U8,    // PCM unsigned 8 bits
-    SAMPLE_FORMAT_PCM_S7_24, // PCM signed 7.24 fixed point representation
-    SAMPLE_FORMAT_OTHER      // other format (e.g. compressed)
-};
-
-// Channel mask
-enum audio_channels_e {
-    CHANNEL_FRONT_LEFT = 0x1,                   // front left channel
-    CHANNEL_FRONT_RIGHT = 0x2,                  // front right channel
-    CHANNEL_FRONT_CENTER = 0x4,                // front center channel
-    CHANNEL_LOW_FREQUENCY = 0x8,               // low frequency channel
-    CHANNEL_BACK_LEFT = 0x10,                   // back left channel
-    CHANNEL_BACK_RIGHT = 0x20,                  // back right channel
-    CHANNEL_FRONT_LEFT_OF_CENTER = 0x40,       // front left of center channel
-    CHANNEL_FRONT_RIGHT_OF_CENTER = 0x80,      // front right of center channel
-    CHANNEL_BACK_CENTER = 0x100,                // back center channel
-    CHANNEL_MONO = CHANNEL_FRONT_LEFT,
-    CHANNEL_STEREO = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT),
-    CHANNEL_QUAD = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
-            CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT),
-    CHANNEL_SURROUND = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
-            CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER),
-    CHANNEL_5POINT1 = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
-            CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT),
-    CHANNEL_7POINT1 = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
-            CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT |
-            CHANNEL_FRONT_LEFT_OF_CENTER | CHANNEL_FRONT_RIGHT_OF_CENTER),
-};
-
-// Render device
-enum audio_device_e {
-    DEVICE_EARPIECE = 0x1,                      // earpiece
-    DEVICE_SPEAKER = 0x2,                       // speaker
-    DEVICE_WIRED_HEADSET = 0x4,                 // wired headset, with microphone
-    DEVICE_WIRED_HEADPHONE = 0x8,               // wired headphone, without microphone
-    DEVICE_BLUETOOTH_SCO = 0x10,                // generic bluetooth SCO
-    DEVICE_BLUETOOTH_SCO_HEADSET = 0x20,        // bluetooth SCO headset
-    DEVICE_BLUETOOTH_SCO_CARKIT = 0x40,         // bluetooth SCO car kit
-    DEVICE_BLUETOOTH_A2DP = 0x80,               // generic bluetooth A2DP
-    DEVICE_BLUETOOTH_A2DP_HEADPHONES = 0x100,   // bluetooth A2DP headphones
-    DEVICE_BLUETOOTH_A2DP_SPEAKER = 0x200,      // bluetooth A2DP speakers
-    DEVICE_AUX_DIGITAL = 0x400,                 // digital output
-    DEVICE_EXTERNAL_SPEAKER = 0x800             // external speaker (stereo and High quality)
-};
-
-// Audio mode
-enum audio_mode_e {
-    AUDIO_EFFECT_MODE_NORMAL,   // device idle
-    AUDIO_EFFECT_MODE_RINGTONE, // device ringing
-    AUDIO_EFFECT_MODE_IN_CALL,  // audio call connected (VoIP or telephony)
-};
-
-// Values for "accessMode" field of buffer_config_t:
-//   overwrite, read only, accumulate (read/modify/write)
-enum effect_buffer_access_e {
-    EFFECT_BUFFER_ACCESS_WRITE,
-    EFFECT_BUFFER_ACCESS_READ,
-    EFFECT_BUFFER_ACCESS_ACCUMULATE
-
-};
-
-// Values for bit field "mask" in buffer_config_t. If a bit is set, the corresponding field
-// in buffer_config_t must be taken into account when executing the EFFECT_CMD_CONFIGURE command
-#define EFFECT_CONFIG_BUFFER    0x0001  // buffer field must be taken into account
-#define EFFECT_CONFIG_SMP_RATE  0x0002  // samplingRate field must be taken into account
-#define EFFECT_CONFIG_CHANNELS  0x0004  // channels field must be taken into account
-#define EFFECT_CONFIG_FORMAT    0x0008  // format field must be taken into account
-#define EFFECT_CONFIG_ACC_MODE  0x0010  // accessMode field must be taken into account
-#define EFFECT_CONFIG_PROVIDER  0x0020  // bufferProvider field must be taken into account
-#define EFFECT_CONFIG_ALL (EFFECT_CONFIG_BUFFER | EFFECT_CONFIG_SMP_RATE | \
-                           EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT | \
-                           EFFECT_CONFIG_ACC_MODE | EFFECT_CONFIG_PROVIDER)
-
-
-// effect_config_s structure describes the format of the pCmdData argument of EFFECT_CMD_CONFIGURE
-// command to configure audio parameters and buffers for effect engine input and output.
-typedef struct effect_config_s {
-    buffer_config_t   inputCfg;
-    buffer_config_t   outputCfg;;
-} effect_config_t;
-
-
-// effect_param_s structure describes the format of the pCmdData argument of EFFECT_CMD_SET_PARAM
-// command and pCmdData and pReplyData of EFFECT_CMD_GET_PARAM command.
-// psize and vsize represent the actual size of parameter and value.
-//
-// NOTE: the start of value field inside the data field is always on a 32 bit boundary:
-//
-//  +-----------+
-//  | status    | sizeof(int)
-//  +-----------+
-//  | psize     | sizeof(int)
-//  +-----------+
-//  | vsize     | sizeof(int)
-//  +-----------+
-//  |           |   |           |
-//  ~ parameter ~   > psize     |
-//  |           |   |           >  ((psize - 1)/sizeof(int) + 1) * sizeof(int)
-//  +-----------+               |
-//  | padding   |               |
-//  +-----------+
-//  |           |   |
-//  ~ value     ~   > vsize
-//  |           |   |
-//  +-----------+
-
-typedef struct effect_param_s {
-    int32_t     status;     // Transaction status (unused for command, used for reply)
-    uint32_t    psize;      // Parameter size
-    uint32_t    vsize;      // Value size
-    char        data[];     // Start of Parameter + Value data
-} effect_param_t;
-
-
-/////////////////////////////////////////////////
-//      Effect library interface
-/////////////////////////////////////////////////
-
-// An effect library is required to implement and expose the following functions
-// to enable effect enumeration and instantiation. The name of these functions must be as
-// specified here as the effect framework will get the function address with dlsym():
-//
-// - effect_QueryNumberEffects_t EffectQueryNumberEffects;
-// - effect_QueryEffect_t EffectQueryEffect;
-// - effect_CreateEffect_t EffectCreate;
-// - effect_ReleaseEffect_t EffectRelease;
-
-
-////////////////////////////////////////////////////////////////////////////////
-//
-//    Function:       EffectQueryNumberEffects
-//
-//    Description:    Returns the number of different effects exposed by the
-//          library. Each effect must have a unique effect uuid (see
-//          effect_descriptor_t). This function together with EffectQueryEffect()
-//          is used to enumerate all effects present in the library.
-//
-//    Input/Output:
-//          pNumEffects:    address where the number of effects should be returned.
-//
-//    Output:
-//        returned value:    0          successful operation.
-//                          -ENODEV     library failed to initialize
-//                          -EINVAL     invalid pNumEffects
-//        *pNumEffects:     updated with number of effects in library
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_QueryNumberEffects_t)(uint32_t *pNumEffects);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-//    Function:       EffectQueryEffect
-//
-//    Description:    Returns the descriptor of the effect engine which index is
-//          given as first argument.
-//          See effect_descriptor_t for details on effect descriptors.
-//          This function together with EffectQueryNumberEffects() is used to enumerate all
-//          effects present in the library. The enumeration sequence is:
-//              EffectQueryNumberEffects(&num_effects);
-//              for (i = 0; i < num_effects; i++)
-//                  EffectQueryEffect(i,...);
-//
-//    Input/Output:
-//          index:          index of the effect
-//          pDescriptor:    address where to return the effect descriptor.
-//
-//    Output:
-//        returned value:    0          successful operation.
-//                          -ENODEV     library failed to initialize
-//                          -EINVAL     invalid pDescriptor or index
-//                          -ENOSYS     effect list has changed since last execution of
-//                                      EffectQueryNumberEffects()
-//                          -ENOENT     no more effect available
-//        *pDescriptor:     updated with the effect descriptor.
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_QueryEffect_t)(uint32_t index,
-                                        effect_descriptor_t *pDescriptor);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-//    Function:       EffectCreate
-//
-//    Description:    Creates an effect engine of the specified type and returns an
-//          effect control interface on this engine. The function will allocate the
-//          resources for an instance of the requested effect engine and return
-//          a handle on the effect control interface.
-//
-//    Input:
-//          uuid:    pointer to the effect uuid.
-//          sessionId:  audio session to which this effect instance will be attached. All effects
-//              created with the same session ID are connected in series and process the same signal
-//              stream. Knowing that two effects are part of the same effect chain can help the
-//              library implement some kind of optimizations.
-//          ioId:   identifies the output or input stream this effect is directed to at audio HAL.
-//              For future use especially with tunneled HW accelerated effects
-//
-//    Input/Output:
-//          pInterface:    address where to return the effect interface.
-//
-//    Output:
-//        returned value:    0          successful operation.
-//                          -ENODEV     library failed to initialize
-//                          -EINVAL     invalid pEffectUuid or pInterface
-//                          -ENOENT     no effect with this uuid found
-//        *pInterface:     updated with the effect interface handle.
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_CreateEffect_t)(effect_uuid_t *uuid,
-                                         int32_t sessionId,
-                                         int32_t ioId,
-                                         effect_interface_t *pInterface);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-//    Function:       EffectRelease
-//
-//    Description:    Releases the effect engine whose handle is given as argument.
-//          All resources allocated to this particular instance of the effect are
-//          released.
-//
-//    Input:
-//          interface:    handle on the effect interface to be released.
-//
-//    Output:
-//        returned value:    0          successful operation.
-//                          -ENODEV     library failed to initialize
-//                          -EINVAL     invalid interface handle
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_ReleaseEffect_t)(effect_interface_t interface);
-
-
-#if __cplusplus
-}  // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTAPI_H_*/
diff --git a/include/media/EffectBassBoostApi.h b/include/media/EffectBassBoostApi.h
index 75f8d78..56119eb 100644
--- a/include/media/EffectBassBoostApi.h
+++ b/include/media/EffectBassBoostApi.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_EFFECTBASSBOOSTAPI_H_
 #define ANDROID_EFFECTBASSBOOSTAPI_H_
 
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
 
 #if __cplusplus
 extern "C" {
diff --git a/include/media/EffectEnvironmentalReverbApi.h b/include/media/EffectEnvironmentalReverbApi.h
index 36accd8..f11c5ec 100644
--- a/include/media/EffectEnvironmentalReverbApi.h
+++ b/include/media/EffectEnvironmentalReverbApi.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_EFFECTENVIRONMENTALREVERBAPI_H_
 #define ANDROID_EFFECTENVIRONMENTALREVERBAPI_H_
 
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
 
 #if __cplusplus
 extern "C" {
diff --git a/include/media/EffectEqualizerApi.h b/include/media/EffectEqualizerApi.h
index 0492ea0..950d138 100644
--- a/include/media/EffectEqualizerApi.h
+++ b/include/media/EffectEqualizerApi.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_EFFECTEQUALIZERAPI_H_
 #define ANDROID_EFFECTEQUALIZERAPI_H_
 
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
 
 #ifndef OPENSL_ES_H_
 static const effect_uuid_t SL_IID_EQUALIZER_ = { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
diff --git a/include/media/EffectPresetReverbApi.h b/include/media/EffectPresetReverbApi.h
index a3f094c..e5b168a6 100644
--- a/include/media/EffectPresetReverbApi.h
+++ b/include/media/EffectPresetReverbApi.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_EFFECTPRESETREVERBAPI_H_
 #define ANDROID_EFFECTPRESETREVERBAPI_H_
 
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
 
 #if __cplusplus
 extern "C" {
diff --git a/include/media/EffectVirtualizerApi.h b/include/media/EffectVirtualizerApi.h
index c3d5131..2e216e2 100644
--- a/include/media/EffectVirtualizerApi.h
+++ b/include/media/EffectVirtualizerApi.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_EFFECTVIRTUALIZERAPI_H_
 #define ANDROID_EFFECTVIRTUALIZERAPI_H_
 
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
 
 #if __cplusplus
 extern "C" {
diff --git a/include/media/EffectVisualizerApi.h b/include/media/EffectVisualizerApi.h
index bef1a4f..e0fa328 100644
--- a/include/media/EffectVisualizerApi.h
+++ b/include/media/EffectVisualizerApi.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_EFFECTVISUALIZERAPI_H_
 #define ANDROID_EFFECTVISUALIZERAPI_H_
 
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
 
 #if __cplusplus
 extern "C" {
diff --git a/include/media/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h
index 0ed1a14..b63fac6 100644
--- a/include/media/EffectsFactoryApi.h
+++ b/include/media/EffectsFactoryApi.h
@@ -20,7 +20,7 @@
 #include <errno.h>
 #include <stdint.h>
 #include <sys/types.h>
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
 
 #if __cplusplus
 extern "C" {
@@ -99,17 +99,17 @@
 //              use especially with tunneled HW accelerated effects
 //
 //    Input/Output:
-//          pInterface:    address where to return the effect interface.
+//          pHandle:        address where to return the effect handle.
 //
 //    Output:
 //        returned value:    0          successful operation.
 //                          -ENODEV     factory failed to initialize
-//                          -EINVAL     invalid pEffectUuid or pInterface
+//                          -EINVAL     invalid pEffectUuid or pHandle
 //                          -ENOENT     no effect with this uuid found
-//        *pInterface:     updated with the effect interface.
+//        *pHandle:         updated with the effect handle.
 //
 ////////////////////////////////////////////////////////////////////////////////
-int EffectCreate(effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, effect_interface_t *pInterface);
+int EffectCreate(effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle);
 
 ////////////////////////////////////////////////////////////////////////////////
 //
@@ -120,7 +120,7 @@
 //          released.
 //
 //    Input:
-//          interface:    handler on the effect interface to be released.
+//          handle:    handler on the effect interface to be released.
 //
 //    Output:
 //        returned value:    0          successful operation.
@@ -128,7 +128,7 @@
 //                          -EINVAL     invalid interface handler
 //
 ////////////////////////////////////////////////////////////////////////////////
-int EffectRelease(effect_interface_t interface);
+int EffectRelease(effect_handle_t handle);
 
 ////////////////////////////////////////////////////////////////////////////////
 //
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 589f7cd..75f3e71 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -27,7 +27,7 @@
 #include <media/IAudioTrack.h>
 #include <media/IAudioRecord.h>
 #include <media/IAudioFlingerClient.h>
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
 #include <media/IEffect.h>
 #include <media/IEffectClient.h>
 #include <utils/String8.h>
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index cd48429..b0d8cf9 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -102,7 +102,7 @@
         const uint32_t size = fontRenderer.getFontRendererSize(i);
         log.appendFormat("  FontRenderer %d       %8d / %8d\n", i, size, size);
     }
-    log.appendFormat("Other:");
+    log.appendFormat("Other:\n");
     log.appendFormat("  FboCache             %8d / %8d\n",
             fboCache.getSize(), fboCache.getMaxSize());
     log.appendFormat("  PatchCache           %8d / %8d\n",
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 8cf325b..6243b01 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -990,12 +990,26 @@
     }
 }
 
+void OpenGLRenderer::accountForClear(SkXfermode::Mode mode) {
+    if (mColorSet && mode == SkXfermode::kClear_Mode) {
+        mColorA = 1.0f;
+        mColorR = mColorG = mColorB = 0.0f;
+        mSetShaderColor = mDescription.setAlpha8Color(mColorR, mColorG, mColorB, mColorA);
+    }
+}
+
 void OpenGLRenderer::setupDrawBlending(SkXfermode::Mode mode, bool swapSrcDst) {
+    // When the blending mode is kClear_Mode, we need to use a modulate color
+    // argb=1,0,0,0
+    accountForClear(mode);
     chooseBlending((mColorSet && mColorA < 1.0f) || (mShader && mShader->blend()), mode,
             mDescription, swapSrcDst);
 }
 
 void OpenGLRenderer::setupDrawBlending(bool blend, SkXfermode::Mode mode, bool swapSrcDst) {
+    // When the blending mode is kClear_Mode, we need to use a modulate color
+    // argb=1,0,0,0
+    accountForClear(mode);
     chooseBlending(blend || (mColorSet && mColorA < 1.0f) || (mShader && mShader->blend()), mode,
             mDescription, swapSrcDst);
 }
@@ -1369,10 +1383,10 @@
     const float width = texture->width;
     const float height = texture->height;
 
-    const float u1 = srcLeft / width;
-    const float v1 = srcTop / height;
-    const float u2 = srcRight / width;
-    const float v2 = srcBottom / height;
+    const float u1 = (srcLeft + 0.5f) / width;
+    const float v1 = (srcTop + 0.5f)  / height;
+    const float u2 = (srcRight - 0.5f) / width;
+    const float v2 = (srcBottom - 0.5f) / height;
 
     mCaches.unbindMeshBuffer();
     resetDrawTextureTexCoords(u1, v1, u2, v2);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 70abe88..e2dbba0 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -478,6 +478,7 @@
     void setupDrawAALine(GLvoid* vertices, GLvoid* distanceCoords, GLvoid* lengthCoords,
             float strokeWidth);
     void finishDrawTexture();
+    void accountForClear(SkXfermode::Mode mode);
 
     void drawRegionRects(const Region& region);
 
diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp
index f58fe1a..2e13e9d 100644
--- a/libs/rs/driver/rsdAllocation.cpp
+++ b/libs/rs/driver/rsdAllocation.cpp
@@ -41,13 +41,42 @@
 };
 
 
+GLenum rsdTypeToGLType(RsDataType t) {
+    switch (t) {
+    case RS_TYPE_UNSIGNED_5_6_5:    return GL_UNSIGNED_SHORT_5_6_5;
+    case RS_TYPE_UNSIGNED_5_5_5_1:  return GL_UNSIGNED_SHORT_5_5_5_1;
+    case RS_TYPE_UNSIGNED_4_4_4_4:  return GL_UNSIGNED_SHORT_4_4_4_4;
+
+    //case RS_TYPE_FLOAT_16:      return GL_HALF_FLOAT;
+    case RS_TYPE_FLOAT_32:      return GL_FLOAT;
+    case RS_TYPE_UNSIGNED_8:    return GL_UNSIGNED_BYTE;
+    case RS_TYPE_UNSIGNED_16:   return GL_UNSIGNED_SHORT;
+    case RS_TYPE_SIGNED_8:      return GL_BYTE;
+    case RS_TYPE_SIGNED_16:     return GL_SHORT;
+    default:    break;
+    }
+    return 0;
+}
+
+GLenum rsdKindToGLFormat(RsDataKind k) {
+    switch (k) {
+    case RS_KIND_PIXEL_L: return GL_LUMINANCE;
+    case RS_KIND_PIXEL_A: return GL_ALPHA;
+    case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA;
+    case RS_KIND_PIXEL_RGB: return GL_RGB;
+    case RS_KIND_PIXEL_RGBA: return GL_RGBA;
+    case RS_KIND_PIXEL_DEPTH: return GL_DEPTH_COMPONENT16;
+    default: break;
+    }
+    return 0;
+}
+
+
 static void Update2DTexture(const Allocation *alloc, const void *ptr, uint32_t xoff, uint32_t yoff,
                      uint32_t lod, RsAllocationCubemapFace face,
                      uint32_t w, uint32_t h) {
     DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
 
-    const GLenum type = alloc->mHal.state.type->getElement()->getComponent().getGLType();
-    const GLenum format = alloc->mHal.state.type->getElement()->getComponent().getGLFormat();
     rsAssert(drv->textureID);
     glBindTexture(drv->glTarget, drv->textureID);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -55,16 +84,13 @@
     if (alloc->mHal.state.hasFaces) {
         t = gFaceOrder[face];
     }
-    glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr);
+    glTexSubImage2D(t, lod, xoff, yoff, w, h, drv->glFormat, drv->glType, ptr);
 }
 
 
 static void Upload2DTexture(const Context *rsc, const Allocation *alloc, bool isFirstUpload) {
     DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
 
-    GLenum type = alloc->mHal.state.type->getElement()->getComponent().getGLType();
-    GLenum format = alloc->mHal.state.type->getElement()->getComponent().getGLFormat();
-
     glBindTexture(drv->glTarget, drv->textureID);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
@@ -85,15 +111,15 @@
             }
 
             if (isFirstUpload) {
-                glTexImage2D(t, lod, format,
+                glTexImage2D(t, lod, drv->glFormat,
                              alloc->mHal.state.type->getLODDimX(lod),
                              alloc->mHal.state.type->getLODDimY(lod),
-                             0, format, type, p);
+                             0, drv->glFormat, drv->glType, p);
             } else {
                 glTexSubImage2D(t, lod, 0, 0,
                                 alloc->mHal.state.type->getLODDimX(lod),
                                 alloc->mHal.state.type->getLODDimY(lod),
-                                format, type, p);
+                                drv->glFormat, drv->glType, p);
             }
         }
     }
@@ -107,10 +133,7 @@
 static void UploadToTexture(const Context *rsc, const Allocation *alloc) {
     DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
 
-    GLenum type = alloc->mHal.state.type->getElement()->getComponent().getGLType();
-    GLenum format = alloc->mHal.state.type->getElement()->getComponent().getGLFormat();
-
-    if (!type || !format) {
+    if (!drv->glType || !drv->glFormat) {
         return;
     }
 
@@ -139,8 +162,7 @@
 static void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) {
     DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
 
-    GLenum format = alloc->mHal.state.type->getElement()->getComponent().getGLFormat();
-    if (!format) {
+    if (!drv->glFormat) {
         return;
     }
 
@@ -154,7 +176,7 @@
             return;
         }
         glBindRenderbuffer(GL_RENDERBUFFER, drv->renderTargetID);
-        glRenderbufferStorage(GL_RENDERBUFFER, format,
+        glRenderbufferStorage(GL_RENDERBUFFER, drv->glFormat,
                               alloc->mHal.state.dimensionX, alloc->mHal.state.dimensionY);
     }
     rsdGLCheckError(rsc, "AllocateRenderTarget");
@@ -208,6 +230,10 @@
         }
     }
 
+    drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType());
+    drv->glFormat = rsdKindToGLFormat(alloc->mHal.state.type->getElement()->getComponent().getKind());
+
+
     alloc->mHal.drvState.mallocPtr = ptr;
     drv->mallocPtr = (uint8_t *)ptr;
     alloc->mHal.drv = drv;
diff --git a/libs/rs/driver/rsdAllocation.h b/libs/rs/driver/rsdAllocation.h
index 45a538b..d7385ce 100644
--- a/libs/rs/driver/rsdAllocation.h
+++ b/libs/rs/driver/rsdAllocation.h
@@ -39,10 +39,17 @@
     uint8_t * mallocPtr;
 
     GLenum glTarget;
+    GLenum glType;
+    GLenum glFormat;
+
 
     bool uploadDeferred;
 };
 
+GLenum rsdTypeToGLType(RsDataType t);
+GLenum rsdKindToGLFormat(RsDataKind k);
+
+
 bool rsdAllocationInit(const android::renderscript::Context *rsc,
                        android::renderscript::Allocation *alloc,
                        bool forceZero);
diff --git a/libs/rs/driver/rsdMeshObj.cpp b/libs/rs/driver/rsdMeshObj.cpp
index 260595c..c220ac1 100644
--- a/libs/rs/driver/rsdMeshObj.cpp
+++ b/libs/rs/driver/rsdMeshObj.cpp
@@ -114,7 +114,7 @@
 
             mAttribs[userNum].size = c.getVectorSize();
             mAttribs[userNum].offset = elem->getFieldOffsetBytes(fieldI);
-            mAttribs[userNum].type = c.getGLType();
+            mAttribs[userNum].type = rsdTypeToGLType(c.getType());
             mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
             mAttribs[userNum].stride = stride;
             String8 tmp(RS_SHADER_ATTR);
diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp
index e2ae043..e65febb 100644
--- a/libs/rs/rsComponent.cpp
+++ b/libs/rs/rsComponent.cpp
@@ -16,11 +16,6 @@
 
 #include "rsComponent.h"
 
-#ifndef ANDROID_RS_SERIALIZE
-#include <GLES/gl.h>
-#include <GLES2/gl2.h>
-#endif
-
 using namespace android;
 using namespace android::renderscript;
 
@@ -181,40 +176,6 @@
     return (mType >= RS_TYPE_ELEMENT);
 }
 
-uint32_t Component::getGLType() const {
-#ifndef ANDROID_RS_SERIALIZE
-    switch (mType) {
-    case RS_TYPE_UNSIGNED_5_6_5:    return GL_UNSIGNED_SHORT_5_6_5;
-    case RS_TYPE_UNSIGNED_5_5_5_1:  return GL_UNSIGNED_SHORT_5_5_5_1;
-    case RS_TYPE_UNSIGNED_4_4_4_4:  return GL_UNSIGNED_SHORT_4_4_4_4;
-
-    //case RS_TYPE_FLOAT_16:      return GL_HALF_FLOAT;
-    case RS_TYPE_FLOAT_32:      return GL_FLOAT;
-    case RS_TYPE_UNSIGNED_8:    return GL_UNSIGNED_BYTE;
-    case RS_TYPE_UNSIGNED_16:   return GL_UNSIGNED_SHORT;
-    case RS_TYPE_SIGNED_8:      return GL_BYTE;
-    case RS_TYPE_SIGNED_16:     return GL_SHORT;
-    default:    break;
-    }
-#endif //ANDROID_RS_SERIALIZE
-    return 0;
-}
-
-uint32_t Component::getGLFormat() const {
-#ifndef ANDROID_RS_SERIALIZE
-    switch (mKind) {
-    case RS_KIND_PIXEL_L: return GL_LUMINANCE;
-    case RS_KIND_PIXEL_A: return GL_ALPHA;
-    case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA;
-    case RS_KIND_PIXEL_RGB: return GL_RGB;
-    case RS_KIND_PIXEL_RGBA: return GL_RGBA;
-    case RS_KIND_PIXEL_DEPTH: return GL_DEPTH_COMPONENT16;
-    default: break;
-    }
-#endif //ANDROID_RS_SERIALIZE
-    return 0;
-}
-
 String8 Component::getGLSLType() const {
     if (mType == RS_TYPE_SIGNED_32) {
         switch (mVectorSize) {
@@ -244,6 +205,7 @@
     return String8();
 }
 
+
 static const char * gTypeBasicStrings[] = {
     "NONE",
     "F16",
diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h
index 1bb4ff4..a448f0e 100644
--- a/libs/rs/rsComponent.h
+++ b/libs/rs/rsComponent.h
@@ -32,8 +32,6 @@
 
     void set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize=1);
 
-    uint32_t getGLType() const;
-    uint32_t getGLFormat() const;
     String8 getGLSLType() const;
     void dumpLOGV(const char *prefix) const;
 
diff --git a/media/libeffects/data/audio_effects.conf b/media/libeffects/data/audio_effects.conf
new file mode 100644
index 0000000..e6a7b37
--- /dev/null
+++ b/media/libeffects/data/audio_effects.conf
@@ -0,0 +1,57 @@
+# List of effect libraries to load. Each library element must contain a "path" element
+# giving the full path of the library .so file.
+libraries {
+  bundle {
+    path /system/lib/soundfx/libbundlewrapper.so
+  }
+  reverb {
+    path /system/lib/soundfx/libreverbwrapper.so
+  }
+  visualizer {
+    path /system/lib/soundfx/libvisualizer.so
+  }
+}
+
+# list of effects to load. Each effect element must contain a "library" and a "uuid" element.
+# The value of the "library" element must correspond to the name of one library element in the
+# "libraries" element.
+# The name of the effect element is indicative, only the value of the "uuid" element
+# designates the effect.
+effects {
+  bassboost {
+    library bundle
+    uuid 8631f300-72e2-11df-b57e-0002a5d5c51b
+  }
+  virtualizer {
+    library bundle
+    uuid 1d4033c0-8557-11df-9f2d-0002a5d5c51b
+  }
+  equalizer {
+    library bundle
+    uuid ce772f20-847d-11df-bb17-0002a5d5c51b
+  }
+  volume {
+    library bundle
+    uuid 119341a0-8469-11df-81f9- 0002a5d5c51b
+  }
+  reverb_env_aux {
+    library reverb
+    uuid 4a387fc0-8ab3-11df-8bad- 0002a5d5c51b
+  }
+  reverb_env_ins {
+    library reverb
+    uuid c7a511a0-a3bb-11df-860e-0002a5d5c51b
+  }
+  reverb_pre_aux {
+    library reverb
+    uuid f29a1400-a3bb-11df-8ddc-0002a5d5c51b
+  }
+  reverb_pre_ins {
+    library reverb
+    uuid 172cdf00-a3bc-11df-a72f-0002a5d5c51b
+  }
+  visualizer {
+    library visualizer
+    uuid d069d9e0-8329-11df-9168-0002a5d5c51b
+  }
+}
diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c
index c19a505..b541be5 100644
--- a/media/libeffects/factory/EffectsFactory.c
+++ b/media/libeffects/factory/EffectsFactory.c
@@ -22,6 +22,8 @@
 #include <stdlib.h>
 #include <dlfcn.h>
 
+#include <cutils/misc.h>
+#include <cutils/config_utils.h>
 
 static list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects
 static list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries
@@ -30,30 +32,39 @@
 static list_elem_t *gCurLib;    // current library in enumeration process
 static list_elem_t *gCurEffect; // current effect in enumeration process
 static uint32_t gCurEffectIdx;       // current effect index in enumeration process
+static lib_entry_t *gCachedLibrary;  // last library accessed by getLibrary()
 
-const char * const gEffectLibPath = "/system/lib/soundfx"; // path to built-in effect libraries
 static int gInitDone; // true is global initialization has been preformed
-static int gNextLibId; // used by loadLibrary() to allocate unique library handles
 static int gCanQueryEffect; // indicates that call to EffectQueryEffect() is valid, i.e. that the list of effects
                           // was not modified since last call to EffectQueryNumberEffects()
 
+
 /////////////////////////////////////////////////
 //      Local functions prototypes
 /////////////////////////////////////////////////
 
 static int init();
-static int loadLibrary(const char *libPath, int *handle);
-static int unloadLibrary(int handle);
+static int loadEffectConfigFile(const char *path);
+static int loadLibraries(cnode *root);
+static int loadLibrary(cnode *root, const char *name);
+static int loadEffects(cnode *root);
+static int loadEffect(cnode *node);
+static lib_entry_t *getLibrary(const char *path);
 static void resetEffectEnumeration();
 static uint32_t updateNumEffects();
-static int findEffect(effect_uuid_t *uuid, lib_entry_t **lib, effect_descriptor_t **desc);
+static int findEffect(effect_uuid_t *type,
+               effect_uuid_t *uuid,
+               lib_entry_t **lib,
+               effect_descriptor_t **desc);
 static void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len);
+static int stringToUuid(const char *str, effect_uuid_t *uuid);
+static int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen);
 
 /////////////////////////////////////////////////
 //      Effect Control Interface functions
 /////////////////////////////////////////////////
 
-int Effect_Process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
+int Effect_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
 {
     int ret = init();
     if (ret < 0) {
@@ -73,7 +84,7 @@
     return ret;
 }
 
-int Effect_Command(effect_interface_t self,
+int Effect_Command(effect_handle_t self,
                    uint32_t cmdCode,
                    uint32_t cmdSize,
                    void *pCmdData,
@@ -98,9 +109,31 @@
     return ret;
 }
 
+int Effect_GetDescriptor(effect_handle_t self,
+                         effect_descriptor_t *desc)
+{
+    int ret = init();
+    if (ret < 0) {
+        return ret;
+    }
+    effect_entry_t *fx = (effect_entry_t *)self;
+    pthread_mutex_lock(&gLibLock);
+    if (fx->lib == NULL) {
+        pthread_mutex_unlock(&gLibLock);
+        return -EPIPE;
+    }
+    pthread_mutex_lock(&fx->lib->lock);
+    pthread_mutex_unlock(&gLibLock);
+
+    ret = (*fx->subItfe)->get_descriptor(fx->subItfe, desc);
+    pthread_mutex_unlock(&fx->lib->lock);
+    return ret;
+}
+
 const struct effect_interface_s gInterface = {
         Effect_Process,
-        Effect_Command
+        Effect_Command,
+        Effect_GetDescriptor
 };
 
 /////////////////////////////////////////////////
@@ -182,7 +215,7 @@
         return -EINVAL;
     }
     pthread_mutex_lock(&gLibLock);
-    ret = findEffect(uuid, &l, &d);
+    ret = findEffect(NULL, uuid, &l, &d);
     if (ret == 0) {
         memcpy(pDescriptor, d, sizeof(effect_descriptor_t));
     }
@@ -190,17 +223,17 @@
     return ret;
 }
 
-int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_interface_t *pInterface)
+int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle)
 {
     list_elem_t *e = gLibraryList;
     lib_entry_t *l = NULL;
     effect_descriptor_t *d = NULL;
-    effect_interface_t itfe;
+    effect_handle_t itfe;
     effect_entry_t *fx;
     int found = 0;
     int ret;
 
-    if (uuid == NULL || pInterface == NULL) {
+    if (uuid == NULL || pHandle == NULL) {
         return -EINVAL;
     }
 
@@ -218,15 +251,15 @@
 
     pthread_mutex_lock(&gLibLock);
 
-    ret = findEffect(uuid, &l, &d);
+    ret = findEffect(NULL, uuid, &l, &d);
     if (ret < 0){
         goto exit;
     }
 
     // create effect in library
-    ret = l->createFx(uuid, sessionId, ioId, &itfe);
+    l->desc->create_effect(uuid, sessionId, ioId, &itfe);
     if (ret != 0) {
-        LOGW("EffectCreate() library %s: could not create fx %s, error %d", l->path, d->name, ret);
+        LOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret);
         goto exit;
     }
 
@@ -241,16 +274,16 @@
     e->next = gEffectList;
     gEffectList = e;
 
-    *pInterface = (effect_interface_t)fx;
+    *pHandle = (effect_handle_t)fx;
 
-    LOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pInterface, itfe, l->path);
+    LOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pHandle, itfe, l->name);
 
 exit:
     pthread_mutex_unlock(&gLibLock);
     return ret;
 }
 
-int EffectRelease(effect_interface_t interface)
+int EffectRelease(effect_handle_t handle)
 {
     effect_entry_t *fx;
     list_elem_t *e1;
@@ -266,7 +299,7 @@
     e1 = gEffectList;
     e2 = NULL;
     while (e1) {
-        if (e1->object == interface) {
+        if (e1->object == handle) {
             if (e2) {
                 e2->next = e1->next;
             } else {
@@ -286,10 +319,10 @@
 
     // release effect in library
     if (fx->lib == NULL) {
-        LOGW("EffectRelease() fx %p library already unloaded", interface);
+        LOGW("EffectRelease() fx %p library already unloaded", handle);
     } else {
         pthread_mutex_lock(&fx->lib->lock);
-        fx->lib->releaseFx(fx->subItfe);
+        fx->lib->desc->release_effect(fx->subItfe);
         pthread_mutex_unlock(&fx->lib->lock);
     }
     free(fx);
@@ -301,29 +334,14 @@
 
 int EffectLoadLibrary(const char *libPath, int *handle)
 {
-    int ret = init();
-    if (ret < 0) {
-        return ret;
-    }
-    if (libPath == NULL) {
-        return -EINVAL;
-    }
-
-    ret = loadLibrary(libPath, handle);
-    updateNumEffects();
-    return ret;
+    // TODO: see if this interface still makes sense with the use of config files
+    return -ENOSYS;
 }
 
 int EffectUnloadLibrary(int handle)
 {
-    int ret = init();
-    if (ret < 0) {
-        return ret;
-    }
-
-    ret = unloadLibrary(handle);
-    updateNumEffects();
-    return ret;
+    // TODO: see if this interface still makes sense with the use of config files
+    return -ENOSYS;
 }
 
 int EffectIsNullUuid(effect_uuid_t *uuid)
@@ -339,9 +357,6 @@
 /////////////////////////////////////////////////
 
 int init() {
-    struct dirent *ent;
-    DIR *dir = NULL;
-    char libpath[PATH_MAX];
     int hdl;
 
     if (gInitDone) {
@@ -350,214 +365,210 @@
 
     pthread_mutex_init(&gLibLock, NULL);
 
-    // load built-in libraries
-    dir = opendir(gEffectLibPath);
-    if (dir == NULL) {
-        return -ENODEV;
+    if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
+        loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
+    } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
+        loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
     }
-    while ((ent = readdir(dir)) != NULL) {
-        LOGV("init() reading file %s", ent->d_name);
-        if ((strlen(ent->d_name) < 3) ||
-            strncmp(ent->d_name, "lib", 3) != 0 ||
-            strncmp(ent->d_name + strlen(ent->d_name) - 3, ".so", 3) != 0) {
-            continue;
-        }
-        strcpy(libpath, gEffectLibPath);
-        strcat(libpath, "/");
-        strcat(libpath, ent->d_name);
-        if (loadLibrary(libpath, &hdl) < 0) {
-            LOGW("init() failed to load library %s",libpath);
-        }
-    }
-    closedir(dir);
+
     updateNumEffects();
     gInitDone = 1;
     LOGV("init() done");
     return 0;
 }
 
-
-int loadLibrary(const char *libPath, int *handle)
+int loadEffectConfigFile(const char *path)
 {
+    cnode *root;
+    char *data;
+
+    data = load_file(path, NULL);
+    if (data == NULL) {
+        return -ENODEV;
+    }
+    root = config_node("", "");
+    config_load(root, data);
+    loadLibraries(root);
+    loadEffects(root);
+    config_free(root);
+    free(root);
+    free(data);
+
+    return 0;
+}
+
+int loadLibraries(cnode *root)
+{
+    cnode *node;
+
+    node = config_find(root, LIBRARIES_TAG);
+    if (node == NULL) {
+        return -ENOENT;
+    }
+    node = node->first_child;
+    while (node) {
+        loadLibrary(node, node->name);
+        node = node->next;
+    }
+    return 0;
+}
+
+int loadLibrary(cnode *root, const char *name)
+{
+    cnode *node;
     void *hdl;
-    effect_QueryNumberEffects_t queryNumFx;
-    effect_QueryEffect_t queryFx;
-    effect_CreateEffect_t createFx;
-    effect_ReleaseEffect_t releaseFx;
-    uint32_t numFx;
-    uint32_t fx;
-    int ret;
-    list_elem_t *e, *descHead = NULL;
+    audio_effect_library_t *desc;
+    list_elem_t *e;
     lib_entry_t *l;
 
-    if (handle == NULL) {
+    node = config_find(root, PATH_TAG);
+    if (node == NULL) {
         return -EINVAL;
     }
 
-    *handle = 0;
-
-    hdl = dlopen(libPath, RTLD_NOW);
-    if (hdl == 0) {
-        LOGW("could open lib %s", libPath);
-        return -ENODEV;
-    }
-
-    // Check functions availability
-    queryNumFx = (effect_QueryNumberEffects_t)dlsym(hdl, "EffectQueryNumberEffects");
-    if (queryNumFx == NULL) {
-        LOGW("could not get EffectQueryNumberEffects from lib %s", libPath);
-        ret = -ENODEV;
-        goto error;
-    }
-    queryFx = (effect_QueryEffect_t)dlsym(hdl, "EffectQueryEffect");
-    if (queryFx == NULL) {
-        LOGW("could not get EffectQueryEffect from lib %s", libPath);
-        ret = -ENODEV;
-        goto error;
-    }
-    createFx = (effect_CreateEffect_t)dlsym(hdl, "EffectCreate");
-    if (createFx == NULL) {
-        LOGW("could not get EffectCreate from lib %s", libPath);
-        ret = -ENODEV;
-        goto error;
-    }
-    releaseFx = (effect_ReleaseEffect_t)dlsym(hdl, "EffectRelease");
-    if (releaseFx == NULL) {
-        LOGW("could not get EffectRelease from lib %s", libPath);
-        ret = -ENODEV;
+    hdl = dlopen(node->value, RTLD_NOW);
+    if (hdl == NULL) {
+        LOGW("loadLibrary() failed to open %s", node->value);
         goto error;
     }
 
-    // load effect descriptors
-    ret = queryNumFx(&numFx);
-    if (ret) {
+    desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
+    if (desc == NULL) {
+        LOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
         goto error;
     }
 
-    for (fx = 0; fx < numFx; fx++) {
-        effect_descriptor_t *d = malloc(sizeof(effect_descriptor_t));
-        if (d == NULL) {
-            ret = -ENOMEM;
-            goto error;
-        }
-        ret = queryFx(fx, d);
-        if (ret == 0) {
-#if (LOG_NDEBUG==0)
-            char s[256];
-            dumpEffectDescriptor(d, s, 256);
-            LOGV("loadLibrary() read descriptor %p:%s",d, s);
-#endif
-            if (d->apiVersion != EFFECT_API_VERSION) {
-                LOGW("Bad API version %04x on lib %s", d->apiVersion, libPath);
-                free(d);
-                continue;
-            }
-            e = malloc(sizeof(list_elem_t));
-            if (e == NULL) {
-                free(d);
-                ret = -ENOMEM;
-                goto error;
-            }
-            e->object = d;
-            e->next = descHead;
-            descHead = e;
-        } else {
-            LOGW("Error querying effect # %d on lib %s", fx, libPath);
-        }
+    if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) {
+        LOGW("getLibrary() bad tag %08x in lib info struct", desc->tag);
+        goto error;
     }
 
-    pthread_mutex_lock(&gLibLock);
+    if (EFFECT_API_VERSION_MAJOR(desc->version) !=
+            EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) {
+        LOGW("loadLibrary() bad lib version %08x", desc->version);
+        goto error;
+    }
 
     // add entry for library in gLibraryList
     l = malloc(sizeof(lib_entry_t));
-    l->id = ++gNextLibId;
+    l->name = strndup(name, PATH_MAX);
+    l->path = strndup(node->value, PATH_MAX);
     l->handle = hdl;
-    strncpy(l->path, libPath, PATH_MAX);
-    l->createFx = createFx;
-    l->releaseFx = releaseFx;
-    l->effects = descHead;
+    l->desc = desc;
+    l->effects = NULL;
     pthread_mutex_init(&l->lock, NULL);
 
     e = malloc(sizeof(list_elem_t));
-    e->next = gLibraryList;
     e->object = l;
+    pthread_mutex_lock(&gLibLock);
+    e->next = gLibraryList;
     gLibraryList = e;
     pthread_mutex_unlock(&gLibLock);
-    LOGV("loadLibrary() linked library %p", l);
-
-    *handle = l->id;
+    LOGV("getLibrary() linked library %p for path %s", l, node->value);
 
     return 0;
 
 error:
-    LOGW("loadLibrary() error: %d on lib: %s", ret, libPath);
-    while (descHead) {
-        free(descHead->object);
-        e = descHead->next;
-        free(descHead);
-        descHead = e;;
+    if (hdl != NULL) {
+        dlclose(hdl);
     }
-    dlclose(hdl);
-    return ret;
+    return -EINVAL;
 }
 
-int unloadLibrary(int handle)
+int loadEffects(cnode *root)
 {
-    void *hdl;
-    int ret;
-    list_elem_t *el1, *el2;
-    lib_entry_t *l;
-    effect_entry_t *fx;
+    cnode *node;
 
-    pthread_mutex_lock(&gLibLock);
-    el1 = gLibraryList;
-    el2 = NULL;
-    while (el1) {
-        l = (lib_entry_t *)el1->object;
-        if (handle == l->id) {
-            if (el2) {
-                el2->next = el1->next;
-            } else {
-                gLibraryList = el1->next;
-            }
-            free(el1);
-            break;
-        }
-        el2 = el1;
-        el1 = el1->next;
-    }
-    pthread_mutex_unlock(&gLibLock);
-    if (el1 == NULL) {
+    node = config_find(root, EFFECTS_TAG);
+    if (node == NULL) {
         return -ENOENT;
     }
-
-    // clear effect descriptor list
-    el1 = l->effects;
-    while (el1) {
-        free(el1->object);
-        el2 = el1->next;
-        free(el1);
-        el1 = el2;
+    node = node->first_child;
+    while (node) {
+        loadEffect(node);
+        node = node->next;
     }
-
-    // disable all effects from this library
-    pthread_mutex_lock(&l->lock);
-
-    el1 = gEffectList;
-    while (el1) {
-        fx = (effect_entry_t *)el1->object;
-        if (fx->lib == l) {
-            fx->lib = NULL;
-        }
-        el1 = el1->next;
-    }
-    pthread_mutex_unlock(&l->lock);
-
-    dlclose(l->handle);
-    free(l);
     return 0;
 }
 
+int loadEffect(cnode *root)
+{
+    cnode *node;
+    effect_uuid_t uuid;
+    lib_entry_t *l;
+    effect_descriptor_t *d;
+    list_elem_t *e;
+
+    node = config_find(root, LIBRARY_TAG);
+    if (node == NULL) {
+        return -EINVAL;
+    }
+
+    l = getLibrary(node->value);
+    if (l == NULL) {
+        LOGW("loadEffect() could not get library %s", node->value);
+        return -EINVAL;
+    }
+
+    node = config_find(root, UUID_TAG);
+    if (node == NULL) {
+        return -EINVAL;
+    }
+    if (stringToUuid(node->value, &uuid) != 0) {
+        LOGW("loadEffect() invalid uuid %s", node->value);
+        return -EINVAL;
+    }
+
+    d = malloc(sizeof(effect_descriptor_t));
+    if (l->desc->get_descriptor(&uuid, d) != 0) {
+        char s[40];
+        uuidToString(&uuid, s, 40);
+        LOGW("Error querying effect %s on lib %s", s, l->name);
+        free(d);
+        return -EINVAL;
+    }
+#if (LOG_NDEBUG==0)
+    char s[256];
+    dumpEffectDescriptor(d, s, 256);
+    LOGV("loadEffect() read descriptor %p:%s",d, s);
+#endif
+    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
+            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
+        LOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
+        free(d);
+        return -EINVAL;
+    }
+    e = malloc(sizeof(list_elem_t));
+    e->object = d;
+    e->next = l->effects;
+    l->effects = e;
+
+    return 0;
+}
+
+lib_entry_t *getLibrary(const char *name)
+{
+    list_elem_t *e;
+
+    if (gCachedLibrary &&
+            !strncmp(gCachedLibrary->name, name, PATH_MAX)) {
+        return gCachedLibrary;
+    }
+
+    e = gLibraryList;
+    while (e) {
+        lib_entry_t *l = (lib_entry_t *)e->object;
+        if (!strcmp(l->name, name)) {
+            gCachedLibrary = l;
+            return l;
+        }
+        e = e->next;
+    }
+
+    return NULL;
+}
+
+
 void resetEffectEnumeration()
 {
     gCurLib = gLibraryList;
@@ -589,7 +600,10 @@
     return cnt;
 }
 
-int findEffect(effect_uuid_t *uuid, lib_entry_t **lib, effect_descriptor_t **desc)
+int findEffect(effect_uuid_t *type,
+               effect_uuid_t *uuid,
+               lib_entry_t **lib,
+               effect_descriptor_t **desc)
 {
     list_elem_t *e = gLibraryList;
     lib_entry_t *l = NULL;
@@ -602,7 +616,11 @@
         list_elem_t *efx = l->effects;
         while (efx) {
             d = (effect_descriptor_t *)efx->object;
-            if (memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
+            if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) {
+                found = 1;
+                break;
+            }
+            if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
                 found = 1;
                 break;
             }
@@ -614,9 +632,11 @@
         LOGV("findEffect() effect not found");
         ret = -ENOENT;
     } else {
-        LOGV("findEffect() found effect: %s in lib %s", d->name, l->path);
+        LOGV("findEffect() found effect: %s in lib %s", d->name, l->name);
         *lib = l;
-        *desc = d;
+        if (desc) {
+            *desc = d;
+        }
     }
 
     return ret;
@@ -626,17 +646,12 @@
     char s[256];
 
     snprintf(str, len, "\nEffect Descriptor %p:\n", desc);
-    sprintf(s, "- UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
-            desc->uuid.timeLow, desc->uuid.timeMid, desc->uuid.timeHiAndVersion,
-            desc->uuid.clockSeq, desc->uuid.node[0], desc->uuid.node[1],desc->uuid.node[2],
-            desc->uuid.node[3],desc->uuid.node[4],desc->uuid.node[5]);
-    strncat(str, s, len);
-    sprintf(s, "- TYPE: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
-                desc->type.timeLow, desc->type.timeMid, desc->type.timeHiAndVersion,
-                desc->type.clockSeq, desc->type.node[0], desc->type.node[1],desc->type.node[2],
-                desc->type.node[3],desc->type.node[4],desc->type.node[5]);
-    strncat(str, s, len);
-    sprintf(s, "- apiVersion: %04X\n- flags: %08X\n",
+    strncat(str, "- TYPE: ", len);
+    uuidToString(&desc->uuid, s, 256);
+    snprintf(str, len, "- UUID: %s\n", s);
+    uuidToString(&desc->type, s, 256);
+    snprintf(str, len, "- TYPE: %s\n", s);
+    sprintf(s, "- apiVersion: %08X\n- flags: %08X\n",
             desc->apiVersion, desc->flags);
     strncat(str, s, len);
     sprintf(s, "- name: %s\n", desc->name);
@@ -645,3 +660,43 @@
     strncat(str, s, len);
 }
 
+int stringToUuid(const char *str, effect_uuid_t *uuid)
+{
+    int tmp[10];
+
+    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
+        return -EINVAL;
+    }
+    uuid->timeLow = (uint32_t)tmp[0];
+    uuid->timeMid = (uint16_t)tmp[1];
+    uuid->timeHiAndVersion = (uint16_t)tmp[2];
+    uuid->clockSeq = (uint16_t)tmp[3];
+    uuid->node[0] = (uint8_t)tmp[4];
+    uuid->node[1] = (uint8_t)tmp[5];
+    uuid->node[2] = (uint8_t)tmp[6];
+    uuid->node[3] = (uint8_t)tmp[7];
+    uuid->node[4] = (uint8_t)tmp[8];
+    uuid->node[5] = (uint8_t)tmp[9];
+
+    return 0;
+}
+
+int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen)
+{
+
+    snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+            uuid->timeLow,
+            uuid->timeMid,
+            uuid->timeHiAndVersion,
+            uuid->clockSeq,
+            uuid->node[0],
+            uuid->node[1],
+            uuid->node[2],
+            uuid->node[3],
+            uuid->node[4],
+            uuid->node[5]);
+
+    return 0;
+}
+
diff --git a/media/libeffects/factory/EffectsFactory.h b/media/libeffects/factory/EffectsFactory.h
index 8f543ca..fcc0dba 100644
--- a/media/libeffects/factory/EffectsFactory.h
+++ b/media/libeffects/factory/EffectsFactory.h
@@ -22,29 +22,35 @@
 #include <dirent.h>
 #include <media/EffectsFactoryApi.h>
 
-
 #if __cplusplus
 extern "C" {
 #endif
 
+#define AUDIO_EFFECT_DEFAULT_CONFIG_FILE "/system/etc/audio_effects.conf"
+#define AUDIO_EFFECT_VENDOR_CONFIG_FILE "/vendor/etc/audio_effects.conf"
+#define EFFECTS_TAG "effects"
+#define LIBRARIES_TAG "libraries"
+#define PATH_TAG "path"
+#define LIBRARY_TAG "library"
+#define UUID_TAG "uuid"
+
 typedef struct list_elem_s {
     void *object;
     struct list_elem_s *next;
 } list_elem_t;
 
 typedef struct lib_entry_s {
-    char path[PATH_MAX];
+    audio_effect_library_t *desc;
+    char *name;
+    char *path;
     void *handle;
-    int id;
-    effect_CreateEffect_t createFx;
-    effect_ReleaseEffect_t releaseFx;
     list_elem_t *effects; //list of effect_descriptor_t
     pthread_mutex_t lock;
 } lib_entry_t;
 
 typedef struct effect_entry_s {
     struct effect_interface_s *itfe;
-    effect_interface_t subItfe;
+    effect_handle_t subItfe;
     lib_entry_t *lib;
 } effect_entry_t;
 
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 0b061db..21c451f 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -27,7 +27,7 @@
 #include <EffectBundle.h>
 
 
-// effect_interface_t interface implementation for bass boost
+// effect_handle_t interface implementation for bass boost
 extern "C" const struct effect_interface_s gLvmEffectInterface;
 
 #define LVM_ERROR_CHECK(LvmStatus, callingFunc, calledFunc){\
@@ -71,7 +71,7 @@
 const effect_descriptor_t gBassBoostDescriptor = {
         {0x0634f220, 0xddd4, 0x11db, 0xa0fc, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }},
         {0x8631f300, 0x72e2, 0x11df, 0xb57e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_DEVICE_IND
         | EFFECT_FLAG_VOLUME_CTRL),
         BASS_BOOST_CUP_LOAD_ARM9E,
@@ -84,7 +84,7 @@
 const effect_descriptor_t gVirtualizerDescriptor = {
         {0x37cc2c00, 0xdddd, 0x11db, 0x8577, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
         {0x1d4033c0, 0x8557, 0x11df, 0x9f2d, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_DEVICE_IND
         | EFFECT_FLAG_VOLUME_CTRL),
         VIRTUALIZER_CUP_LOAD_ARM9E,
@@ -97,7 +97,7 @@
 const effect_descriptor_t gEqualizerDescriptor = {
         {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
         {0xce772f20, 0x847d, 0x11df, 0xbb17, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid Eq NXP
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_VOLUME_CTRL),
         EQUALIZER_CUP_LOAD_ARM9E,
         BUNDLE_MEM_USAGE,
@@ -109,7 +109,7 @@
 const effect_descriptor_t gVolumeDescriptor = {
         {0x09e8ede0, 0xddde, 0x11db, 0xb4f6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }},
         {0x119341a0, 0x8469, 0x11df, 0x81f9, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }}, //uuid VOL NXP
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_VOLUME_CTRL),
         VOLUME_CUP_LOAD_ARM9E,
         BUNDLE_MEM_USAGE,
@@ -187,7 +187,7 @@
 extern "C" int EffectCreate(effect_uuid_t       *uuid,
                             int32_t             sessionId,
                             int32_t             ioId,
-                            effect_interface_t  *pInterface){
+                            effect_handle_t  *pHandle){
     int ret = 0;
     int sessionNo;
     int i;
@@ -197,7 +197,7 @@
 
     LOGV("\n\tEffectCreate start session %d", sessionId);
 
-    if (pInterface == NULL || uuid == NULL){
+    if (pHandle == NULL || uuid == NULL){
         LOGV("\tLVM_ERROR : EffectCreate() called with NULL pointer");
         ret = -EINVAL;
         goto exit;
@@ -355,19 +355,19 @@
             }
             delete pContext;
         }
-        *pInterface = (effect_interface_t)NULL;
+        *pHandle = (effect_handle_t)NULL;
     } else {
-        *pInterface = (effect_interface_t)pContext;
+        *pHandle = (effect_handle_t)pContext;
     }
     LOGV("\tEffectCreate end..\n\n");
     return ret;
 } /* end EffectCreate */
 
-extern "C" int EffectRelease(effect_interface_t interface){
-    LOGV("\n\tEffectRelease start %p", interface);
-    EffectContext * pContext = (EffectContext *)interface;
+extern "C" int EffectRelease(effect_handle_t handle){
+    LOGV("\n\tEffectRelease start %p", handle);
+    EffectContext * pContext = (EffectContext *)handle;
 
-    LOGV("\tEffectRelease start interface: %p, context %p", interface, pContext->pBundledContext);
+    LOGV("\tEffectRelease start handle: %p, context %p", handle, pContext->pBundledContext);
     if (pContext == NULL){
         LOGV("\tLVM_ERROR : EffectRelease called with NULL pointer");
         return -EINVAL;
@@ -460,6 +460,34 @@
 
 } /* end EffectRelease */
 
+extern "C" int EffectGetDescriptor(effect_uuid_t       *uuid,
+                                   effect_descriptor_t *pDescriptor) {
+    const effect_descriptor_t *desc = NULL;
+
+    if (pDescriptor == NULL || uuid == NULL){
+        LOGV("EffectGetDescriptor() called with NULL pointer");
+        return -EINVAL;
+    }
+
+    if (memcmp(uuid, &gBassBoostDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+        desc = &gBassBoostDescriptor;
+    } else if (memcmp(uuid, &gVirtualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+        desc = &gVirtualizerDescriptor;
+    } else if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+        desc = &gEqualizerDescriptor;
+    } else if (memcmp(uuid, &gVolumeDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+        desc = &gVolumeDescriptor;
+    }
+
+    if (desc == NULL) {
+        return  -EINVAL;
+    }
+
+    memcpy(pDescriptor, desc, sizeof(effect_descriptor_t));
+
+    return 0;
+} /* end EffectGetDescriptor */
+
 void LvmGlobalBundle_init(){
     LOGV("\tLvmGlobalBundle_init start");
     for(int i=0; i<LVM_MAX_SESSIONS; i++){
@@ -493,16 +521,16 @@
     LOGV("\tLvmBundle_init start");
 
     pContext->config.inputCfg.accessMode                    = EFFECT_BUFFER_ACCESS_READ;
-    pContext->config.inputCfg.channels                      = CHANNEL_STEREO;
-    pContext->config.inputCfg.format                        = SAMPLE_FORMAT_PCM_S15;
+    pContext->config.inputCfg.channels                      = AUDIO_CHANNEL_OUT_STEREO;
+    pContext->config.inputCfg.format                        = AUDIO_FORMAT_PCM_16_BIT;
     pContext->config.inputCfg.samplingRate                  = 44100;
     pContext->config.inputCfg.bufferProvider.getBuffer      = NULL;
     pContext->config.inputCfg.bufferProvider.releaseBuffer  = NULL;
     pContext->config.inputCfg.bufferProvider.cookie         = NULL;
     pContext->config.inputCfg.mask                          = EFFECT_CONFIG_ALL;
     pContext->config.outputCfg.accessMode                   = EFFECT_BUFFER_ACCESS_ACCUMULATE;
-    pContext->config.outputCfg.channels                     = CHANNEL_STEREO;
-    pContext->config.outputCfg.format                       = SAMPLE_FORMAT_PCM_S15;
+    pContext->config.outputCfg.channels                     = AUDIO_CHANNEL_OUT_STEREO;
+    pContext->config.outputCfg.format                       = AUDIO_FORMAT_PCM_16_BIT;
     pContext->config.outputCfg.samplingRate                 = 44100;
     pContext->config.outputCfg.bufferProvider.getBuffer     = NULL;
     pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
@@ -928,10 +956,10 @@
     CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
     CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
     CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
-    CHECK_ARG(pConfig->inputCfg.channels == CHANNEL_STEREO);
+    CHECK_ARG(pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO);
     CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
               || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
-    CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15);
+    CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT);
 
     memcpy(&pContext->config, pConfig, sizeof(effect_config_t));
 
@@ -2545,8 +2573,9 @@
 } // namespace
 } // namespace
 
+extern "C" {
 /* Effect Control Interface Implementation: Process */
-extern "C" int Effect_process(effect_interface_t     self,
+int Effect_process(effect_handle_t     self,
                               audio_buffer_t         *inBuffer,
                               audio_buffer_t         *outBuffer){
     EffectContext * pContext = (EffectContext *) self;
@@ -2666,7 +2695,7 @@
 }   /* end Effect_process */
 
 /* Effect Control Interface Implementation: Command */
-extern "C" int Effect_command(effect_interface_t  self,
+int Effect_command(effect_handle_t  self,
                               uint32_t            cmdCode,
                               uint32_t            cmdSize,
                               void                *pCmdData,
@@ -3016,11 +3045,11 @@
         case EFFECT_CMD_SET_DEVICE:
         {
             LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_DEVICE start");
-            audio_device_e device = *(audio_device_e *)pCmdData;
+            uint32_t device = *(uint32_t *)pCmdData;
 
             if(pContext->EffectType == LVM_BASS_BOOST){
-                if((device == DEVICE_SPEAKER)||(device == DEVICE_BLUETOOTH_SCO_CARKIT)||
-                   (device == DEVICE_BLUETOOTH_A2DP_SPEAKER)){
+                if((device == AUDIO_DEVICE_OUT_SPEAKER)||(device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)||
+                   (device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)){
                     LOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_BASS_BOOST %d",
                           *(int32_t *)pCmdData);
                     LOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_BAS_BOOST");
@@ -3051,8 +3080,8 @@
                 }
             }
             if(pContext->EffectType == LVM_VIRTUALIZER){
-                if((device == DEVICE_SPEAKER)||(device == DEVICE_BLUETOOTH_SCO_CARKIT)||
-                   (device == DEVICE_BLUETOOTH_A2DP_SPEAKER)){
+                if((device == AUDIO_DEVICE_OUT_SPEAKER)||(device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)||
+                   (device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)){
                     LOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_VIRTUALIZER %d",
                           *(int32_t *)pCmdData);
                     LOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_VIRTUALIZER");
@@ -3164,9 +3193,57 @@
     return 0;
 }    /* end Effect_command */
 
-// effect_interface_t interface implementation for effect
+/* Effect Control Interface Implementation: get_descriptor */
+int Effect_getDescriptor(effect_handle_t   self,
+                                    effect_descriptor_t *pDescriptor)
+{
+    EffectContext * pContext = (EffectContext *) self;
+    const effect_descriptor_t *desc;
+
+    if (pContext == NULL || pDescriptor == NULL) {
+        LOGV("Effect_getDescriptor() invalid param");
+        return -EINVAL;
+    }
+
+    switch(pContext->EffectType) {
+        case LVM_BASS_BOOST:
+            desc = &android::gBassBoostDescriptor;
+            break;
+        case LVM_VIRTUALIZER:
+            desc = &android::gVirtualizerDescriptor;
+            break;
+        case LVM_EQUALIZER:
+            desc = &android::gEqualizerDescriptor;
+            break;
+        case LVM_VOLUME:
+            desc = &android::gVolumeDescriptor;
+            break;
+        default:
+            return -EINVAL;
+    }
+
+    memcpy(pDescriptor, desc, sizeof(effect_descriptor_t));
+
+    return 0;
+}   /* end Effect_getDescriptor */
+
+// effect_handle_t interface implementation for effect
 const struct effect_interface_s gLvmEffectInterface = {
     Effect_process,
-    Effect_command
+    Effect_command,
+    Effect_getDescriptor
 };    /* end gLvmEffectInterface */
 
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+    tag : AUDIO_EFFECT_LIBRARY_TAG,
+    version : EFFECT_LIBRARY_API_VERSION,
+    name : "Effect Bundle Library",
+    implementor : "NXP Software Ltd.",
+    query_num_effects : android::EffectQueryNumberEffects,
+    query_effect : android::EffectQueryEffect,
+    create_effect : android::EffectCreate,
+    release_effect : android::EffectRelease,
+    get_descriptor : android::EffectGetDescriptor,
+};
+
+}
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 9097e20..2727375 100755
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -27,7 +27,7 @@
 #include <EffectReverb.h>
 #include <LVREV.h>
 
-// effect_interface_t interface implementation for reverb
+// effect_handle_t interface implementation for reverb
 extern "C" const struct effect_interface_s gReverbInterface;
 
 #define LVM_ERROR_CHECK(LvmStatus, callingFunc, calledFunc){\
@@ -77,7 +77,7 @@
 const effect_descriptor_t gAuxEnvReverbDescriptor = {
         { 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e } },
         { 0x4a387fc0, 0x8ab3, 0x11df, 0x8bad, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         EFFECT_FLAG_TYPE_AUXILIARY,
         LVREV_CUP_LOAD_ARM9E,
         LVREV_MEM_USAGE,
@@ -89,7 +89,7 @@
 static const effect_descriptor_t gInsertEnvReverbDescriptor = {
         {0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}},
         {0xc7a511a0, 0xa3bb, 0x11df, 0x860e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL,
         LVREV_CUP_LOAD_ARM9E,
         LVREV_MEM_USAGE,
@@ -101,7 +101,7 @@
 static const effect_descriptor_t gAuxPresetReverbDescriptor = {
         {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
         {0xf29a1400, 0xa3bb, 0x11df, 0x8ddc, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         EFFECT_FLAG_TYPE_AUXILIARY,
         LVREV_CUP_LOAD_ARM9E,
         LVREV_MEM_USAGE,
@@ -113,7 +113,7 @@
 static const effect_descriptor_t gInsertPresetReverbDescriptor = {
         {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
         {0x172cdf00, 0xa3bc, 0x11df, 0xa72f, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL,
         LVREV_CUP_LOAD_ARM9E,
         LVREV_MEM_USAGE,
@@ -192,7 +192,8 @@
     return 0;
 }     /* end EffectQueryNumberEffects */
 
-extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor){
+extern "C" int EffectQueryEffect(uint32_t index,
+                                 effect_descriptor_t *pDescriptor){
     LOGV("\n\tEffectQueryEffect start");
     LOGV("\tEffectQueryEffect processing index %d", index);
     if (pDescriptor == NULL){
@@ -211,7 +212,7 @@
 extern "C" int EffectCreate(effect_uuid_t       *uuid,
                             int32_t             sessionId,
                             int32_t             ioId,
-                            effect_interface_t  *pInterface){
+                            effect_handle_t  *pHandle){
     int ret;
     int i;
     int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
@@ -219,7 +220,7 @@
 
     LOGV("\t\nEffectCreate start");
 
-    if (pInterface == NULL || uuid == NULL){
+    if (pHandle == NULL || uuid == NULL){
         LOGV("\tLVM_ERROR : EffectCreate() called with NULL pointer");
         return -EINVAL;
     }
@@ -270,7 +271,7 @@
         return ret;
     }
 
-    *pInterface = (effect_interface_t)pContext;
+    *pHandle = (effect_handle_t)pContext;
 
     #ifdef LVM_PCM
     pContext->PcmInPtr = NULL;
@@ -295,10 +296,10 @@
     return 0;
 } /* end EffectCreate */
 
-extern "C" int EffectRelease(effect_interface_t interface){
-    ReverbContext * pContext = (ReverbContext *)interface;
+extern "C" int EffectRelease(effect_handle_t handle){
+    ReverbContext * pContext = (ReverbContext *)handle;
 
-    LOGV("\tEffectRelease %p", interface);
+    LOGV("\tEffectRelease %p", handle);
     if (pContext == NULL){
         LOGV("\tLVM_ERROR : EffectRelease called with NULL pointer");
         return -EINVAL;
@@ -315,6 +316,28 @@
     return 0;
 } /* end EffectRelease */
 
+extern "C" int EffectGetDescriptor(effect_uuid_t       *uuid,
+                                   effect_descriptor_t *pDescriptor) {
+    int i;
+    int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
+
+    if (pDescriptor == NULL || uuid == NULL){
+        LOGV("EffectGetDescriptor() called with NULL pointer");
+        return -EINVAL;
+    }
+
+    for (i = 0; i < length; i++) {
+        if (memcmp(uuid, &gDescriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) {
+            memcpy(pDescriptor, gDescriptors[i], sizeof(effect_descriptor_t));
+            LOGV("EffectGetDescriptor - UUID matched Reverb type %d, UUID = %x",
+                 i, gDescriptors[i]->uuid.timeLow);
+            return 0;
+        }
+    }
+
+    return -EINVAL;
+} /* end EffectGetDescriptor */
+
 /* local functions */
 #define CHECK_ARG(cond) {                     \
     if (!(cond)) {                            \
@@ -418,9 +441,9 @@
 
 
     // Check that the input is either mono or stereo
-    if (pContext->config.inputCfg.channels == CHANNEL_STEREO) {
+    if (pContext->config.inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO) {
         samplesPerFrame = 2;
-    } else if (pContext->config.inputCfg.channels != CHANNEL_MONO) {
+    } else if (pContext->config.inputCfg.channels != AUDIO_CHANNEL_OUT_MONO) {
         LOGV("\tLVREV_ERROR : process invalid PCM format");
         return -EINVAL;
     }
@@ -608,12 +631,12 @@
 
     CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
     CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
-    CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == CHANNEL_MONO) ||
-              ((!pContext->auxiliary) && pConfig->inputCfg.channels == CHANNEL_STEREO));
-    CHECK_ARG(pConfig->outputCfg.channels == CHANNEL_STEREO);
+    CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) ||
+              ((!pContext->auxiliary) && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO));
+    CHECK_ARG(pConfig->outputCfg.channels == AUDIO_CHANNEL_OUT_STEREO);
     CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
               || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
-    CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15);
+    CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT);
 
     if(pConfig->inputCfg.samplingRate != 44100){
         return -EINVAL;
@@ -700,20 +723,20 @@
 
     pContext->config.inputCfg.accessMode                    = EFFECT_BUFFER_ACCESS_READ;
     if (pContext->auxiliary) {
-        pContext->config.inputCfg.channels                  = CHANNEL_MONO;
+        pContext->config.inputCfg.channels                  = AUDIO_CHANNEL_OUT_MONO;
     } else {
-        pContext->config.inputCfg.channels                  = CHANNEL_STEREO;
+        pContext->config.inputCfg.channels                  = AUDIO_CHANNEL_OUT_STEREO;
     }
 
-    pContext->config.inputCfg.format                        = SAMPLE_FORMAT_PCM_S15;
+    pContext->config.inputCfg.format                        = AUDIO_FORMAT_PCM_16_BIT;
     pContext->config.inputCfg.samplingRate                  = 44100;
     pContext->config.inputCfg.bufferProvider.getBuffer      = NULL;
     pContext->config.inputCfg.bufferProvider.releaseBuffer  = NULL;
     pContext->config.inputCfg.bufferProvider.cookie         = NULL;
     pContext->config.inputCfg.mask                          = EFFECT_CONFIG_ALL;
     pContext->config.outputCfg.accessMode                   = EFFECT_BUFFER_ACCESS_ACCUMULATE;
-    pContext->config.outputCfg.channels                     = CHANNEL_STEREO;
-    pContext->config.outputCfg.format                       = SAMPLE_FORMAT_PCM_S15;
+    pContext->config.outputCfg.channels                     = AUDIO_CHANNEL_OUT_STEREO;
+    pContext->config.outputCfg.format                       = AUDIO_FORMAT_PCM_16_BIT;
     pContext->config.outputCfg.samplingRate                 = 44100;
     pContext->config.outputCfg.bufferProvider.getBuffer     = NULL;
     pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
@@ -800,7 +823,7 @@
     params.OperatingMode  = LVM_MODE_ON;
     params.SampleRate     = LVM_FS_44100;
 
-    if(pContext->config.inputCfg.channels == CHANNEL_MONO){
+    if(pContext->config.inputCfg.channels == AUDIO_CHANNEL_OUT_MONO){
         params.SourceFormat   = LVM_MONO;
     } else {
         params.SourceFormat   = LVM_STEREO;
@@ -1832,8 +1855,9 @@
 } // namespace
 } // namespace
 
+extern "C" {
 /* Effect Control Interface Implementation: Process */
-extern "C" int Reverb_process(effect_interface_t   self,
+int Reverb_process(effect_handle_t   self,
                                  audio_buffer_t         *inBuffer,
                                  audio_buffer_t         *outBuffer){
     android::ReverbContext * pContext = (android::ReverbContext *) self;
@@ -1868,7 +1892,7 @@
 }   /* end Reverb_process */
 
 /* Effect Control Interface Implementation: Command */
-extern "C" int Reverb_command(effect_interface_t  self,
+int Reverb_command(effect_handle_t  self,
                               uint32_t            cmdCode,
                               uint32_t            cmdSize,
                               void                *pCmdData,
@@ -2075,9 +2099,54 @@
     return 0;
 }    /* end Reverb_command */
 
-// effect_interface_t interface implementation for Reverb effect
+/* Effect Control Interface Implementation: get_descriptor */
+int Reverb_getDescriptor(effect_handle_t   self,
+                                    effect_descriptor_t *pDescriptor)
+{
+    android::ReverbContext * pContext = (android::ReverbContext *)self;
+    const effect_descriptor_t *desc;
+
+    if (pContext == NULL || pDescriptor == NULL) {
+        LOGV("Reverb_getDescriptor() invalid param");
+        return -EINVAL;
+    }
+
+    if (pContext->auxiliary) {
+        if (pContext->preset) {
+            desc = &android::gAuxPresetReverbDescriptor;
+        } else {
+            desc = &android::gAuxEnvReverbDescriptor;
+        }
+    } else {
+        if (pContext->preset) {
+            desc = &android::gInsertPresetReverbDescriptor;
+        } else {
+            desc = &android::gInsertEnvReverbDescriptor;
+        }
+    }
+
+    memcpy(pDescriptor, desc, sizeof(effect_descriptor_t));
+
+    return 0;
+}   /* end Reverb_getDescriptor */
+
+// effect_handle_t interface implementation for Reverb effect
 const struct effect_interface_s gReverbInterface = {
     Reverb_process,
-    Reverb_command
+    Reverb_command,
+    Reverb_getDescriptor
 };    /* end gReverbInterface */
 
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+    tag : AUDIO_EFFECT_LIBRARY_TAG,
+    version : EFFECT_LIBRARY_API_VERSION,
+    name : "Reverb Library",
+    implementor : "NXP Software Ltd.",
+    query_num_effects : android::EffectQueryNumberEffects,
+    query_effect : android::EffectQueryEffect,
+    create_effect : android::EffectCreate,
+    release_effect : android::EffectRelease,
+    get_descriptor : android::EffectGetDescriptor,
+};
+
+}
diff --git a/media/libeffects/testlibs/Android.mk_ b/media/libeffects/testlibs/Android.mk_
index 9ba71ed..98d477b 100644
--- a/media/libeffects/testlibs/Android.mk_
+++ b/media/libeffects/testlibs/Android.mk_
@@ -25,7 +25,7 @@
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, graphics corecg)
 
-LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
 
@@ -60,7 +60,7 @@
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, graphics corecg)
 
-LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
 
diff --git a/media/libeffects/testlibs/AudioFormatAdapter.h b/media/libeffects/testlibs/AudioFormatAdapter.h
index d93ebe9..41f1810 100644
--- a/media/libeffects/testlibs/AudioFormatAdapter.h
+++ b/media/libeffects/testlibs/AudioFormatAdapter.h
@@ -18,7 +18,7 @@
 #ifndef AUDIOFORMATADAPTER_H_
 #define AUDIOFORMATADAPTER_H_
 
-#include <media/EffectApi.h>
+#include <hardware/audio_effect.h>
 
 
 #define min(x,y) (((x) < (y)) ? (x) : (y))
@@ -75,7 +75,7 @@
         while (numSamples > 0) {
             uint32_t numSamplesIter = min(numSamples, mMaxSamplesPerCall);
             uint32_t nSamplesChannels = numSamplesIter * mNumChannels;
-            if (mPcmFormat == SAMPLE_FORMAT_PCM_S7_24) {
+            if (mPcmFormat == AUDIO_FORMAT_PCM_8_24_BIT) {
                 if (mBehavior == EFFECT_BUFFER_ACCESS_WRITE) {
                     mpProcessor->process(
                         reinterpret_cast<const audio_sample_t *> (pIn),
@@ -125,7 +125,7 @@
     //              sample.
     // numSamples   The number of single-channel samples to process.
     void ConvertInput(const void *& pIn, uint32_t numSamples) {
-        if (mPcmFormat == SAMPLE_FORMAT_PCM_S15) {
+        if (mPcmFormat == AUDIO_FORMAT_PCM_16_BIT) {
             const int16_t * pIn16 = reinterpret_cast<const int16_t *>(pIn);
             audio_sample_t * pOut = mBuffer;
             while (numSamples-- > 0) {
@@ -143,7 +143,7 @@
     //              When function exist will point to the next output sample.
     // numSamples   The number of single-channel samples to process.
     void ConvertOutput(void *& pOut, uint32_t numSamples) {
-        if (mPcmFormat == SAMPLE_FORMAT_PCM_S15) {
+        if (mPcmFormat == AUDIO_FORMAT_PCM_16_BIT) {
             const audio_sample_t * pIn = mBuffer;
             int16_t * pOut16 = reinterpret_cast<int16_t *>(pOut);
             if (mBehavior == EFFECT_BUFFER_ACCESS_WRITE) {
diff --git a/media/libeffects/testlibs/EffectEqualizer.cpp b/media/libeffects/testlibs/EffectEqualizer.cpp
index f8e4357..43dfa82 100644
--- a/media/libeffects/testlibs/EffectEqualizer.cpp
+++ b/media/libeffects/testlibs/EffectEqualizer.cpp
@@ -28,7 +28,7 @@
 #include "AudioFormatAdapter.h"
 #include <media/EffectEqualizerApi.h>
 
-// effect_interface_t interface implementation for equalizer effect
+// effect_handle_t interface implementation for equalizer effect
 extern "C" const struct effect_interface_s gEqualizerInterface;
 
 enum equalizer_state_e {
@@ -44,12 +44,12 @@
 const effect_descriptor_t gEqualizerDescriptor = {
         {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
         {0xe25aa840, 0x543b, 0x11df, 0x98a5, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
         0, // TODO
         1,
         "Graphic Equalizer",
-        "Google Inc.",
+        "The Android Open Source Project",
 };
 
 /////////////////// BEGIN EQ PRESETS ///////////////////////////////////////////
@@ -127,7 +127,8 @@
     return 0;
 } /* end EffectQueryNumberEffects */
 
-extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) {
+extern "C" int EffectQueryEffect(uint32_t index,
+                                 effect_descriptor_t *pDescriptor) {
     if (pDescriptor == NULL) {
         return -EINVAL;
     }
@@ -139,15 +140,15 @@
 } /* end EffectQueryNext */
 
 extern "C" int EffectCreate(effect_uuid_t *uuid,
-        int32_t sessionId,
-        int32_t ioId,
-        effect_interface_t *pInterface) {
+                            int32_t sessionId,
+                            int32_t ioId,
+                            effect_handle_t *pHandle) {
     int ret;
     int i;
 
     LOGV("EffectLibCreateEffect start");
 
-    if (pInterface == NULL || uuid == NULL) {
+    if (pHandle == NULL || uuid == NULL) {
         return -EINVAL;
     }
 
@@ -168,19 +169,20 @@
         return ret;
     }
 
-    *pInterface = (effect_interface_t)pContext;
+    *pHandle = (effect_handle_t)pContext;
     pContext->state = EQUALIZER_STATE_INITIALIZED;
 
-    LOGV("EffectLibCreateEffect %p, size %d", pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext));
+    LOGV("EffectLibCreateEffect %p, size %d",
+         pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext));
 
     return 0;
 
 } /* end EffectCreate */
 
-extern "C" int EffectRelease(effect_interface_t interface) {
-    EqualizerContext * pContext = (EqualizerContext *)interface;
+extern "C" int EffectRelease(effect_handle_t handle) {
+    EqualizerContext * pContext = (EqualizerContext *)handle;
 
-    LOGV("EffectLibReleaseEffect %p", interface);
+    LOGV("EffectLibReleaseEffect %p", handle);
     if (pContext == NULL) {
         return -EINVAL;
     }
@@ -192,6 +194,22 @@
     return 0;
 } /* end EffectRelease */
 
+extern "C" int EffectGetDescriptor(effect_uuid_t       *uuid,
+                                   effect_descriptor_t *pDescriptor) {
+
+    if (pDescriptor == NULL || uuid == NULL){
+        LOGV("EffectGetDescriptor() called with NULL pointer");
+        return -EINVAL;
+    }
+
+    if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+        memcpy(pDescriptor, &gEqualizerDescriptor, sizeof(effect_descriptor_t));
+        return 0;
+    }
+
+    return  -EINVAL;
+} /* end EffectGetDescriptor */
+
 
 //
 //--- local functions
@@ -228,14 +246,15 @@
     CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
     CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
     CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
-    CHECK_ARG((pConfig->inputCfg.channels == CHANNEL_MONO) || (pConfig->inputCfg.channels == CHANNEL_STEREO));
+    CHECK_ARG((pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) ||
+              (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO));
     CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
               || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
-    CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S7_24
-              || pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15);
+    CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_8_24_BIT
+              || pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT);
 
     int channelCount;
-    if (pConfig->inputCfg.channels == CHANNEL_MONO) {
+    if (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) {
         channelCount = 1;
     } else {
         channelCount = 2;
@@ -281,16 +300,16 @@
     }
 
     pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
-    pContext->config.inputCfg.channels = CHANNEL_STEREO;
-    pContext->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
+    pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+    pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
     pContext->config.inputCfg.samplingRate = 44100;
     pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
     pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
     pContext->config.inputCfg.bufferProvider.cookie = NULL;
     pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
     pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
-    pContext->config.outputCfg.channels = CHANNEL_STEREO;
-    pContext->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
+    pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+    pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
     pContext->config.outputCfg.samplingRate = 44100;
     pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
     pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
@@ -402,7 +421,8 @@
     case EQ_PARAM_LEVEL_RANGE:
         *(int16_t *)pValue = -9600;
         *((int16_t *)pValue + 1) = 4800;
-        LOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d", *(int32_t *)pValue, *((int32_t *)pValue + 1));
+        LOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d",
+             *(int32_t *)pValue, *((int32_t *)pValue + 1));
         break;
 
     case EQ_PARAM_BAND_LEVEL:
@@ -412,7 +432,8 @@
             break;
         }
         *(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2);
-        LOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", param2, *(int32_t *)pValue);
+        LOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d",
+             param2, *(int32_t *)pValue);
         break;
 
     case EQ_PARAM_CENTER_FREQ:
@@ -422,7 +443,8 @@
             break;
         }
         *(int32_t *)pValue = pEqualizer->getFrequency(param2);
-        LOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d", param2, *(int32_t *)pValue);
+        LOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d",
+             param2, *(int32_t *)pValue);
         break;
 
     case EQ_PARAM_BAND_FREQ_RANGE:
@@ -432,13 +454,15 @@
             break;
         }
         pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1));
-        LOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
+        LOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d",
+             param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
         break;
 
     case EQ_PARAM_GET_BAND:
         param2 = *pParam;
         *(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2);
-        LOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d", param2, *(int32_t *)pValue);
+        LOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d",
+             param2, *(int32_t *)pValue);
         break;
 
     case EQ_PARAM_CUR_PRESET:
@@ -461,7 +485,8 @@
         strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1);
         name[*pValueSize - 1] = 0;
         *pValueSize = strlen(name) + 1;
-        LOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", param2, gEqualizerPresets[param2].name, *pValueSize);
+        LOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d",
+             param2, gEqualizerPresets[param2].name, *pValueSize);
         break;
 
     case EQ_PARAM_PROPERTIES: {
@@ -571,7 +596,7 @@
 //--- Effect Control Interface Implementation
 //
 
-extern "C" int Equalizer_process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
+extern "C" int Equalizer_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
 {
     android::EqualizerContext * pContext = (android::EqualizerContext *) self;
 
@@ -596,7 +621,7 @@
     return 0;
 }   // end Equalizer_process
 
-extern "C" int Equalizer_command(effect_interface_t self, uint32_t cmdCode, uint32_t cmdSize,
+extern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
         void *pCmdData, uint32_t *replySize, void *pReplyData) {
 
     android::EqualizerContext * pContext = (android::EqualizerContext *) self;
@@ -647,7 +672,8 @@
 
         } break;
     case EFFECT_CMD_SET_PARAM: {
-        LOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData);
+        LOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p",
+             cmdSize, pCmdData, *replySize, pReplyData);
         if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
             pReplyData == NULL || *replySize != sizeof(int32_t)) {
             return -EINVAL;
@@ -690,10 +716,37 @@
     return 0;
 }
 
-// effect_interface_t interface implementation for equalizer effect
+extern "C" int Equalizer_getDescriptor(effect_handle_t   self,
+                                    effect_descriptor_t *pDescriptor)
+{
+    android::EqualizerContext * pContext = (android::EqualizerContext *) self;
+
+    if (pContext == NULL || pDescriptor == NULL) {
+        LOGV("Equalizer_getDescriptor() invalid param");
+        return -EINVAL;
+    }
+
+    memcpy(pDescriptor, &android::gEqualizerDescriptor, sizeof(effect_descriptor_t));
+
+    return 0;
+}
+
+// effect_handle_t interface implementation for equalizer effect
 const struct effect_interface_s gEqualizerInterface = {
         Equalizer_process,
-        Equalizer_command
+        Equalizer_command,
+        Equalizer_getDescriptor
 };
 
 
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+    tag : AUDIO_EFFECT_LIBRARY_TAG,
+    version : EFFECT_LIBRARY_API_VERSION,
+    name : "Test Equalizer Library",
+    implementor : "The Android Open Source Project",
+    query_num_effects : android::EffectQueryNumberEffects,
+    query_effect : android::EffectQueryEffect,
+    create_effect : android::EffectCreate,
+    release_effect : android::EffectRelease,
+    get_descriptor : android::EffectGetDescriptor,
+};
diff --git a/media/libeffects/testlibs/EffectReverb.c b/media/libeffects/testlibs/EffectReverb.c
index 3eb8b2c..02762c9 100644
--- a/media/libeffects/testlibs/EffectReverb.c
+++ b/media/libeffects/testlibs/EffectReverb.c
@@ -23,59 +23,60 @@
 #include "EffectReverb.h"
 #include "EffectsMath.h"
 
-// effect_interface_t interface implementation for reverb effect
+// effect_handle_t interface implementation for reverb effect
 const struct effect_interface_s gReverbInterface = {
         Reverb_Process,
-        Reverb_Command
+        Reverb_Command,
+        Reverb_GetDescriptor
 };
 
 // Google auxiliary environmental reverb UUID: 1f0ae2e0-4ef7-11df-bc09-0002a5d5c51b
 static const effect_descriptor_t gAuxEnvReverbDescriptor = {
         {0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}},
         {0x1f0ae2e0, 0x4ef7, 0x11df, 0xbc09, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         // flags other than EFFECT_FLAG_TYPE_AUXILIARY set for test purpose
         EFFECT_FLAG_TYPE_AUXILIARY | EFFECT_FLAG_DEVICE_IND | EFFECT_FLAG_AUDIO_MODE_IND,
         0, // TODO
         33,
         "Aux Environmental Reverb",
-        "Google Inc."
+        "The Android Open Source Project"
 };
 
 // Google insert environmental reverb UUID: aa476040-6342-11df-91a4-0002a5d5c51b
 static const effect_descriptor_t gInsertEnvReverbDescriptor = {
         {0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}},
         {0xaa476040, 0x6342, 0x11df, 0x91a4, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST,
         0, // TODO
         33,
         "Insert Environmental reverb",
-        "Google Inc."
+        "The Android Open Source Project"
 };
 
 // Google auxiliary preset reverb UUID: 63909320-53a6-11df-bdbd-0002a5d5c51b
 static const effect_descriptor_t gAuxPresetReverbDescriptor = {
         {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
         {0x63909320, 0x53a6, 0x11df, 0xbdbd, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         EFFECT_FLAG_TYPE_AUXILIARY,
         0, // TODO
         33,
         "Aux Preset Reverb",
-        "Google Inc."
+        "The Android Open Source Project"
 };
 
 // Google insert preset reverb UUID: d93dc6a0-6342-11df-b128-0002a5d5c51b
 static const effect_descriptor_t gInsertPresetReverbDescriptor = {
         {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
         {0xd93dc6a0, 0x6342, 0x11df, 0xb128, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST,
         0, // TODO
         33,
         "Insert Preset Reverb",
-        "Google Inc."
+        "The Android Open Source Project"
 };
 
 // gDescriptors contains pointers to all defined effect descriptor in this library
@@ -112,7 +113,7 @@
 int EffectCreate(effect_uuid_t *uuid,
         int32_t sessionId,
         int32_t ioId,
-        effect_interface_t *pInterface) {
+        effect_handle_t *pHandle) {
     int ret;
     int i;
     reverb_module_t *module;
@@ -122,7 +123,7 @@
 
     LOGV("EffectLibCreateEffect start");
 
-    if (pInterface == NULL || uuid == NULL) {
+    if (pHandle == NULL || uuid == NULL) {
         return -EINVAL;
     }
 
@@ -157,7 +158,7 @@
         return ret;
     }
 
-    *pInterface = (effect_interface_t) module;
+    *pHandle = (effect_handle_t) module;
 
     module->context.mState = REVERB_STATE_INITIALIZED;
 
@@ -166,11 +167,11 @@
     return 0;
 }
 
-int EffectRelease(effect_interface_t interface) {
-    reverb_module_t *pRvbModule = (reverb_module_t *)interface;
+int EffectRelease(effect_handle_t handle) {
+    reverb_module_t *pRvbModule = (reverb_module_t *)handle;
 
-    LOGV("EffectLibReleaseEffect %p", interface);
-    if (interface == NULL) {
+    LOGV("EffectLibReleaseEffect %p", handle);
+    if (handle == NULL) {
         return -EINVAL;
     }
 
@@ -180,10 +181,31 @@
     return 0;
 }
 
+int EffectGetDescriptor(effect_uuid_t       *uuid,
+                        effect_descriptor_t *pDescriptor) {
+    int i;
+    int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
+
+    if (pDescriptor == NULL || uuid == NULL){
+        LOGV("EffectGetDescriptor() called with NULL pointer");
+        return -EINVAL;
+    }
+
+    for (i = 0; i < length; i++) {
+        if (memcmp(uuid, &gDescriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) {
+            memcpy(pDescriptor, gDescriptors[i], sizeof(effect_descriptor_t));
+            LOGV("EffectGetDescriptor - UUID matched Reverb type %d, UUID = %x",
+                 i, gDescriptors[i]->uuid.timeLow);
+            return 0;
+        }
+    }
+
+    return -EINVAL;
+} /* end EffectGetDescriptor */
 
 /*--- Effect Control Interface Implementation ---*/
 
-static int Reverb_Process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) {
+static int Reverb_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) {
     reverb_object_t *pReverb;
     int16_t *pSrc, *pDst;
     reverb_module_t *pRvbModule = (reverb_module_t *)self;
@@ -270,7 +292,7 @@
 }
 
 
-static int Reverb_Command(effect_interface_t self, uint32_t cmdCode, uint32_t cmdSize,
+static int Reverb_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
         void *pCmdData, uint32_t *replySize, void *pReplyData) {
     reverb_module_t *pRvbModule = (reverb_module_t *) self;
     reverb_object_t *pReverb;
@@ -383,6 +405,38 @@
     return 0;
 }
 
+int Reverb_GetDescriptor(effect_handle_t   self,
+                                    effect_descriptor_t *pDescriptor)
+{
+    reverb_module_t *pRvbModule = (reverb_module_t *) self;
+    reverb_object_t *pReverb;
+    const effect_descriptor_t *desc;
+
+    if (pRvbModule == NULL ||
+            pRvbModule->context.mState == REVERB_STATE_UNINITIALIZED) {
+        return -EINVAL;
+    }
+
+    pReverb = (reverb_object_t*) &pRvbModule->context;
+
+    if (pReverb->m_Aux) {
+        if (pReverb->m_Preset) {
+            desc = &gAuxPresetReverbDescriptor;
+        } else {
+            desc = &gAuxEnvReverbDescriptor;
+        }
+    } else {
+        if (pReverb->m_Preset) {
+            desc = &gInsertPresetReverbDescriptor;
+        } else {
+            desc = &gInsertEnvReverbDescriptor;
+        }
+    }
+
+    memcpy(pDescriptor, desc, sizeof(effect_descriptor_t));
+
+    return 0;
+}   /* end Reverb_getDescriptor */
 
 /*----------------------------------------------------------------------------
  * Reverb internal functions
@@ -418,19 +472,19 @@
 
     pRvbModule->config.inputCfg.samplingRate = 44100;
     if (aux) {
-        pRvbModule->config.inputCfg.channels = CHANNEL_MONO;
+        pRvbModule->config.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO;
     } else {
-        pRvbModule->config.inputCfg.channels = CHANNEL_STEREO;
+        pRvbModule->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
     }
-    pRvbModule->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
+    pRvbModule->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
     pRvbModule->config.inputCfg.bufferProvider.getBuffer = NULL;
     pRvbModule->config.inputCfg.bufferProvider.releaseBuffer = NULL;
     pRvbModule->config.inputCfg.bufferProvider.cookie = NULL;
     pRvbModule->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
     pRvbModule->config.inputCfg.mask = EFFECT_CONFIG_ALL;
     pRvbModule->config.outputCfg.samplingRate = 44100;
-    pRvbModule->config.outputCfg.channels = CHANNEL_STEREO;
-    pRvbModule->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
+    pRvbModule->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+    pRvbModule->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
     pRvbModule->config.outputCfg.bufferProvider.getBuffer = NULL;
     pRvbModule->config.outputCfg.bufferProvider.releaseBuffer = NULL;
     pRvbModule->config.outputCfg.bufferProvider.cookie = NULL;
@@ -474,13 +528,13 @@
     if (pConfig->inputCfg.samplingRate
         != pConfig->outputCfg.samplingRate
         || pConfig->outputCfg.channels != OUTPUT_CHANNELS
-        || pConfig->inputCfg.format != SAMPLE_FORMAT_PCM_S15
-        || pConfig->outputCfg.format != SAMPLE_FORMAT_PCM_S15) {
+        || pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT
+        || pConfig->outputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
         LOGV("Reverb_Configure invalid config");
         return -EINVAL;
     }
-    if ((pReverb->m_Aux && (pConfig->inputCfg.channels != CHANNEL_MONO)) ||
-        (!pReverb->m_Aux && (pConfig->inputCfg.channels != CHANNEL_STEREO))) {
+    if ((pReverb->m_Aux && (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_MONO)) ||
+        (!pReverb->m_Aux && (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO))) {
         LOGV("Reverb_Configure invalid config");
         return -EINVAL;
     }
@@ -2133,3 +2187,15 @@
 
     return 0;
 }
+
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+    .tag = AUDIO_EFFECT_LIBRARY_TAG,
+    .version = EFFECT_LIBRARY_API_VERSION,
+    .name = "Test Equalizer Library",
+    .implementor = "The Android Open Source Project",
+    .query_num_effects = EffectQueryNumberEffects,
+    .query_effect = EffectQueryEffect,
+    .create_effect = EffectCreate,
+    .release_effect = EffectRelease,
+    .get_descriptor = EffectGetDescriptor,
+};
diff --git a/media/libeffects/testlibs/EffectReverb.h b/media/libeffects/testlibs/EffectReverb.h
index dbcd192..a239814 100644
--- a/media/libeffects/testlibs/EffectReverb.h
+++ b/media/libeffects/testlibs/EffectReverb.h
@@ -40,7 +40,7 @@
                                             )
 
 #define NUM_OUTPUT_CHANNELS 2
-#define OUTPUT_CHANNELS CHANNEL_STEREO
+#define OUTPUT_CHANNELS AUDIO_CHANNEL_OUT_STEREO
 
 #define REVERB_BUFFER_SIZE_IN_SAMPLES_MAX   16384
 
@@ -306,19 +306,22 @@
 int EffectCreate(effect_uuid_t *effectUID,
                  int32_t sessionId,
                  int32_t ioId,
-                 effect_interface_t *pInterface);
-int EffectRelease(effect_interface_t interface);
+                 effect_handle_t *pHandle);
+int EffectRelease(effect_handle_t handle);
+int EffectGetDescriptor(effect_uuid_t       *uuid,
+                        effect_descriptor_t *pDescriptor);
 
-static int Reverb_Process(effect_interface_t self,
+static int Reverb_Process(effect_handle_t self,
                           audio_buffer_t *inBuffer,
                           audio_buffer_t *outBuffer);
-static int Reverb_Command(effect_interface_t self,
+static int Reverb_Command(effect_handle_t self,
                           uint32_t cmdCode,
                           uint32_t cmdSize,
                           void *pCmdData,
                           uint32_t *replySize,
                           void *pReplyData);
-
+static int Reverb_GetDescriptor(effect_handle_t   self,
+                                effect_descriptor_t *pDescriptor);
 
 /*------------------------------------
  * internal functions
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index c957dba..80d1f69 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -23,21 +23,22 @@
 #include <new>
 #include <media/EffectVisualizerApi.h>
 
-namespace android {
 
-// effect_interface_t interface implementation for visualizer effect
-extern "C" const struct effect_interface_s gVisualizerInterface;
+extern "C" {
+
+// effect_handle_t interface implementation for visualizer effect
+extern const struct effect_interface_s gVisualizerInterface;
 
 // Google Visualizer UUID: d069d9e0-8329-11df-9168-0002a5d5c51b
 const effect_descriptor_t gVisualizerDescriptor = {
         {0xe46b26a0, 0xdddd, 0x11db, 0x8afd, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
         {0xd069d9e0, 0x8329, 0x11df, 0x9168, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
-        EFFECT_API_VERSION,
+        EFFECT_CONTROL_API_VERSION,
         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST),
         0, // TODO
         1,
         "Visualizer",
-        "Google Inc.",
+        "The Android Open Source Project",
 };
 
 enum visualizer_state_e {
@@ -90,10 +91,10 @@
     if (pConfig->inputCfg.samplingRate != pConfig->outputCfg.samplingRate) return -EINVAL;
     if (pConfig->inputCfg.channels != pConfig->outputCfg.channels) return -EINVAL;
     if (pConfig->inputCfg.format != pConfig->outputCfg.format) return -EINVAL;
-    if (pConfig->inputCfg.channels != CHANNEL_STEREO) return -EINVAL;
+    if (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) return -EINVAL;
     if (pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_WRITE &&
             pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_ACCUMULATE) return -EINVAL;
-    if (pConfig->inputCfg.format != SAMPLE_FORMAT_PCM_S15) return -EINVAL;
+    if (pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
 
     memcpy(&pContext->mConfig, pConfig, sizeof(effect_config_t));
 
@@ -118,16 +119,16 @@
 int Visualizer_init(VisualizerContext *pContext)
 {
     pContext->mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
-    pContext->mConfig.inputCfg.channels = CHANNEL_STEREO;
-    pContext->mConfig.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
+    pContext->mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+    pContext->mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
     pContext->mConfig.inputCfg.samplingRate = 44100;
     pContext->mConfig.inputCfg.bufferProvider.getBuffer = NULL;
     pContext->mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
     pContext->mConfig.inputCfg.bufferProvider.cookie = NULL;
     pContext->mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
     pContext->mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
-    pContext->mConfig.outputCfg.channels = CHANNEL_STEREO;
-    pContext->mConfig.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
+    pContext->mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+    pContext->mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
     pContext->mConfig.outputCfg.samplingRate = 44100;
     pContext->mConfig.outputCfg.bufferProvider.getBuffer = NULL;
     pContext->mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
@@ -145,12 +146,13 @@
 //--- Effect Library Interface Implementation
 //
 
-extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects) {
+int VisualizerLib_QueryNumberEffects(uint32_t *pNumEffects) {
     *pNumEffects = 1;
     return 0;
 }
 
-extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) {
+int VisualizerLib_QueryEffect(uint32_t index,
+                              effect_descriptor_t *pDescriptor) {
     if (pDescriptor == NULL) {
         return -EINVAL;
     }
@@ -161,14 +163,14 @@
     return 0;
 }
 
-extern "C" int EffectCreate(effect_uuid_t *uuid,
-        int32_t sessionId,
-        int32_t ioId,
-        effect_interface_t *pInterface) {
+int VisualizerLib_Create(effect_uuid_t *uuid,
+                         int32_t sessionId,
+                         int32_t ioId,
+                         effect_handle_t *pHandle) {
     int ret;
     int i;
 
-    if (pInterface == NULL || uuid == NULL) {
+    if (pHandle == NULL || uuid == NULL) {
         return -EINVAL;
     }
 
@@ -183,25 +185,25 @@
 
     ret = Visualizer_init(pContext);
     if (ret < 0) {
-        LOGW("EffectCreate() init failed");
+        LOGW("VisualizerLib_Create() init failed");
         delete pContext;
         return ret;
     }
 
-    *pInterface = (effect_interface_t)pContext;
+    *pHandle = (effect_handle_t)pContext;
 
     pContext->mState = VISUALIZER_STATE_INITIALIZED;
 
-    LOGV("EffectCreate %p", pContext);
+    LOGV("VisualizerLib_Create %p", pContext);
 
     return 0;
 
 }
 
-extern "C" int EffectRelease(effect_interface_t interface) {
-    VisualizerContext * pContext = (VisualizerContext *)interface;
+int VisualizerLib_Release(effect_handle_t handle) {
+    VisualizerContext * pContext = (VisualizerContext *)handle;
 
-    LOGV("EffectRelease %p", interface);
+    LOGV("VisualizerLib_Release %p", handle);
     if (pContext == NULL) {
         return -EINVAL;
     }
@@ -211,6 +213,22 @@
     return 0;
 }
 
+int VisualizerLib_GetDescriptor(effect_uuid_t       *uuid,
+                                effect_descriptor_t *pDescriptor) {
+
+    if (pDescriptor == NULL || uuid == NULL){
+        LOGV("VisualizerLib_GetDescriptor() called with NULL pointer");
+        return -EINVAL;
+    }
+
+    if (memcmp(uuid, &gVisualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+        memcpy(pDescriptor, &gVisualizerDescriptor, sizeof(effect_descriptor_t));
+        return 0;
+    }
+
+    return  -EINVAL;
+} /* end VisualizerLib_GetDescriptor */
+
 //
 //--- Effect Control Interface Implementation
 //
@@ -222,10 +240,10 @@
     return sample;
 }
 
-extern "C" int Visualizer_process(
-        effect_interface_t self,audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
+int Visualizer_process(
+        effect_handle_t self,audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
 {
-    android::VisualizerContext * pContext = (android::VisualizerContext *)self;
+    VisualizerContext * pContext = (VisualizerContext *)self;
 
     if (pContext == NULL) {
         return -EINVAL;
@@ -244,7 +262,7 @@
     // this gives more interesting captures for display.
     int32_t shift = 32;
     int len = inBuffer->frameCount * 2;
-    for (size_t i = 0; i < len; i++) {
+    for (int i = 0; i < len; i++) {
         int32_t smp = inBuffer->s16[i];
         if (smp < 0) smp = -smp - 1; // take care to keep the max negative in range
         int32_t clz = __builtin_clz(smp);
@@ -293,10 +311,10 @@
     return 0;
 }   // end Visualizer_process
 
-extern "C" int Visualizer_command(effect_interface_t self, uint32_t cmdCode, uint32_t cmdSize,
+int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
         void *pCmdData, uint32_t *replySize, void *pReplyData) {
 
-    android::VisualizerContext * pContext = (android::VisualizerContext *)self;
+    VisualizerContext * pContext = (VisualizerContext *)self;
     int retsize;
 
     if (pContext == NULL || pContext->mState == VISUALIZER_STATE_UNINITIALIZED) {
@@ -412,11 +430,40 @@
     return 0;
 }
 
-// effect_interface_t interface implementation for visualizer effect
+/* Effect Control Interface Implementation: get_descriptor */
+int Visualizer_getDescriptor(effect_handle_t   self,
+                                    effect_descriptor_t *pDescriptor)
+{
+    VisualizerContext * pContext = (VisualizerContext *) self;
+
+    if (pContext == NULL || pDescriptor == NULL) {
+        LOGV("Visualizer_getDescriptor() invalid param");
+        return -EINVAL;
+    }
+
+    memcpy(pDescriptor, &gVisualizerDescriptor, sizeof(effect_descriptor_t));
+
+    return 0;
+}   /* end Visualizer_getDescriptor */
+
+// effect_handle_t interface implementation for visualizer effect
 const struct effect_interface_s gVisualizerInterface = {
         Visualizer_process,
-        Visualizer_command
+        Visualizer_command,
+        Visualizer_getDescriptor
 };
 
-} // namespace
 
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+    tag : AUDIO_EFFECT_LIBRARY_TAG,
+    version : EFFECT_LIBRARY_API_VERSION,
+    name : "Visualizer Library",
+    implementor : "The Android Open Source Project",
+    query_num_effects : VisualizerLib_QueryNumberEffects,
+    query_effect : VisualizerLib_QueryEffect,
+    create_effect : VisualizerLib_Create,
+    release_effect : VisualizerLib_Release,
+    get_descriptor : VisualizerLib_GetDescriptor,
+};
+
+}; // extern "C"
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 8e86eda..67c6d96 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -61,7 +61,6 @@
 
 // ----------------------------------------------------------------------------
 
-extern const char * const gEffectLibPath;
 
 namespace android {
 
@@ -4622,10 +4621,6 @@
     if (!settingsAllowed()) {
         return PERMISSION_DENIED;
     }
-    // only allow libraries loaded from /system/lib/soundfx for now
-    if (strncmp(gEffectLibPath, libPath, strlen(gEffectLibPath)) != 0) {
-        return PERMISSION_DENIED;
-    }
 
     Mutex::Autolock _l(mLock);
     return EffectLoadLibrary(libPath, handle);
@@ -4677,7 +4672,6 @@
 {
     status_t lStatus = NO_ERROR;
     sp<EffectHandle> handle;
-    effect_interface_t itfe;
     effect_descriptor_t desc;
     sp<Client> client;
     wp<Client> wclient;
@@ -5515,19 +5509,19 @@
 
     // TODO: handle configuration of effects replacing track process
     if (thread->channelCount() == 1) {
-        channels = CHANNEL_MONO;
+        channels = AUDIO_CHANNEL_OUT_MONO;
     } else {
-        channels = CHANNEL_STEREO;
+        channels = AUDIO_CHANNEL_OUT_STEREO;
     }
 
     if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
-        mConfig.inputCfg.channels = CHANNEL_MONO;
+        mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO;
     } else {
         mConfig.inputCfg.channels = channels;
     }
     mConfig.outputCfg.channels = channels;
-    mConfig.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
-    mConfig.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
+    mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+    mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
     mConfig.inputCfg.samplingRate = thread->sampleRate();
     mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate;
     mConfig.inputCfg.bufferProvider.cookie = NULL;
@@ -5772,11 +5766,6 @@
     Mutex::Autolock _l(mLock);
     status_t status = NO_ERROR;
     if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
-        // convert device bit field from AudioSystem to EffectApi format.
-        device = deviceAudioSystemToEffectApi(device);
-        if (device == 0) {
-            return BAD_VALUE;
-        }
         status_t cmdStatus;
         uint32_t size = sizeof(status_t);
         status = (*mEffectInterface)->command(mEffectInterface,
@@ -5797,17 +5786,12 @@
     Mutex::Autolock _l(mLock);
     status_t status = NO_ERROR;
     if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_MODE_MASK) == EFFECT_FLAG_AUDIO_MODE_IND) {
-        // convert audio mode from AudioSystem to EffectApi format.
-        int effectMode = modeAudioSystemToEffectApi(mode);
-        if (effectMode < 0) {
-            return BAD_VALUE;
-        }
         status_t cmdStatus;
         uint32_t size = sizeof(status_t);
         status = (*mEffectInterface)->command(mEffectInterface,
                                               EFFECT_CMD_SET_AUDIO_MODE,
                                               sizeof(int),
-                                              &effectMode,
+                                              &mode,
                                               &size,
                                               &cmdStatus);
         if (status == NO_ERROR) {
@@ -5817,53 +5801,6 @@
     return status;
 }
 
-// update this table when AudioSystem::audio_devices or audio_device_e (in EffectApi.h) are modified
-const uint32_t AudioFlinger::EffectModule::sDeviceConvTable[] = {
-    DEVICE_EARPIECE, // AUDIO_DEVICE_OUT_EARPIECE
-    DEVICE_SPEAKER, // AUDIO_DEVICE_OUT_SPEAKER
-    DEVICE_WIRED_HEADSET, // case AUDIO_DEVICE_OUT_WIRED_HEADSET
-    DEVICE_WIRED_HEADPHONE, // AUDIO_DEVICE_OUT_WIRED_HEADPHONE
-    DEVICE_BLUETOOTH_SCO, // AUDIO_DEVICE_OUT_BLUETOOTH_SCO
-    DEVICE_BLUETOOTH_SCO_HEADSET, // AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET
-    DEVICE_BLUETOOTH_SCO_CARKIT, //  AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT
-    DEVICE_BLUETOOTH_A2DP, //  AUDIO_DEVICE_OUT_BLUETOOTH_A2DP
-    DEVICE_BLUETOOTH_A2DP_HEADPHONES, // AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES
-    DEVICE_BLUETOOTH_A2DP_SPEAKER, // AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
-    DEVICE_AUX_DIGITAL // AUDIO_DEVICE_OUT_AUX_DIGITAL
-};
-
-uint32_t AudioFlinger::EffectModule::deviceAudioSystemToEffectApi(uint32_t device)
-{
-    uint32_t deviceOut = 0;
-    while (device) {
-        const uint32_t i = 31 - __builtin_clz(device);
-        device &= ~(1 << i);
-        if (i >= sizeof(sDeviceConvTable)/sizeof(uint32_t)) {
-            LOGE("device conversion error for AudioSystem device 0x%08x", device);
-            return 0;
-        }
-        deviceOut |= (uint32_t)sDeviceConvTable[i];
-    }
-    return deviceOut;
-}
-
-// update this table when AudioSystem::audio_mode or audio_mode_e (in EffectApi.h) are modified
-const uint32_t AudioFlinger::EffectModule::sModeConvTable[] = {
-    AUDIO_EFFECT_MODE_NORMAL,   // AUDIO_MODE_NORMAL
-    AUDIO_EFFECT_MODE_RINGTONE, // AUDIO_MODE_RINGTONE
-    AUDIO_EFFECT_MODE_IN_CALL,  // AUDIO_MODE_IN_CALL
-    AUDIO_EFFECT_MODE_IN_CALL   // AUDIO_MODE_IN_COMMUNICATION, same conversion as for AUDIO_MODE_IN_CALL
-};
-
-int AudioFlinger::EffectModule::modeAudioSystemToEffectApi(uint32_t mode)
-{
-    int modeOut = -1;
-    if (mode < sizeof(sModeConvTable) / sizeof(uint32_t)) {
-        modeOut = (int)sModeConvTable[mode];
-    }
-    return modeOut;
-}
-
 status_t AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
 {
     const size_t SIZE = 256;
@@ -5895,7 +5832,7 @@
                 mDescriptor.type.clockSeq, mDescriptor.type.node[0], mDescriptor.type.node[1],mDescriptor.type.node[2],
                 mDescriptor.type.node[3],mDescriptor.type.node[4],mDescriptor.type.node[5]);
     result.append(buffer);
-    snprintf(buffer, SIZE, "\t\t- apiVersion: %04X\n\t\t- flags: %08X\n",
+    snprintf(buffer, SIZE, "\t\t- apiVersion: %08X\n\t\t- flags: %08X\n",
             mDescriptor.apiVersion,
             mDescriptor.flags);
     result.append(buffer);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 39314ad..f3e1984 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -1002,14 +1002,6 @@
         status_t start_l();
         status_t stop_l();
 
-        // update this table when AudioSystem::audio_devices or audio_device_e (in EffectApi.h) are modified
-        static const uint32_t sDeviceConvTable[];
-        static uint32_t deviceAudioSystemToEffectApi(uint32_t device);
-
-        // update this table when AudioSystem::audio_mode or audio_mode_e (in EffectApi.h) are modified
-        static const uint32_t sModeConvTable[];
-        static int modeAudioSystemToEffectApi(uint32_t mode);
-
         Mutex               mLock;      // mutex for process, commands and handles list protection
         wp<ThreadBase>      mThread;    // parent thread
         wp<EffectChain>     mChain;     // parent effect chain
@@ -1017,7 +1009,7 @@
         int                 mSessionId; // audio session ID
         effect_descriptor_t mDescriptor;// effect descriptor received from effect engine
         effect_config_t     mConfig;    // input and output audio configuration
-        effect_interface_t  mEffectInterface; // Effect module C API
+        effect_handle_t  mEffectInterface; // Effect module C API
         status_t mStatus;               // initialization status
         uint32_t mState;                // current activation state (effect_state)
         Vector< wp<EffectHandle> > mHandles;    // list of client handles
diff --git a/tests/BiDiTests/res/layout/canvas.xml b/tests/BiDiTests/res/layout/canvas.xml
index 371cc23..77007af3 100644
--- a/tests/BiDiTests/res/layout/canvas.xml
+++ b/tests/BiDiTests/res/layout/canvas.xml
@@ -31,4 +31,4 @@
         android:background="#FF0000"
     />
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/patch.9.png b/tests/HwAccelerationTest/res/drawable-hdpi/patch.9.png
new file mode 100644
index 0000000..e3b3639
--- /dev/null
+++ b/tests/HwAccelerationTest/res/drawable-hdpi/patch.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ClearActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ClearActivity.java
index 1d7ff0f..b49db7c5 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ClearActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ClearActivity.java
@@ -51,7 +51,7 @@
             mClearPaint = new Paint();
             mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
             mClearPaint.setAntiAlias(true);
-            mClearPaint.setColor(0xff00ff00);
+            mClearPaint.setColor(0x0000ff00);
             mClearPaint.setStrokeWidth(15.0f);
             mClearPaint.setStyle(Paint.Style.FILL);
             mClearPaint.setTextSize(32.0f);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ThinPatchesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ThinPatchesActivity.java
index 4f605fa..cfad6da 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ThinPatchesActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ThinPatchesActivity.java
@@ -18,7 +18,10 @@
 
 import android.app.Activity;
 import android.content.res.Resources;
+import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.view.View;
@@ -42,6 +45,7 @@
 
     private class PatchView extends View {
         private Drawable mPatch1, mPatch2;
+        private Bitmap mTexture;
 
         public PatchView(Activity activity) {
             super(activity);
@@ -49,6 +53,20 @@
             final Resources resources = activity.getResources();
             mPatch1 = resources.getDrawable(R.drawable.patch);
             mPatch2 = resources.getDrawable(R.drawable.btn_toggle_on);
+
+            mTexture = Bitmap.createBitmap(4, 3, Bitmap.Config.ARGB_8888);
+            mTexture.setPixel(0, 0, 0xffff0000);
+            mTexture.setPixel(1, 0, 0xffffffff);
+            mTexture.setPixel(2, 0, 0xff000000);
+            mTexture.setPixel(3, 0, 0xffff0000);
+            mTexture.setPixel(0, 1, 0xffff0000);
+            mTexture.setPixel(1, 1, 0xff000000);
+            mTexture.setPixel(2, 1, 0xffffffff);
+            mTexture.setPixel(3, 1, 0xffff0000);
+            mTexture.setPixel(0, 2, 0xffff0000);
+            mTexture.setPixel(1, 2, 0xffff0000);
+            mTexture.setPixel(2, 2, 0xffff0000);
+            mTexture.setPixel(3, 2, 0xffff0000);
         }
 
         @Override
@@ -62,10 +80,17 @@
             mPatch1.setBounds(left, top, left + width, top + height);
             mPatch1.draw(canvas);
 
+            canvas.save();
             canvas.translate(0.0f, height + 20.0f);
             
             mPatch2.setBounds(left, top, left + width, top + height);
             mPatch2.draw(canvas);
+
+            canvas.restore();
+
+//            Rect src = new Rect(1, 0, 3, 2);
+//            RectF dst = new RectF(0, 0, getWidth(), getHeight());
+//            canvas.drawBitmap(mTexture, src, dst, null);
         }
     }
 }