Merge "Notification actions API."
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index e575c26..24a7800 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -1826,7 +1826,7 @@
      *
      * @return true if write-ahead-logging is set. false otherwise
      *
-     * @throw IllegalStateException if there are transactions in progress at the
+     * @throws IllegalStateException if there are transactions in progress at the
      * time this method is called.  WAL mode can only be changed when there are no
      * transactions in progress.
      */
@@ -1882,7 +1882,7 @@
     /**
      * This method disables the features enabled by {@link #enableWriteAheadLogging()}.
      *
-     * @throw IllegalStateException if there are transactions in progress at the
+     * @throws IllegalStateException if there are transactions in progress at the
      * time this method is called.  WAL mode can only be changed when there are no
      * transactions in progress.
      */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index fbb3273..d74ccb8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -793,6 +793,7 @@
             MOVED_TO_SECURE.add(Secure.HTTP_PROXY);
             MOVED_TO_SECURE.add(Secure.INSTALL_NON_MARKET_APPS);
             MOVED_TO_SECURE.add(Secure.LOCATION_PROVIDERS_ALLOWED);
+            MOVED_TO_SECURE.add(Secure.LOCK_BIOMETRIC_WEAK_FLAGS);
             MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_ENABLED);
             MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_VISIBLE);
             MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED);
@@ -2657,6 +2658,13 @@
         public static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
 
         /**
+         * A flag containing settings used for biometric weak
+         * @hide
+         */
+        public static final String LOCK_BIOMETRIC_WEAK_FLAGS =
+                "lock_biometric_weak_flags";
+
+        /**
          * Whether autolock is enabled (0 = false, 1 = true)
          */
         public static final String LOCK_PATTERN_ENABLED = "lock_pattern_autolock";
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 92e8f4e..77fd8d2 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -1654,14 +1654,22 @@
             }
         }
     }
-    
+
     /**
-     * Scales down the coordination of this event by the given scale.
+     * Applies a scale factor to all points within this event.
      *
+     * This method is used to adjust touch events to simulate different density
+     * displays for compatibility mode.  The values returned by {@link #getRawX()},
+     * {@link #getRawY()}, {@link #getXPrecision()} and {@link #getYPrecision()}
+     * are also affected by the scale factor.
+     *
+     * @param scale The scale factor to apply.
      * @hide
      */
     public final void scale(float scale) {
-        nativeScale(mNativePtr, scale);
+        if (scale != 1.0f) {
+            nativeScale(mNativePtr, scale);
+        }
     }
 
     /** {@inheritDoc} */
@@ -2631,7 +2639,9 @@
      * @param deltaY Amount to add to the current Y coordinate of the event.
      */
     public final void offsetLocation(float deltaX, float deltaY) {
-        nativeOffsetLocation(mNativePtr, deltaX, deltaY);
+        if (deltaX != 0.0f || deltaY != 0.0f) {
+            nativeOffsetLocation(mNativePtr, deltaX, deltaY);
+        }
     }
 
     /**
@@ -2644,7 +2654,7 @@
     public final void setLocation(float x, float y) {
         float oldX = getX();
         float oldY = getY();
-        nativeOffsetLocation(mNativePtr, x - oldX, y - oldY);
+        offsetLocation(x - oldX, y - oldY);
     }
     
     /**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d403cb9e..ffffc73 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1459,7 +1459,7 @@
      * apps.
      * @hide
      */
-    public static final boolean USE_DISPLAY_LIST_PROPERTIES = true;
+    public static final boolean USE_DISPLAY_LIST_PROPERTIES = false;
 
     /**
      * Map used to store views' tags.
diff --git a/core/java/android/webkit/WebSettingsClassic.java b/core/java/android/webkit/WebSettingsClassic.java
index 7e38570..c41bc00 100644
--- a/core/java/android/webkit/WebSettingsClassic.java
+++ b/core/java/android/webkit/WebSettingsClassic.java
@@ -121,9 +121,6 @@
     private boolean         mForceUserScalable = false;
 
     // AutoFill Profile data
-    /**
-     * @hide for now, pending API council approval.
-     */
     public static class AutoFillProfile {
         private int mUniqueId;
         private String mFullName;
@@ -644,7 +641,6 @@
     /**
      * Set the double-tap zoom of the page in percent. Default is 100.
      * @param doubleTapZoom A percent value for increasing or decreasing the double-tap zoom.
-     * @hide
      */
     public void setDoubleTapZoom(int doubleTapZoom) {
         if (mDoubleTapZoom != doubleTapZoom) {
@@ -656,7 +652,6 @@
     /**
      * Get the double-tap zoom of the page in percent.
      * @return A percent value describing the double-tap zoom.
-     * @hide
      */
     public int getDoubleTapZoom() {
         return mDoubleTapZoom;
@@ -1012,7 +1007,6 @@
     /**
      * Set the number of pages cached by the WebKit for the history navigation.
      * @param size A non-negative integer between 0 (no cache) and 20 (max).
-     * @hide
      */
     public synchronized void setPageCacheCapacity(int size) {
         if (size < 0) size = 0;
@@ -1108,7 +1102,6 @@
     /**
      * Tell the WebView to use Skia's hardware accelerated rendering path
      * @param flag True if the WebView should use Skia's hw-accel path
-     * @hide
      */
     public synchronized void setHardwareAccelSkiaEnabled(boolean flag) {
         if (mHardwareAccelSkia != flag) {
@@ -1119,7 +1112,6 @@
 
     /**
      * @return True if the WebView is using hardware accelerated skia
-     * @hide
      */
     public synchronized boolean getHardwareAccelSkiaEnabled() {
         return mHardwareAccelSkia;
@@ -1128,7 +1120,6 @@
     /**
      * Tell the WebView to show the visual indicator
      * @param flag True if the WebView should show the visual indicator
-     * @hide
      */
     public synchronized void setShowVisualIndicator(boolean flag) {
         if (mShowVisualIndicator != flag) {
@@ -1139,7 +1130,6 @@
 
     /**
      * @return True if the WebView is showing the visual indicator
-     * @hide
      */
     public synchronized boolean getShowVisualIndicator() {
         return mShowVisualIndicator;
@@ -1283,7 +1273,6 @@
      * @param flag True if the WebView should enable WebWorkers.
      * Note that this flag only affects V8. JSC does not have
      * an equivalent setting.
-     * @hide
      */
     public synchronized void setWorkersEnabled(boolean flag) {
         if (mWorkersEnabled != flag) {
@@ -1305,8 +1294,8 @@
 
     /**
      * Sets whether XSS Auditor is enabled.
+     * Only used by LayoutTestController.
      * @param flag Whether XSS Auditor should be enabled.
-     * @hide Only used by LayoutTestController.
      */
     public synchronized void setXSSAuditorEnabled(boolean flag) {
         if (mXSSAuditorEnabled != flag) {
@@ -1507,7 +1496,6 @@
      * of an HTML page to fit the screen. This conflicts with attempts by
      * the UI to zoom in and out of an image, so it is set false by default.
      * @param shrink Set true to let webkit shrink the standalone image to fit.
-     * {@hide}
      */
     public void setShrinksStandaloneImagesToFit(boolean shrink) {
         if (mShrinksStandaloneImagesToFit != shrink) {
@@ -1520,7 +1508,6 @@
      * Specify the maximum decoded image size. The default is
      * 2 megs for small memory devices and 8 megs for large memory devices.
      * @param size The maximum decoded size, or zero to set to the default.
-     * @hide
      */
     public void setMaximumDecodedImageSize(long size) {
         if (mMaximumDecodedImageSize != size) {
@@ -1562,7 +1549,6 @@
 
     /**
      * Returns whether the viewport metatag can disable zooming
-     * @hide
      */
     public boolean forceUserScalable() {
         return mForceUserScalable;
@@ -1571,7 +1557,6 @@
     /**
      * Sets whether viewport metatag can disable zooming.
      * @param flag Whether or not to forceably enable user scalable.
-     * @hide
      */
     public synchronized void setForceUserScalable(boolean flag) {
         mForceUserScalable = flag;
@@ -1584,9 +1569,6 @@
         }
     }
 
-    /**
-     * @hide
-     */
     public synchronized void setAutoFillEnabled(boolean enabled) {
         // AutoFill is always disabled in private browsing mode.
         boolean autoFillEnabled = enabled && !mPrivateBrowsingEnabled;
@@ -1596,16 +1578,10 @@
         }
     }
 
-    /**
-     * @hide
-     */
     public synchronized boolean getAutoFillEnabled() {
         return mAutoFillEnabled;
     }
 
-    /**
-     * @hide
-     */
     public synchronized void setAutoFillProfile(AutoFillProfile profile) {
         if (mAutoFillProfile != profile) {
             mAutoFillProfile = profile;
@@ -1613,9 +1589,6 @@
         }
     }
 
-    /**
-     * @hide
-     */
     public synchronized AutoFillProfile getAutoFillProfile() {
         return mAutoFillProfile;
     }
@@ -1633,18 +1606,12 @@
         }
     }
 
-    /**
-     * @hide
-     */
     public void setProperty(String key, String value) {
         if (mWebView.nativeSetProperty(key, value)) {
             mWebView.invalidate();
         }
     }
 
-    /**
-     * @hide
-     */
     public String getProperty(String key) {
         return mWebView.nativeGetProperty(key);
     }
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index e553a2e..6f60583 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -348,8 +348,6 @@
  *
  * @hide
  */
-// TODO: Remove duplicated API documentation and @hide from fields and methods, and
-// checkThread() call. (All left in for now to ease branch merging.)
 // TODO: Check if any WebView published API methods are called from within here, and if so
 // we should bounce the call out via the proxy to enable any sub-class to override it.
 @Widget
@@ -1464,8 +1462,6 @@
      */
     @Override
     public void init(Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
-        checkThread();
-
         Context context = mContext;
 
         // Used by the chrome stack to find application paths
@@ -1497,8 +1493,7 @@
         mEditTextScroller = new Scroller(context);
     }
 
-    // === START: WebView Proxy binding ===
-    // Keep the webview proxy / SPI related stuff in this section, to minimize merge conflicts.
+    // WebViewProvider bindings
 
     static class Factory implements WebViewFactoryProvider,  WebViewFactoryProvider.Statics {
         @Override
@@ -1587,8 +1582,6 @@
         mWebViewPrivate.setScrollYRaw(mScrollY);
     }
 
-    // === END: WebView Proxy binding ===
-
     private static class TrustStorageListener extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -1969,7 +1962,6 @@
      */
     @Override
     public void setHorizontalScrollbarOverlay(boolean overlay) {
-        checkThread();
         mOverlayHorizontalScrollbar = overlay;
     }
 
@@ -1978,7 +1970,6 @@
      */
     @Override
     public void setVerticalScrollbarOverlay(boolean overlay) {
-        checkThread();
         mOverlayVerticalScrollbar = overlay;
     }
 
@@ -1987,7 +1978,6 @@
      */
     @Override
     public boolean overlayHorizontalScrollbar() {
-        checkThread();
         return mOverlayHorizontalScrollbar;
     }
 
@@ -1996,7 +1986,6 @@
      */
     @Override
     public boolean overlayVerticalScrollbar() {
-        checkThread();
         return mOverlayVerticalScrollbar;
     }
 
@@ -2022,7 +2011,6 @@
     /**
      * Returns the height (in pixels) of the embedded title bar (if any). Does not care about
      * scrolling
-     * @hide
      */
     protected int getTitleHeight() {
         if (mWebView instanceof TitleBarDelegate) {
@@ -2039,7 +2027,6 @@
     public int getVisibleTitleHeight() {
         // Actually, this method returns the height of the embedded title bar if one is set via the
         // hidden setEmbeddedTitleBar method.
-        checkThread();
         return getVisibleTitleHeightImpl();
     }
 
@@ -2085,7 +2072,6 @@
      */
     @Override
     public SslCertificate getCertificate() {
-        checkThread();
         return mCertificate;
     }
 
@@ -2094,7 +2080,6 @@
      */
     @Override
     public void setCertificate(SslCertificate certificate) {
-        checkThread();
         if (DebugFlags.WEB_VIEW) {
             Log.v(LOGTAG, "setCertificate=" + certificate);
         }
@@ -2111,7 +2096,6 @@
      */
     @Override
     public void savePassword(String host, String username, String password) {
-        checkThread();
         mDatabase.setUsernamePassword(host, username, password);
     }
 
@@ -2121,7 +2105,6 @@
     @Override
     public void setHttpAuthUsernamePassword(String host, String realm,
             String username, String password) {
-        checkThread();
         mDatabase.setHttpAuthUsernamePassword(host, realm, username, password);
     }
 
@@ -2130,7 +2113,6 @@
      */
     @Override
     public String[] getHttpAuthUsernamePassword(String host, String realm) {
-        checkThread();
         return mDatabase.getHttpAuthUsernamePassword(host, realm);
     }
 
@@ -2170,7 +2152,6 @@
      */
     @Override
     public void destroy() {
-        checkThread();
         destroyImpl();
     }
 
@@ -2203,7 +2184,6 @@
      */
     @Deprecated
     public static void enablePlatformNotifications() {
-        checkThread();
         synchronized (WebViewClassic.class) {
             sNotificationsEnabled = true;
             Context context = JniUtil.getContext();
@@ -2217,7 +2197,6 @@
      */
     @Deprecated
     public static void disablePlatformNotifications() {
-        checkThread();
         synchronized (WebViewClassic.class) {
             sNotificationsEnabled = false;
             Context context = JniUtil.getContext();
@@ -2231,10 +2210,9 @@
      *
      * @param flags JS engine flags in a String
      *
-     * @hide This is an implementation detail.
+     * This is an implementation detail.
      */
     public void setJsFlags(String flags) {
-        checkThread();
         mWebViewCore.sendMessage(EventHub.SET_JS_FLAGS, flags);
     }
 
@@ -2243,17 +2221,14 @@
      */
     @Override
     public void setNetworkAvailable(boolean networkUp) {
-        checkThread();
         mWebViewCore.sendMessage(EventHub.SET_NETWORK_STATE,
                 networkUp ? 1 : 0, 0);
     }
 
     /**
      * Inform WebView about the current network type.
-     * {@hide}
      */
     public void setNetworkType(String type, String subtype) {
-        checkThread();
         Map<String, String> map = new HashMap<String, String>();
         map.put("type", type);
         map.put("subtype", subtype);
@@ -2265,7 +2240,6 @@
      */
     @Override
     public WebBackForwardList saveState(Bundle outState) {
-        checkThread();
         if (outState == null) {
             return null;
         }
@@ -2317,7 +2291,6 @@
     @Override
     @Deprecated
     public boolean savePicture(Bundle b, final File dest) {
-        checkThread();
         if (dest == null || b == null) {
             return false;
         }
@@ -2379,7 +2352,6 @@
     @Override
     @Deprecated
     public boolean restorePicture(Bundle b, File src) {
-        checkThread();
         if (src == null || b == null) {
             return false;
         }
@@ -2425,7 +2397,6 @@
      * of WebView.
      * @param stream The {@link OutputStream} to save to
      * @return True if saved successfully
-     * @hide
      */
     public boolean saveViewState(OutputStream stream) {
         try {
@@ -2441,7 +2412,6 @@
      * {@link #saveViewState(OutputStream)} for more information.
      * @param stream The {@link InputStream} to load from
      * @return True if loaded successfully
-     * @hide
      */
     public boolean loadViewState(InputStream stream) {
         try {
@@ -2471,7 +2441,6 @@
      */
     @Override
     public WebBackForwardList restoreState(Bundle inState) {
-        checkThread();
         WebBackForwardList returnList = null;
         if (inState == null) {
             return returnList;
@@ -2528,7 +2497,6 @@
      */
     @Override
     public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
-        checkThread();
         loadUrlImpl(url, additionalHttpHeaders);
     }
 
@@ -2546,7 +2514,6 @@
      */
     @Override
     public void loadUrl(String url) {
-        checkThread();
         loadUrlImpl(url);
     }
 
@@ -2562,7 +2529,6 @@
      */
     @Override
     public void postUrl(String url, byte[] postData) {
-        checkThread();
         if (URLUtil.isNetworkUrl(url)) {
             switchOutDrawHistory();
             WebViewCore.PostUrlData arg = new WebViewCore.PostUrlData();
@@ -2580,7 +2546,6 @@
      */
     @Override
     public void loadData(String data, String mimeType, String encoding) {
-        checkThread();
         loadDataImpl(data, mimeType, encoding);
     }
 
@@ -2601,7 +2566,6 @@
     @Override
     public void loadDataWithBaseURL(String baseUrl, String data,
             String mimeType, String encoding, String historyUrl) {
-        checkThread();
 
         if (baseUrl != null && baseUrl.toLowerCase().startsWith("data:")) {
             loadDataImpl(data, mimeType, encoding);
@@ -2623,7 +2587,6 @@
      */
     @Override
     public void saveWebArchive(String filename) {
-        checkThread();
         saveWebArchiveImpl(filename, false, null);
     }
 
@@ -2645,7 +2608,6 @@
      */
     @Override
     public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback) {
-        checkThread();
         saveWebArchiveImpl(basename, autoname, callback);
     }
 
@@ -2660,7 +2622,6 @@
      */
     @Override
     public void stopLoading() {
-        checkThread();
         // TODO: should we clear all the messages in the queue before sending
         // STOP_LOADING?
         switchOutDrawHistory();
@@ -2672,7 +2633,6 @@
      */
     @Override
     public void reload() {
-        checkThread();
         clearHelpers();
         switchOutDrawHistory();
         mWebViewCore.sendMessage(EventHub.RELOAD);
@@ -2683,7 +2643,6 @@
      */
     @Override
     public boolean canGoBack() {
-        checkThread();
         WebBackForwardList l = mCallbackProxy.getBackForwardList();
         synchronized (l) {
             if (l.getClearPending()) {
@@ -2699,7 +2658,6 @@
      */
     @Override
     public void goBack() {
-        checkThread();
         goBackOrForwardImpl(-1);
     }
 
@@ -2708,7 +2666,6 @@
      */
     @Override
     public boolean canGoForward() {
-        checkThread();
         WebBackForwardList l = mCallbackProxy.getBackForwardList();
         synchronized (l) {
             if (l.getClearPending()) {
@@ -2724,7 +2681,6 @@
      */
     @Override
     public void goForward() {
-        checkThread();
         goBackOrForwardImpl(1);
     }
 
@@ -2733,7 +2689,6 @@
      */
     @Override
     public boolean canGoBackOrForward(int steps) {
-        checkThread();
         WebBackForwardList l = mCallbackProxy.getBackForwardList();
         synchronized (l) {
             if (l.getClearPending()) {
@@ -2750,7 +2705,6 @@
      */
     @Override
     public void goBackOrForward(int steps) {
-        checkThread();
         goBackOrForwardImpl(steps);
     }
 
@@ -2771,7 +2725,6 @@
      */
     @Override
     public boolean isPrivateBrowsingEnabled() {
-        checkThread();
         return getSettings().isPrivateBrowsingEnabled();
     }
 
@@ -2793,7 +2746,6 @@
      */
     @Override
     public boolean pageUp(boolean top) {
-        checkThread();
         if (mNativeClass == 0) {
             return false;
         }
@@ -2818,7 +2770,6 @@
      */
     @Override
     public boolean pageDown(boolean bottom) {
-        checkThread();
         if (mNativeClass == 0) {
             return false;
         }
@@ -2842,7 +2793,6 @@
      */
     @Override
     public void clearView() {
-        checkThread();
         mContentWidth = 0;
         mContentHeight = 0;
         setBaseLayer(0, null, false, false);
@@ -2854,7 +2804,6 @@
      */
     @Override
     public Picture capturePicture() {
-        checkThread();
         if (mNativeClass == 0) return null;
         Picture result = new Picture();
         nativeCopyBaseContentToPicture(result);
@@ -2866,7 +2815,6 @@
      */
     @Override
     public float getScale() {
-        checkThread();
         return mZoomManager.getScale();
     }
 
@@ -2884,7 +2832,6 @@
      */
     @Override
     public void setInitialScale(int scaleInPercent) {
-        checkThread();
         mZoomManager.setInitialScaleInPercent(scaleInPercent);
     }
 
@@ -2893,7 +2840,6 @@
      */
     @Override
     public void invokeZoomPicker() {
-        checkThread();
         if (!getSettings().supportZoom()) {
             Log.w(LOGTAG, "This WebView doesn't support zoom.");
             return;
@@ -2907,7 +2853,6 @@
      */
     @Override
     public HitTestResult getHitTestResult() {
-        checkThread();
         return mInitialHitTestResult;
     }
 
@@ -2943,7 +2888,6 @@
      */
     @Override
     public void requestFocusNodeHref(Message hrefMsg) {
-        checkThread();
         if (hrefMsg == null) {
             return;
         }
@@ -2966,7 +2910,6 @@
      */
     @Override
     public void requestImageRef(Message msg) {
-        checkThread();
         if (0 == mNativeClass) return; // client isn't initialized
         String url = mFocusedNode != null ? mFocusedNode.mImageUrl : null;
         Bundle data = msg.getData();
@@ -3020,7 +2963,6 @@
      * along with it vertically, while remaining in view horizontally. Pass
      * null to remove the title bar from the WebView, and return to drawing
      * the WebView normally without translating to account for the title bar.
-     * @hide
      */
     public void setEmbeddedTitleBar(View v) {
         if (mWebView instanceof TitleBarDelegate) {
@@ -3042,7 +2984,6 @@
      * Set where to render the embedded title bar
      * NO_GRAVITY at the top of the page
      * TOP        at the top of the screen
-     * @hide
      */
     public void setTitleBarGravity(int gravity) {
         mTitleGravity = gravity;
@@ -3422,7 +3363,6 @@
         return getViewHeight();
     }
 
-    /** @hide */
     @Override
     public void onDrawVerticalScrollBar(Canvas canvas,
                                            Drawable scrollBar,
@@ -3471,7 +3411,6 @@
      */
     @Override
     public String getUrl() {
-        checkThread();
         WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
         return h != null ? h.getUrl() : null;
     }
@@ -3481,7 +3420,6 @@
      */
     @Override
     public String getOriginalUrl() {
-        checkThread();
         WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
         return h != null ? h.getOriginalUrl() : null;
     }
@@ -3491,7 +3429,6 @@
      */
     @Override
     public String getTitle() {
-        checkThread();
         WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
         return h != null ? h.getTitle() : null;
     }
@@ -3501,7 +3438,6 @@
      */
     @Override
     public Bitmap getFavicon() {
-        checkThread();
         WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
         return h != null ? h.getFavicon() : null;
     }
@@ -3520,7 +3456,6 @@
      */
     @Override
     public int getProgress() {
-        checkThread();
         return mCallbackProxy.getProgress();
     }
 
@@ -3529,7 +3464,6 @@
      */
     @Override
     public int getContentHeight() {
-        checkThread();
         return mContentHeight;
     }
 
@@ -3541,9 +3475,6 @@
         return mContentWidth;
     }
 
-    /**
-     * @hide
-     */
     public int getPageBackgroundColor() {
         return nativeGetBackgroundColor();
     }
@@ -3553,7 +3484,6 @@
      */
     @Override
     public void pauseTimers() {
-        checkThread();
         mWebViewCore.sendMessage(EventHub.PAUSE_TIMERS);
     }
 
@@ -3562,7 +3492,6 @@
      */
     @Override
     public void resumeTimers() {
-        checkThread();
         mWebViewCore.sendMessage(EventHub.RESUME_TIMERS);
     }
 
@@ -3571,7 +3500,6 @@
      */
     @Override
     public void onPause() {
-        checkThread();
         if (!mIsPaused) {
             mIsPaused = true;
             mWebViewCore.sendMessage(EventHub.ON_PAUSE);
@@ -3610,7 +3538,6 @@
      */
     @Override
     public void onResume() {
-        checkThread();
         if (mIsPaused) {
             mIsPaused = false;
             mWebViewCore.sendMessage(EventHub.ON_RESUME);
@@ -3642,7 +3569,6 @@
      */
     @Override
     public void freeMemory() {
-        checkThread();
         mWebViewCore.sendMessage(EventHub.FREE_MEMORY);
     }
 
@@ -3651,7 +3577,6 @@
      */
     @Override
     public void clearCache(boolean includeDiskFiles) {
-        checkThread();
         // Note: this really needs to be a static method as it clears cache for all
         // WebView. But we need mWebViewCore to send message to WebCore thread, so
         // we can't make this static.
@@ -3664,7 +3589,6 @@
      */
     @Override
     public void clearFormData() {
-        checkThread();
         if (mAutoCompletePopup != null) {
             mAutoCompletePopup.clearAdapter();
         }
@@ -3675,7 +3599,6 @@
      */
     @Override
     public void clearHistory() {
-        checkThread();
         mCallbackProxy.getBackForwardList().setClearPending();
         mWebViewCore.sendMessage(EventHub.CLEAR_HISTORY);
     }
@@ -3685,7 +3608,6 @@
      */
     @Override
     public void clearSslPreferences() {
-        checkThread();
         mWebViewCore.sendMessage(EventHub.CLEAR_SSL_PREF_TABLE);
     }
 
@@ -3694,7 +3616,6 @@
      */
     @Override
     public WebBackForwardList copyBackForwardList() {
-        checkThread();
         return mCallbackProxy.getBackForwardList().clone();
     }
 
@@ -3705,7 +3626,6 @@
      * @param listener An implementation of FindListener
      */
      public void setFindListener(FindListener listener) {
-         checkThread();
          mFindListener = listener;
      }
 
@@ -3714,7 +3634,6 @@
      */
     @Override
     public void findNext(boolean forward) {
-        checkThread();
         if (0 == mNativeClass) return; // client isn't initialized
         mWebViewCore.sendMessage(EventHub.FIND_NEXT, forward ? 1 : 0);
     }
@@ -3727,15 +3646,11 @@
         return findAllBody(find, false);
     }
 
-    /**
-     * @hide
-     */
     public void findAllAsync(String find) {
         findAllBody(find, true);
     }
 
     private int findAllBody(String find, boolean isAsync) {
-        checkThread();
         if (0 == mNativeClass) return 0; // client isn't initialized
         mLastFind = find;
         if (find == null) return 0;
@@ -3772,7 +3687,6 @@
      * @return boolean True if the find dialog is shown, false otherwise.
      */
     public boolean showFindDialog(String text, boolean showIme) {
-        checkThread();
         FindActionModeCallback callback = new FindActionModeCallback(mContext);
         if (mWebView.getParent() == null || mWebView.startActionMode(callback) == null) {
             // Could not start the action mode, so end Find on page
@@ -3841,12 +3755,10 @@
      * @return the address, or if no address is found, return null.
      */
     public static String findAddress(String addr) {
-        checkThread();
         return findAddress(addr, false);
     }
 
     /**
-     * @hide
      * Return the first substring consisting of the address of a physical
      * location. Currently, only addresses in the United States are detected,
      * and consist of:
@@ -3876,7 +3788,6 @@
      */
     @Override
     public void clearMatches() {
-        checkThread();
         if (mNativeClass == 0)
             return;
         mWebViewCore.removeMessages(EventHub.FIND_ALL);
@@ -3906,7 +3817,6 @@
      */
     @Override
     public void documentHasImages(Message response) {
-        checkThread();
         if (response == null) {
             return;
         }
@@ -3915,8 +3825,6 @@
 
     /**
      * Request the scroller to abort any ongoing animation
-     *
-     * @hide
      */
     public void stopScroll() {
         mScroller.forceFinished(true);
@@ -4340,7 +4248,6 @@
      */
     @Override
     public void setWebViewClient(WebViewClient client) {
-        checkThread();
         mCallbackProxy.setWebViewClient(client);
     }
 
@@ -4348,7 +4255,7 @@
      * Gets the WebViewClient
      * @return the current WebViewClient instance.
      *
-     * @hide This is an implementation detail.
+     * This is an implementation detail.
      */
     public WebViewClient getWebViewClient() {
         return mCallbackProxy.getWebViewClient();
@@ -4359,7 +4266,6 @@
      */
     @Override
     public void setDownloadListener(DownloadListener listener) {
-        checkThread();
         mCallbackProxy.setDownloadListener(listener);
     }
 
@@ -4368,7 +4274,6 @@
      */
     @Override
     public void setWebChromeClient(WebChromeClient client) {
-        checkThread();
         mCallbackProxy.setWebChromeClient(client);
     }
 
@@ -4376,7 +4281,7 @@
      * Gets the chrome handler.
      * @return the current WebChromeClient instance.
      *
-     * @hide This is an implementation detail.
+     * This is an implementation detail.
      */
     public WebChromeClient getWebChromeClient() {
         return mCallbackProxy.getWebChromeClient();
@@ -4387,7 +4292,6 @@
      * WebBackForwardListClient for handling new items and changes in the
      * history index.
      * @param client An implementation of WebBackForwardListClient.
-     * {@hide}
      */
     public void setWebBackForwardListClient(WebBackForwardListClient client) {
         mCallbackProxy.setWebBackForwardListClient(client);
@@ -4395,7 +4299,6 @@
 
     /**
      * Gets the WebBackForwardListClient.
-     * {@hide}
      */
     public WebBackForwardListClient getWebBackForwardListClient() {
         return mCallbackProxy.getWebBackForwardListClient();
@@ -4407,21 +4310,14 @@
     @Override
     @Deprecated
     public void setPictureListener(PictureListener listener) {
-        checkThread();
         mPictureListener = listener;
     }
 
-    /**
-     * {@hide}
-     */
     /* FIXME: Debug only! Remove for SDK! */
     public void externalRepresentation(Message callback) {
         mWebViewCore.sendMessage(EventHub.REQUEST_EXT_REPRESENTATION, callback);
     }
 
-    /**
-     * {@hide}
-     */
     /* FIXME: Debug only! Remove for SDK! */
     public void documentAsText(Message callback) {
         mWebViewCore.sendMessage(EventHub.REQUEST_DOC_AS_TEXT, callback);
@@ -4432,7 +4328,6 @@
      */
     @Override
     public void addJavascriptInterface(Object object, String name) {
-        checkThread();
         if (object == null) {
             return;
         }
@@ -4447,7 +4342,6 @@
      */
     @Override
     public void removeJavascriptInterface(String interfaceName) {
-        checkThread();
         if (mWebViewCore != null) {
             WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
             arg.mInterfaceName = interfaceName;
@@ -4462,7 +4356,6 @@
      */
     @Override
     public WebSettingsClassic getSettings() {
-        checkThread();
         return (mWebViewCore != null) ? mWebViewCore.getSettings() : null;
     }
 
@@ -4471,7 +4364,6 @@
      */
     @Deprecated
     public static synchronized PluginList getPluginList() {
-        checkThread();
         return new PluginList();
     }
 
@@ -4480,7 +4372,6 @@
      */
     @Deprecated
     public void refreshPlugins(boolean reloadOpenPages) {
-        checkThread();
     }
 
     //-------------------------------------------------------------------------
@@ -4784,7 +4675,7 @@
     /**
      * Select the word at the last click point.
      *
-     * @hide This is an implementation detail.
+     * This is an implementation detail.
      */
     public boolean selectText() {
         int x = viewToContentX(mLastTouchX + getScrollX());
@@ -5135,7 +5026,7 @@
     /**
      * Dump the display tree to "/sdcard/displayTree.txt"
      *
-     * @hide debug only
+     * debug only
      */
     public void dumpDisplayTree() {
         nativeDumpDisplayTree(getUrl());
@@ -5145,7 +5036,7 @@
      * Dump the dom tree to adb shell if "toFile" is False, otherwise dump it to
      * "/sdcard/domTree.txt"
      *
-     * @hide debug only
+     * debug only
      */
     public void dumpDomTree(boolean toFile) {
         mWebViewCore.sendMessage(EventHub.DUMP_DOMTREE, toFile ? 1 : 0, 0);
@@ -5155,7 +5046,7 @@
      * Dump the render tree to adb shell if "toFile" is False, otherwise dump it
      * to "/sdcard/renderTree.txt"
      *
-     * @hide debug only
+     * debug only
      */
     public void dumpRenderTree(boolean toFile) {
         mWebViewCore.sendMessage(EventHub.DUMP_RENDERTREE, toFile ? 1 : 0, 0);
@@ -5164,7 +5055,7 @@
     /**
      * Called by DRT on UI thread, need to proxy to WebCore thread.
      *
-     * @hide debug only
+     * debug only
      */
     public void useMockDeviceOrientation() {
         mWebViewCore.sendMessage(EventHub.USE_MOCK_DEVICE_ORIENTATION);
@@ -5173,7 +5064,7 @@
     /**
      * Called by DRT on WebCore thread.
      *
-     * @hide debug only
+     * debug only
      */
     public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
             boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
@@ -5510,13 +5401,12 @@
     @Override
     @Deprecated
     public void emulateShiftHeld() {
-        checkThread();
     }
 
     /**
      * Select all of the text in this WebView.
      *
-     * @hide This is an implementation detail.
+     * This is an implementation detail.
      */
     public void selectAll() {
         mWebViewCore.sendMessage(EventHub.SELECT_ALL);
@@ -5548,7 +5438,7 @@
     /**
      * Copy the selection to the clipboard
      *
-     * @hide This is an implementation detail.
+     * This is an implementation detail.
      */
     public boolean copySelection() {
         boolean copiedSomething = false;
@@ -5575,7 +5465,7 @@
     /**
      * Cut the selected text into the clipboard
      *
-     * @hide This is an implementation detail
+     * This is an implementation detail
      */
     public void cutSelection() {
         copySelection();
@@ -5587,7 +5477,7 @@
     /**
      * Paste text from the clipboard to the cursor position.
      *
-     * @hide This is an implementation detail
+     * This is an implementation detail
      */
     public void pasteFromClipboard() {
         ClipboardManager cm = (ClipboardManager)mContext
@@ -5603,7 +5493,7 @@
     }
 
     /**
-     * @hide This is an implementation detail.
+     * This is an implementation detail.
      */
     public SearchBox getSearchBox() {
         if ((mWebViewCore == null) || (mWebViewCore.getBrowserFrame() == null)) {
@@ -5779,9 +5669,6 @@
                 mVisibleContentRect, getScale());
     }
 
-    /**
-     * @hide
-     */
     @Override
     public boolean setFrame(int left, int top, int right, int bottom) {
         boolean changed = mWebViewPrivate.super_setFrame(left, top, right, bottom);
@@ -6861,7 +6748,6 @@
     private DrawData mLoadedPicture;
 
     public void setMapTrackballToArrowKeys(boolean setMap) {
-        checkThread();
         mMapTrackballToArrowKeys = setMap;
     }
 
@@ -7088,7 +6974,6 @@
     }
 
     public void flingScroll(int vx, int vy) {
-        checkThread();
         mScroller.fling(getScrollX(), getScrollY(), vx, vy, 0, computeMaxScrollX(), 0,
                 computeMaxScrollY(), mOverflingDistance, mOverflingDistance);
         invalidate();
@@ -7210,7 +7095,6 @@
     @Override
     @Deprecated
     public View getZoomControls() {
-        checkThread();
         if (!getSettings().supportZoom()) {
             Log.w(LOGTAG, "This WebView doesn't support zoom.");
             return null;
@@ -7239,7 +7123,6 @@
      */
     @Override
     public boolean canZoomIn() {
-        checkThread();
         return mZoomManager.canZoomIn();
     }
 
@@ -7248,7 +7131,6 @@
      */
     @Override
     public boolean canZoomOut() {
-        checkThread();
         return mZoomManager.canZoomOut();
     }
 
@@ -7257,7 +7139,6 @@
      */
     @Override
     public boolean zoomIn() {
-        checkThread();
         return mZoomManager.zoomIn();
     }
 
@@ -7266,7 +7147,6 @@
      */
     @Override
     public boolean zoomOut() {
-        checkThread();
         return mZoomManager.zoomOut();
     }
 
@@ -7556,9 +7436,6 @@
         mWebViewCore.sendMessageDelayed(EventHub.SAVE_DOCUMENT_STATE, null, 1000);
     }
 
-    /**
-     * @hide
-     */
     public synchronized WebViewCore getWebViewCore() {
         return mWebViewCore;
     }
@@ -8740,7 +8617,7 @@
         void onPageSwapOccurred(boolean notifyAnimationStarted);
     }
 
-    /** @hide Called by JNI when pages are swapped (only occurs with hardware
+    /** Called by JNI when pages are swapped (only occurs with hardware
      * acceleration) */
     protected void pageSwapCallback(boolean notifyAnimationStarted) {
         mWebViewCore.resumeWebKitDraw();
@@ -9306,7 +9183,7 @@
      * view-specific zoom, scroll offset, or other changes. It does not draw
      * any view-specific chrome, such as progress or URL bars.
      *
-     * @hide only needs to be accessible to Browser and testing
+     * only needs to be accessible to Browser and testing
      */
     public void drawPage(Canvas canvas) {
         calcOurContentVisibleRectF(mVisibleContentRect);
@@ -9316,7 +9193,7 @@
     /**
      * Enable the communication b/t the webView and VideoViewProxy
      *
-     * @hide only used by the Browser
+     * only used by the Browser
      */
     public void setHTML5VideoViewProxy(HTML5VideoViewProxy proxy) {
         mHTML5VideoViewProxy = proxy;
@@ -9326,7 +9203,7 @@
      * Set the time to wait between passing touches to WebCore. See also the
      * TOUCH_SENT_INTERVAL member for further discussion.
      *
-     * @hide This is only used by the DRT test application.
+     * This is only used by the DRT test application.
      */
     public void setTouchInterval(int interval) {
         mCurrentTouchInterval = interval;
@@ -9353,26 +9230,14 @@
         return mViewManager;
     }
 
-    private static void checkThread() {
-        if (Looper.myLooper() != Looper.getMainLooper()) {
-            Throwable throwable = new Throwable(
-                    "Warning: A WebView method was called on thread '" +
-                    Thread.currentThread().getName() + "'. " +
-                    "All WebView methods must be called on the UI thread. " +
-                    "Future versions of WebView may not support use on other threads.");
-            Log.w(LOGTAG, Log.getStackTraceString(throwable));
-            StrictMode.onWebViewMethodCalledOnWrongThread(throwable);
-        }
-    }
-
-    /** @hide send content invalidate */
+    /** send content invalidate */
     protected void contentInvalidateAll() {
         if (mWebViewCore != null && !mBlockWebkitViewMessages) {
             mWebViewCore.sendMessage(EventHub.CONTENT_INVALIDATE_ALL);
         }
     }
 
-    /** @hide discard all textures from tiles. Used in Profiled WebView */
+    /** discard all textures from tiles. Used in Profiled WebView */
     public void discardAllTextures() {
         nativeDiscardAllTextures();
     }
@@ -9404,7 +9269,7 @@
     /**
      * Begin collecting per-tile profiling data
      *
-     * @hide only used by profiling tests
+     * only used by profiling tests
      */
     public void tileProfilingStart() {
         nativeTileProfilingStart();
@@ -9412,29 +9277,29 @@
     /**
      * Return per-tile profiling data
      *
-     * @hide only used by profiling tests
+     * only used by profiling tests
      */
     public float tileProfilingStop() {
         return nativeTileProfilingStop();
     }
 
-    /** @hide only used by profiling tests */
+    /** only used by profiling tests */
     public void tileProfilingClear() {
         nativeTileProfilingClear();
     }
-    /** @hide only used by profiling tests */
+    /** only used by profiling tests */
     public int tileProfilingNumFrames() {
         return nativeTileProfilingNumFrames();
     }
-    /** @hide only used by profiling tests */
+    /** only used by profiling tests */
     public int tileProfilingNumTilesInFrame(int frame) {
         return nativeTileProfilingNumTilesInFrame(frame);
     }
-    /** @hide only used by profiling tests */
+    /** only used by profiling tests */
     public int tileProfilingGetInt(int frame, int tile, String key) {
         return nativeTileProfilingGetInt(frame, tile, key);
     }
-    /** @hide only used by profiling tests */
+    /** only used by profiling tests */
     public float tileProfilingGetFloat(int frame, int tile, String key) {
         return nativeTileProfilingGetFloat(frame, tile, key);
     }
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index acc3c1c..5a7d519 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -105,6 +105,12 @@
      */
     public static final int MIN_PATTERN_REGISTER_FAIL = MIN_LOCK_PATTERN_SIZE;
 
+    /**
+     * The bit in LOCK_BIOMETRIC_WEAK_FLAGS to be used to indicate whether liveliness should
+     * be used
+     */
+    public static final int FLAG_BIOMETRIC_WEAK_LIVELINESS = 0x1;
+
     private final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
     private final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
     private final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
@@ -878,6 +884,28 @@
     }
 
     /**
+     * Set whether biometric weak liveliness is enabled.
+     */
+    public void setBiometricWeakLivelinessEnabled(boolean enabled) {
+        long currentFlag = getLong(Settings.Secure.LOCK_BIOMETRIC_WEAK_FLAGS, 0L);
+        long newFlag;
+        if (enabled) {
+            newFlag = currentFlag | FLAG_BIOMETRIC_WEAK_LIVELINESS;
+        } else {
+            newFlag = currentFlag & ~FLAG_BIOMETRIC_WEAK_LIVELINESS;
+        }
+        setLong(Settings.Secure.LOCK_BIOMETRIC_WEAK_FLAGS, newFlag);
+    }
+
+    /**
+     * @return Whether the biometric weak liveliness is enabled.
+     */
+    public boolean isBiometricWeakLivelinessEnabled() {
+        long currentFlag = getLong(Settings.Secure.LOCK_BIOMETRIC_WEAK_FLAGS, 0L);
+        return ((currentFlag & FLAG_BIOMETRIC_WEAK_LIVELINESS) != 0);
+    }
+
+    /**
      * Set whether the lock pattern is enabled.
      */
     public void setLockPatternEnabled(boolean enabled) {
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 392ea87..7c612ba 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -30,6 +30,7 @@
 class MemoryDealer;
 struct OMXCodecObserver;
 struct CodecProfileLevel;
+class SkipCutBuffer;
 
 struct OMXCodec : public MediaSource,
                   public MediaBufferObserver {
@@ -201,6 +202,7 @@
     ReadOptions::SeekMode mSeekMode;
     int64_t mTargetTimeUs;
     bool mOutputPortSettingsChangedPending;
+    SkipCutBuffer *mSkipCutBuffer;
 
     MediaBuffer *mLeftOverBuffer;
 
@@ -378,6 +380,7 @@
         const char *mimeType, bool queryDecoders,
         Vector<CodecCapabilities> *results);
 
+
 }  // namespace android
 
 #endif  // OMX_CODEC_H_
diff --git a/include/media/stagefright/SkipCutBuffer.h b/include/media/stagefright/SkipCutBuffer.h
new file mode 100644
index 0000000..5c7cd47
--- /dev/null
+++ b/include/media/stagefright/SkipCutBuffer.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 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 SKIP_CUT_BUFFER_H_
+
+#define SKIP_CUT_BUFFER_H_
+
+#include <media/stagefright/MediaBuffer.h>
+
+namespace android {
+
+/**
+ * utility class to cut the start and end off a stream of data in MediaBuffers
+ *
+ */
+class SkipCutBuffer {
+ public:
+    // 'skip' is the number of bytes to skip from the beginning
+    // 'cut' is the number of bytes to cut from the end
+    // 'output_size' is the size in bytes of the MediaBuffers that will be used
+    SkipCutBuffer(int32_t skip, int32_t cut, int32_t output_size);
+    virtual ~SkipCutBuffer();
+
+    // Submit one MediaBuffer for skipping and cutting. This may consume all or
+    // some of the data in the buffer, or it may add data to it.
+    // After this, the caller should continue processing the buffer as usual.
+    void submit(MediaBuffer *buffer);
+    void clear();
+    size_t size(); // how many bytes are currently stored in the buffer
+
+ private:
+    void write(const char *src, size_t num);
+    size_t read(char *dst, size_t num);
+    int32_t mFrontPadding;
+    int32_t mBackPadding;
+    int32_t mWriteHead;
+    int32_t mReadHead;
+    int32_t mCapacity;
+    char* mCutBuffer;
+    DISALLOW_EVIL_CONSTRUCTORS(SkipCutBuffer);
+};
+
+}  // namespace android
+
+#endif  // OMX_CODEC_H_
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 38d0374..4bbb04f 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -51,7 +51,7 @@
 
 // Set to 1 to enable native processing of View properties. 0 by default. Eventually this
 // will go away and we will always use this approach for accelerated apps.
-#define USE_DISPLAY_LIST_PROPERTIES 1
+#define USE_DISPLAY_LIST_PROPERTIES 0
 
 #define TRANSLATION 0x0001
 #define ROTATION    0x0002
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 21e8f29..43008d4 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -3,47 +3,26 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-    AudioParameter.cpp
-LOCAL_MODULE:= libmedia_helper
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    AudioTrack.cpp \
-    IAudioFlinger.cpp \
-    IAudioFlingerClient.cpp \
-    IAudioTrack.cpp \
-    IAudioRecord.cpp \
-    AudioRecord.cpp \
-    AudioSystem.cpp \
-    mediaplayer.cpp \
-    IMediaPlayerService.cpp \
-    IMediaPlayerClient.cpp \
-    IMediaRecorderClient.cpp \
-    IMediaPlayer.cpp \
-    IMediaRecorder.cpp \
-    IStreamSource.cpp \
-    Metadata.cpp \
-    mediarecorder.cpp \
-    IMediaMetadataRetriever.cpp \
-    mediametadataretriever.cpp \
-    ToneGenerator.cpp \
-    JetPlayer.cpp \
-    IOMX.cpp \
-    IAudioPolicyService.cpp \
-    MediaScanner.cpp \
-    MediaScannerClient.cpp \
     autodetect.cpp \
     IMediaDeathNotifier.cpp \
+    IMediaMetadataRetriever.cpp \
+    IMediaPlayerClient.cpp \
+    IMediaPlayer.cpp \
+    IMediaPlayerService.cpp \
+    IMediaRecorderClient.cpp \
+    IMediaRecorder.cpp \
+    IOMX.cpp \
+    IStreamSource.cpp \
+    JetPlayer.cpp \
+    mediametadataretriever.cpp \
+    mediaplayer.cpp \
     MediaProfiles.cpp \
-    IEffect.cpp \
-    IEffectClient.cpp \
-    AudioEffect.cpp \
-    Visualizer.cpp \
-    MemoryLeakTrackUtil.cpp
+    mediarecorder.cpp \
+    MediaScannerClient.cpp \
+    MediaScanner.cpp \
+    MemoryLeakTrackUtil.cpp \
+    Metadata.cpp \
+    Visualizer.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libui libcutils libutils libbinder libsonivox libicuuc libexpat \
diff --git a/media/libmedia_native/Android.mk b/media/libmedia_native/Android.mk
index 065a90f..07f0978 100644
--- a/media/libmedia_native/Android.mk
+++ b/media/libmedia_native/Android.mk
@@ -1,11 +1,39 @@
-LOCAL_PATH := $(call my-dir)
+# FIXME remove "/../libmedia" at same time as rename
+LOCAL_PATH := $(call my-dir)/../libmedia
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES :=
+LOCAL_SRC_FILES:= \
+    AudioParameter.cpp
+LOCAL_MODULE:= libmedia_helper
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+    AudioEffect.cpp \
+    AudioRecord.cpp \
+    AudioSystem.cpp \
+    AudioTrack.cpp \
+    IAudioFlingerClient.cpp \
+    IAudioFlinger.cpp \
+    IAudioPolicyService.cpp \
+    IAudioRecord.cpp \
+    IAudioTrack.cpp \
+    IEffectClient.cpp \
+    IEffect.cpp \
+    ToneGenerator.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libaudioutils libbinder libcutils libutils
 
 LOCAL_MODULE:= libmedia_native
 
+LOCAL_C_INCLUDES := \
+    $(call include-path-for, audio-utils)
+
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 77714f3..7d7bd7d 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -42,6 +42,7 @@
         OggExtractor.cpp                  \
         SampleIterator.cpp                \
         SampleTable.cpp                   \
+        SkipCutBuffer.cpp                 \
         StagefrightMediaScanner.cpp       \
         StagefrightMetadataRetriever.cpp  \
         SurfaceMediaSource.cpp            \
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index d5e6bec..8b6e9d5 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -38,6 +38,7 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/OMXCodec.h>
 #include <media/stagefright/Utils.h>
+#include <media/stagefright/SkipCutBuffer.h>
 #include <utils/Vector.h>
 
 #include <OMX_Audio.h>
@@ -1303,6 +1304,7 @@
       mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC),
       mTargetTimeUs(-1),
       mOutputPortSettingsChangedPending(false),
+      mSkipCutBuffer(NULL),
       mLeftOverBuffer(NULL),
       mPaused(false),
       mNativeWindow(
@@ -1413,6 +1415,9 @@
 
     free(mMIME);
     mMIME = NULL;
+
+    delete mSkipCutBuffer;
+    mSkipCutBuffer = NULL;
 }
 
 status_t OMXCodec::init() {
@@ -1573,6 +1578,34 @@
              portIndex == kPortIndexInput ? "input" : "output");
     }
 
+    if (portIndex == kPortIndexOutput) {
+
+        sp<MetaData> meta = mSource->getFormat();
+        int32_t delay = 0;
+        if (!meta->findInt32(kKeyEncoderDelay, &delay)) {
+            delay = 0;
+        }
+        int32_t padding = 0;
+        if (!meta->findInt32(kKeyEncoderPadding, &padding)) {
+            padding = 0;
+        }
+        int32_t numchannels = 0;
+        if (delay + padding) {
+            if (meta->findInt32(kKeyChannelCount, &numchannels)) {
+                size_t frameSize = numchannels * sizeof(int16_t);
+                if (mSkipCutBuffer) {
+                    size_t prevbuffersize = mSkipCutBuffer->size();
+                    if (prevbuffersize != 0) {
+                        ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbuffersize);
+                    }
+                    delete mSkipCutBuffer;
+                }
+                mSkipCutBuffer = new SkipCutBuffer(delay * frameSize, padding * frameSize,
+                                                   def.nBufferSize);
+            }
+        }
+    }
+
     // dumpPortStatus(portIndex);
 
     if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) {
@@ -2490,6 +2523,10 @@
             CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
                      mPortBuffers[portIndex].size());
 
+            if (mSkipCutBuffer && mPortStatus[kPortIndexOutput] == ENABLED) {
+                mSkipCutBuffer->clear();
+            }
+
             if (mState == RECONFIGURING) {
                 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
 
@@ -3800,6 +3837,9 @@
     info->mStatus = OWNED_BY_CLIENT;
 
     info->mMediaBuffer->add_ref();
+    if (mSkipCutBuffer) {
+        mSkipCutBuffer->submit(info->mMediaBuffer);
+    }
     *buffer = info->mMediaBuffer;
 
     return OK;
diff --git a/media/libstagefright/SkipCutBuffer.cpp b/media/libstagefright/SkipCutBuffer.cpp
new file mode 100755
index 0000000..6d331b0
--- /dev/null
+++ b/media/libstagefright/SkipCutBuffer.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "SkipCutBuffer"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/SkipCutBuffer.h>
+
+namespace android {
+
+SkipCutBuffer::SkipCutBuffer(int32_t skip, int32_t cut, int32_t output_size) {
+    mFrontPadding = skip;
+    mBackPadding = cut;
+    mWriteHead = 0;
+    mReadHead = 0;
+    mCapacity = cut + output_size;
+    mCutBuffer = new char[mCapacity];
+    ALOGV("skipcutbuffer %d %d %d", skip, cut, mCapacity);
+}
+
+SkipCutBuffer::~SkipCutBuffer() {
+    delete[] mCutBuffer;
+}
+
+void SkipCutBuffer::submit(MediaBuffer *buffer) {
+    int32_t offset = buffer->range_offset();
+    int32_t buflen = buffer->range_length();
+
+    // drop the initial data from the buffer if needed
+    if (mFrontPadding > 0) {
+        // still data left to drop
+        int32_t to_drop = (buflen < mFrontPadding) ? buflen : mFrontPadding;
+        offset += to_drop;
+        buflen -= to_drop;
+        buffer->set_range(offset, buflen);
+        mFrontPadding -= to_drop;
+    }
+
+
+    // append data to cutbuffer
+    char *src = ((char*) buffer->data()) + offset;
+    write(src, buflen);
+
+
+    // the mediabuffer is now empty. Fill it from cutbuffer, always leaving
+    // at least mBackPadding bytes in the cutbuffer
+    char *dst = (char*) buffer->data();
+    size_t copied = read(dst, buffer->size());
+    buffer->set_range(0, copied);
+}
+
+void SkipCutBuffer::clear() {
+    mWriteHead = mReadHead = 0;
+}
+
+void SkipCutBuffer::write(const char *src, size_t num) {
+    int32_t sizeused = (mWriteHead - mReadHead);
+    if (sizeused < 0) sizeused += mCapacity;
+
+    // everything must fit
+    CHECK_GE((mCapacity - size_t(sizeused)), num);
+
+    size_t copyfirst = (mCapacity - mWriteHead);
+    if (copyfirst > num) copyfirst = num;
+    if (copyfirst) {
+        memcpy(mCutBuffer + mWriteHead, src, copyfirst);
+        num -= copyfirst;
+        src += copyfirst;
+        mWriteHead += copyfirst;
+        CHECK_LE(mWriteHead, mCapacity);
+        if (mWriteHead == mCapacity) mWriteHead = 0;
+        if (num) {
+            memcpy(mCutBuffer, src, num);
+            mWriteHead += num;
+        }
+    }
+}
+
+size_t SkipCutBuffer::read(char *dst, size_t num) {
+    int32_t available = (mWriteHead - mReadHead);
+    if (available < 0) available += mCapacity;
+
+    available -= mBackPadding;
+    if (available <=0) {
+        return 0;
+    }
+    if (available < num) {
+        num = available;
+    }
+
+    size_t copyfirst = (mCapacity - mReadHead);
+    if (copyfirst > num) copyfirst = num;
+    if (copyfirst) {
+        memcpy(dst, mCutBuffer + mReadHead, copyfirst);
+        num -= copyfirst;
+        dst += copyfirst;
+        mReadHead += copyfirst;
+        CHECK_LE(mReadHead, mCapacity);
+        if (mReadHead == mCapacity) mReadHead = 0;
+        if (num) {
+            memcpy(dst, mCutBuffer, num);
+            mReadHead += num;
+        }
+    }
+    return available;
+}
+
+size_t SkipCutBuffer::size() {
+    int32_t available = (mWriteHead - mReadHead);
+    if (available < 0) available += mCapacity;
+    return available;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index ad55295..92009ee 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -115,6 +115,7 @@
     mDecoderBuf = malloc(memRequirements);
 
     pvmp3_InitDecoder(mConfig, mDecoderBuf);
+    mIsFirst = true;
 }
 
 OMX_ERRORTYPE SoftMP3::internalGetParameter(
@@ -190,7 +191,10 @@
             inInfo->mOwnedByUs = false;
             notifyEmptyBufferDone(inHeader);
 
-            outHeader->nFilledLen = 0;
+            // pad the end of the stream with 529 samples, since that many samples
+            // were trimmed off the beginning when decoding started
+            outHeader->nFilledLen = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
+            memset(outHeader->pBuffer, 0, outHeader->nFilledLen);
             outHeader->nFlags = OMX_BUFFERFLAG_EOS;
 
             outQueue.erase(outQueue.begin());
@@ -251,8 +255,17 @@
             return;
         }
 
-        outHeader->nOffset = 0;
-        outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t);
+        if (mIsFirst) {
+            mIsFirst = false;
+            // The decoder delay is 529 samples, so trim that many samples off
+            // the start of the first output buffer. This essentially makes this
+            // decoder have zero delay, which the rest of the pipeline assumes.
+            outHeader->nOffset = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
+            outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t) - outHeader->nOffset;
+        } else {
+            outHeader->nOffset = 0;
+            outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t);
+        }
 
         outHeader->nTimeStamp =
             mAnchorTimeUs
@@ -288,6 +301,7 @@
         // Make sure that the next buffer output does not still
         // depend on fragments from the last one decoded.
         pvmp3_InitDecoder(mConfig, mDecoderBuf);
+        mIsFirst = true;
     }
 }
 
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.h b/media/libstagefright/codecs/mp3dec/SoftMP3.h
index 70d0682..3a05466 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.h
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h
@@ -46,7 +46,8 @@
 private:
     enum {
         kNumBuffers = 4,
-        kOutputBufferSize = 4608 * 2
+        kOutputBufferSize = 4608 * 2,
+        kPVMP3DecoderDelay = 529 // frames
     };
 
     tPVMP3DecoderExternal *mConfig;
@@ -57,8 +58,7 @@
     int32_t mNumChannels;
     int32_t mSamplingRate;
 
-    bool mConfigured;
-
+    bool mIsFirst;
     bool mSignalledError;
 
     enum {