Merge "Properly initialize FBO textures for linear filtering."
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index cc6e739..d058e38 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -767,10 +767,10 @@
         boolean finished;
         boolean result;
 
-        public void packageDeleted(boolean succeeded) {
+        public void packageDeleted(String packageName, int returnCode) {
             synchronized (this) {
                 finished = true;
-                result = succeeded;
+                result = returnCode == PackageManager.DELETE_SUCCEEDED;
                 notifyAll();
             }
         }
diff --git a/core/java/android/app/DialogFragment.java b/core/java/android/app/DialogFragment.java
index 50953d7..dee1ef3 100644
--- a/core/java/android/app/DialogFragment.java
+++ b/core/java/android/app/DialogFragment.java
@@ -25,6 +25,9 @@
 import android.view.Window;
 import android.view.WindowManager;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
 /**
  * A fragment that displays a dialog window, floating on top of its
  * activity's window.  This fragment contains a Dialog object, which it
@@ -177,8 +180,9 @@
     int mBackStackId = -1;
 
     Dialog mDialog;
-    boolean mDestroyed;
-    boolean mRemoved;
+    boolean mViewDestroyed;
+    boolean mDismissed;
+    boolean mShownByMe;
 
     public DialogFragment() {
     }
@@ -219,6 +223,8 @@
      * {@link FragmentTransaction#add(Fragment, String) FragmentTransaction.add}.
      */
     public void show(FragmentManager manager, String tag) {
+        mDismissed = false;
+        mShownByMe = true;
         FragmentTransaction ft = manager.beginTransaction();
         ft.add(this, tag);
         ft.commit();
@@ -234,8 +240,10 @@
      * {@link FragmentTransaction#commit() FragmentTransaction.commit()}.
      */
     public int show(FragmentTransaction transaction, String tag) {
+        mDismissed = false;
+        mShownByMe = true;
         transaction.add(this, tag);
-        mRemoved = false;
+        mViewDestroyed = false;
         mBackStackId = transaction.commit();
         return mBackStackId;
     }
@@ -251,11 +259,16 @@
     }
 
     void dismissInternal(boolean allowStateLoss) {
+        if (mDismissed) {
+            return;
+        }
+        mDismissed = true;
+        mShownByMe = false;
         if (mDialog != null) {
             mDialog.dismiss();
             mDialog = null;
         }
-        mRemoved = true;
+        mViewDestroyed = true;
         if (mBackStackId >= 0) {
             getFragmentManager().popBackStack(mBackStackId,
                     FragmentManager.POP_BACK_STACK_INCLUSIVE);
@@ -329,6 +342,27 @@
     }
 
     @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        if (!mShownByMe) {
+            // If not explicitly shown through our API, take this as an
+            // indication that the dialog is no longer dismissed.
+            mDismissed = false;
+        }
+    }
+
+    @Override
+    public void onDetach() {
+        super.onDetach();
+        if (!mShownByMe && !mDismissed) {
+            // The fragment was not shown by a direct call here, it is not
+            // dismissed, and now it is being detached...  well, okay, thou
+            // art now dismissed.  Have fun.
+            mDismissed = true;
+        }
+    }
+
+    @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
@@ -352,7 +386,6 @@
         }
 
         mDialog = onCreateDialog(savedInstanceState);
-        mDestroyed = false;
         switch (mStyle) {
             case STYLE_NO_INPUT:
                 mDialog.getWindow().addFlags(
@@ -363,7 +396,11 @@
             case STYLE_NO_TITLE:
                 mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
         }
-        return (LayoutInflater)mDialog.getContext().getSystemService(
+        if (mDialog != null) {
+            return (LayoutInflater)mDialog.getContext().getSystemService(
+                    Context.LAYOUT_INFLATER_SERVICE);
+        }
+        return (LayoutInflater)mActivity.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
     }
     
@@ -397,7 +434,7 @@
     }
 
     public void onDismiss(DialogInterface dialog) {
-        if (!mRemoved) {
+        if (!mViewDestroyed) {
             // Note: we need to use allowStateLoss, because the dialog
             // dispatches this asynchronously so we can receive the call
             // after the activity is paused.  Worst case, when the user comes
@@ -439,7 +476,7 @@
     public void onStart() {
         super.onStart();
         if (mDialog != null) {
-            mRemoved = false;
+            mViewDestroyed = false;
             mDialog.show();
         }
     }
@@ -484,14 +521,28 @@
     @Override
     public void onDestroyView() {
         super.onDestroyView();
-        mDestroyed = true;
         if (mDialog != null) {
             // Set removed here because this dismissal is just to hide
             // the dialog -- we don't want this to cause the fragment to
             // actually be removed.
-            mRemoved = true;
+            mViewDestroyed = true;
             mDialog.dismiss();
             mDialog = null;
         }
     }
+
+    @Override
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        super.dump(prefix, fd, writer, args);
+        writer.print(prefix); writer.println("DialogFragment:");
+        writer.print(prefix); writer.print("  mStyle="); writer.print(mStyle);
+                writer.print(" mTheme=0x"); writer.println(Integer.toHexString(mTheme));
+        writer.print(prefix); writer.print("  mCancelable="); writer.print(mCancelable);
+                writer.print(" mShowsDialog="); writer.print(mShowsDialog);
+                writer.print(" mBackStackId="); writer.println(mBackStackId);
+        writer.print(prefix); writer.print("  mDialog="); writer.println(mDialog);
+        writer.print(prefix); writer.print("  mViewDestroyed="); writer.print(mViewDestroyed);
+                writer.print(" mDismissed="); writer.print(mDismissed);
+                writer.print(" mShownByMe="); writer.println(mShownByMe);
+    }
 }
diff --git a/core/java/android/content/pm/IPackageDeleteObserver.aidl b/core/java/android/content/pm/IPackageDeleteObserver.aidl
index bc16b3e..2e2d16e 100644
--- a/core/java/android/content/pm/IPackageDeleteObserver.aidl
+++ b/core/java/android/content/pm/IPackageDeleteObserver.aidl
@@ -23,6 +23,6 @@
  * {@hide}
  */
 oneway interface IPackageDeleteObserver {
-    void packageDeleted(in boolean succeeded);
+    void packageDeleted(in String packageName, in int returnCode);
 }
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 7525749..fc07478 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -552,9 +552,38 @@
     public static final int DONT_DELETE_DATA = 0x00000001;
 
     /**
+     * Return code for when package deletion succeeds. This is passed to the
+     * {@link IPackageDeleteObserver} by {@link #deletePackage()} if the system
+     * succeeded in deleting the package.
+     * 
+     * @hide
+     */
+    public static final int DELETE_SUCCEEDED = 1;
+
+    /**
+     * Deletion failed return code: this is passed to the
+     * {@link IPackageDeleteObserver} by {@link #deletePackage()} if the system
+     * failed to delete the package for an unspecified reason.
+     * 
+     * @hide
+     */
+    public static final int DELETE_FAILED_INTERNAL_ERROR = -1;
+
+    /**
+     * Deletion failed return code: this is passed to the
+     * {@link IPackageDeleteObserver} by {@link #deletePackage()} if the system
+     * failed to delete the package because it is the active DevicePolicy
+     * manager.
+     * 
+     * @hide
+     */
+    public static final int DELETE_FAILED_DEVICE_POLICY_MANAGER = -2;
+
+    /**
      * Return code that is passed to the {@link IPackageMoveObserver} by
-     * {@link #movePackage(android.net.Uri, IPackageMoveObserver)}
-     * when the package has been successfully moved by the system.
+     * {@link #movePackage(android.net.Uri, IPackageMoveObserver)} when the
+     * package has been successfully moved by the system.
+     * 
      * @hide
      */
     public static final int MOVE_SUCCEEDED = 1;
diff --git a/core/java/android/database/AbstractWindowedCursor.java b/core/java/android/database/AbstractWindowedCursor.java
index 8addaa8..3d95769 100644
--- a/core/java/android/database/AbstractWindowedCursor.java
+++ b/core/java/android/database/AbstractWindowedCursor.java
@@ -117,7 +117,8 @@
         super.checkPosition();
         
         if (mWindow == null) {
-            throw new StaleDataException("Attempting to access a closed cursor");
+            throw new StaleDataException("Attempting to access a closed CursorWindow." +
+                    "Most probable cause: cursor is deactivated prior to calling this method.");
         }
     }
 
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index bd78063..f7cbf7a 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -17,14 +17,12 @@
 package android.database;
 
 import android.content.res.Resources;
-import android.database.sqlite.DatabaseObjectNotClosedException;
 import android.database.sqlite.SQLiteClosable;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.Process;
-import android.os.StrictMode;
 import android.util.Log;
 import android.util.SparseIntArray;
 
@@ -47,7 +45,6 @@
     private int nWindow;
 
     private int mStartPos;
-    private final Throwable mStackTrace;
 
     /**
      * Creates a new empty window.
@@ -59,7 +56,6 @@
         int rslt = native_init(sCursorWindowSize, localWindow);
         printDebugMsgIfError(rslt);
         recordNewWindow(Binder.getCallingPid(), nWindow);
-        mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
     }
 
     private void printDebugMsgIfError(int rslt) {
@@ -568,12 +564,9 @@
         if (nWindow == 0) {
             return;
         }
-        if (StrictMode.vmSqliteObjectLeaksEnabled()) {
-            StrictMode.onSqliteObjectLeaked(
-                    "Releasing cursor in a finalizer. Please ensure " +
-                    "that you explicitly call close() on your cursor: ",
-                    mStackTrace);
-        }
+        // due to bugs 3329504, 3502276, cursorwindow sometimes is closed in fialize()
+        // don't print any warning saying "don't release cursor in finzlize"
+        // because it is a bug in framework code - NOT an app bug.
         recordClosingOfWindow(nWindow);
         close_native();
     }
@@ -606,7 +599,6 @@
         IBinder nativeBinder = source.readStrongBinder();
         mStartPos = source.readInt();
         int rslt = native_init(nativeBinder);
-        mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
         printDebugMsgIfError(rslt);
     }
 
diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java
index f750122..a408ea0 100644
--- a/core/java/android/net/Proxy.java
+++ b/core/java/android/net/Proxy.java
@@ -233,17 +233,11 @@
                 if (host.equalsIgnoreCase("localhost")) {
                     return true;
                 }
-                // Check we have a numeric address so we don't cause a DNS lookup in getByName.
-                if (InetAddress.isNumeric(host)) {
-                    if (InetAddress.getByName(host).isLoopbackAddress()) {
-                        return true;
-                    }
+                if (NetworkUtils.numericToInetAddress(host).isLoopbackAddress()) {
+                    return true;
                 }
             }
-        } catch (UnknownHostException ignored) {
-            // Can't happen for a numeric address (InetAddress.getByName).
         } catch (IllegalArgumentException iex) {
-            // Ignore (URI.create)
         }
         return false;
     }
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index a402c91..7dc36f9 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -392,4 +392,5 @@
     
     final private WeakReference mSelf;
     private int mObject;
+    private int mOrgue;
 }
diff --git a/core/java/android/server/BluetoothPanProfileHandler.java b/core/java/android/server/BluetoothPanProfileHandler.java
index 3f24811..8925856 100644
--- a/core/java/android/server/BluetoothPanProfileHandler.java
+++ b/core/java/android/server/BluetoothPanProfileHandler.java
@@ -28,6 +28,7 @@
 import android.net.ConnectivityManager;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
+import android.net.NetworkUtils;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.ServiceManager;
@@ -379,9 +380,9 @@
             if (ifcg != null) {
                 InetAddress addr = null;
                 if (ifcg.addr == null || (addr = ifcg.addr.getAddress()) == null ||
-                        addr.equals(InetAddress.getByName("0.0.0.0")) ||
-                        addr.equals(InetAddress.getByName("::0"))) {
-                    addr = InetAddress.getByName(address);
+                        addr.equals(NetworkUtils.numericToInetAddress("0.0.0.0")) ||
+                        addr.equals(NetworkUtils.numericToInetAddress("::0"))) {
+                    addr = NetworkUtils.numericToInetAddress(address);
                 }
                 ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up");
                 ifcg.addr = new LinkAddress(addr, BLUETOOTH_PREFIX_LENGTH);
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index e44e2e7..d6e36bb 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -295,6 +295,7 @@
     public void setCookie(String url, String value) {
         if (JniUtil.useChromiumHttpStack()) {
             setCookie(url, value, false);
+            return;
         }
 
         WebAddress uri;
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index ee0d122..88c8b2a 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -227,13 +227,10 @@
         assert density > 0;
 
         if (Math.abs(density - mDefaultScale) > MINIMUM_SCALE_INCREMENT) {
-            // Remember the current zoom density before it gets changed.
-            final float originalDefault = mDefaultScale;
             // set the new default density
             setDefaultZoomScale(density);
-            float scaleChange = (originalDefault > 0.0) ? density / originalDefault: 1.0f;
             // adjust the scale if it falls outside the new zoom bounds
-            setZoomScale(mActualScale * scaleChange, true);
+            setZoomScale(mActualScale, true);
         }
     }
 
@@ -725,7 +722,10 @@
         }
 
         public boolean onScale(ScaleGestureDetector detector) {
-            float scale = computeScaleWithLimits(detector.getScaleFactor() * mActualScale);
+            // Prevent scaling beyond overview scale.
+            float scale = Math.max(
+                    computeScaleWithLimits(detector.getScaleFactor() * mActualScale),
+                    getZoomOverviewScale());
             if (mPinchToZoomAnimating || willScaleTriggerZoom(scale)) {
                 mPinchToZoomAnimating = true;
                 // limit the scale change per step
@@ -781,6 +781,13 @@
 
         // update mMinZoomScale if the minimum zoom scale is not fixed
         if (!mMinZoomScaleFixed) {
+            // when change from narrow screen to wide screen, the new viewWidth
+            // can be wider than the old content width. We limit the minimum
+            // scale to 1.0f. The proper minimum scale will be calculated when
+            // the new picture shows up.
+            mMinZoomScale = Math.min(1.0f, (float) mWebView.getViewWidth()
+                    / (mWebView.drawHistory() ? mWebView.getHistoryPictureWidth()
+                            : mZoomOverviewWidth));
             // limit the minZoomScale to the initialScale if it is set
             if (mInitialScale > 0 && mInitialScale < mMinZoomScale) {
                 mMinZoomScale = mInitialScale;
@@ -817,7 +824,7 @@
                 // Keep overview mode unchanged when rotating.
                 final float zoomOverviewScale = getZoomOverviewScale();
                 final float newScale = (mInZoomOverviewBeforeSizeChange) ?
-                    zoomOverviewScale : mActualScale;
+                    zoomOverviewScale : Math.max(mActualScale, zoomOverviewScale); 
                 setZoomScale(newScale, mUpdateTextWrap, true);
                 // update the zoom buttons as the scale can be changed
                 updateZoomPicker();
@@ -873,15 +880,21 @@
             }
         }
 
+        if (!mMinZoomScaleFixed) {
+            mMinZoomScale = newZoomOverviewScale;
+        }
         // fit the content width to the current view for the first new picture
         // after first layout.
         boolean scaleHasDiff = exceedsMinScaleIncrement(newZoomOverviewScale, mActualScale);
+        // Make sure the actual scale is no less than zoom overview scale.
+        boolean scaleLessThanOverview =
+                (newZoomOverviewScale - mActualScale) >= MINIMUM_SCALE_INCREMENT;
         // Make sure mobile sites are correctly handled since mobile site will
         // change content width after rotating.
         boolean mobileSiteInOverview = mInZoomOverview &&
                 !exceedsMinScaleIncrement(newZoomOverviewScale, 1.0f);
         if (!mWebView.drawHistory() &&
-                (mInitialZoomOverview || mobileSiteInOverview) &&
+                (mInitialZoomOverview || scaleLessThanOverview || mobileSiteInOverview) &&
                 scaleHasDiff && zoomOverviewWidthChanged) {
             mInitialZoomOverview = false;
             setZoomScale(newZoomOverviewScale, !willScaleTriggerZoom(mTextWrapScale) &&
@@ -955,11 +968,10 @@
                 mTextWrapScale = viewState.mTextWrapScale;
                 scale = viewState.mViewScale;
             } else {
-                scale = mDefaultScale;
-                mTextWrapScale = mDefaultScale;
-                if (settings.getUseWideViewPort()
-                        && settings.getLoadWithOverviewMode()) {
-                    scale = Math.max(overviewScale, scale);
+                scale = overviewScale;
+                if (!settings.getUseWideViewPort()
+                    || !settings.getLoadWithOverviewMode()) {
+                    scale = Math.max(viewState.mTextWrapScale, scale);
                 }
                 if (settings.isNarrowColumnLayout() &&
                     settings.getUseFixedViewport()) {
@@ -970,7 +982,7 @@
             }
             boolean reflowText = false;
             if (!viewState.mIsRestored) {
-                if (settings.getUseFixedViewport() && settings.getLoadWithOverviewMode()) {
+                if (settings.getUseFixedViewport()) {
                     // Override the scale only in case of fixed viewport.
                     scale = Math.max(scale, overviewScale);
                     mTextWrapScale = Math.max(mTextWrapScale, overviewScale);
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 2925632..eca39fc 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -624,6 +624,9 @@
      */
     private boolean mForceTranscriptScroll;
 
+    private int mGlowPaddingLeft;
+    private int mGlowPaddingRight;
+
     /**
      * Interface definition for a callback to be invoked when the list or grid
      * has been scrolled.
@@ -3314,9 +3317,11 @@
             final int scrollY = mScrollY;
             if (!mEdgeGlowTop.isFinished()) {
                 final int restoreCount = canvas.save();
-                final int width = getWidth() - mListPadding.left - mListPadding.right;
+                final int leftPadding = mListPadding.left + mGlowPaddingLeft;
+                final int rightPadding = mListPadding.right + mGlowPaddingRight;
+                final int width = getWidth() - leftPadding - rightPadding;
 
-                canvas.translate(mListPadding.left,
+                canvas.translate(leftPadding,
                         Math.min(0, scrollY + mFirstPositionDistanceGuess));
                 mEdgeGlowTop.setSize(width, getHeight());
                 if (mEdgeGlowTop.draw(canvas)) {
@@ -3326,10 +3331,12 @@
             }
             if (!mEdgeGlowBottom.isFinished()) {
                 final int restoreCount = canvas.save();
-                final int width = getWidth() - mListPadding.left - mListPadding.right;
+                final int leftPadding = mListPadding.left + mGlowPaddingLeft;
+                final int rightPadding = mListPadding.right + mGlowPaddingRight;
+                final int width = getWidth() - leftPadding - rightPadding;
                 final int height = getHeight();
 
-                canvas.translate(-width + mListPadding.left,
+                canvas.translate(-width + leftPadding,
                         Math.max(height, scrollY + mLastPositionDistanceGuess));
                 canvas.rotate(180, width, 0);
                 mEdgeGlowBottom.setSize(width, height);
@@ -3353,6 +3360,14 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    public void setOverScrollEffectPadding(int leftPadding, int rightPadding) {
+        mGlowPaddingLeft = leftPadding;
+        mGlowPaddingRight = rightPadding;
+    }
+
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         int action = ev.getAction();
diff --git a/core/java/com/android/internal/net/DomainNameValidator.java b/core/java/com/android/internal/net/DomainNameValidator.java
index dbd5019..36973f1 100644
--- a/core/java/com/android/internal/net/DomainNameValidator.java
+++ b/core/java/com/android/internal/net/DomainNameValidator.java
@@ -15,12 +15,11 @@
  */
 package com.android.internal.net;
 
-
+import android.net.NetworkUtils;
 import android.util.Config;
 import android.util.Log;
 
 import java.net.InetAddress;
-import java.net.UnknownHostException;
 import java.security.cert.CertificateParsingException;
 import java.security.cert.X509Certificate;
 import java.util.Collection;
@@ -38,13 +37,6 @@
     private static final boolean DEBUG = false;
     private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
 
-    private static Pattern QUICK_IP_PATTERN;
-    static {
-        try {
-            QUICK_IP_PATTERN = Pattern.compile("^[a-f0-9\\.:]+$");
-        } catch (PatternSyntaxException e) {}
-    }
-
     private static final int ALT_DNS_NAME = 2;
     private static final int ALT_IPA_NAME = 7;
 
@@ -75,19 +67,11 @@
         if (rval) {
             try {
                 // do a quick-dirty IP match first to avoid DNS lookup
-                rval = QUICK_IP_PATTERN.matcher(domain).matches();
-                if (rval) {
-                    rval = domain.equals(
-                        InetAddress.getByName(domain).getHostAddress());
-                }
-            } catch (UnknownHostException e) {
-                String errorMessage = e.getMessage();
-                if (errorMessage == null) {
-                  errorMessage = "unknown host exception";
-                }
-
+                rval = domain.equals(
+                        NetworkUtils.numericToInetAddress(domain).getHostAddress());
+            } catch (IllegalArgumentException e) {
                 if (LOG_ENABLED) {
-                    Log.v(TAG, "DomainNameValidator.isIpAddress(): " + errorMessage);
+                    Log.v(TAG, "DomainNameValidator.isIpAddress(): " + e);
                 }
 
                 rval = false;
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 15362eb..5deed1e 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -105,6 +105,7 @@
     // Object state.
     jfieldID mObject;
     jfieldID mSelf;
+    jfieldID mOrgue;
 
 } gBinderProxyOffsets;
 
@@ -374,12 +375,12 @@
 class JavaDeathRecipient : public IBinder::DeathRecipient
 {
 public:
-    JavaDeathRecipient(JNIEnv* env, jobject object, sp<DeathRecipientList>& list)
+    JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
         : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)), mList(list)
     {
         // These objects manage their own lifetimes so are responsible for final bookkeeping.
         // The list holds a strong reference to this object.
-        mList->add(this);
+        list->add(this);
 
         android_atomic_inc(&gNumDeathRefs);
         incRefsCreated(env);
@@ -404,7 +405,10 @@
 
     void clearReference()
     {
-        mList->remove(this);
+        sp<DeathRecipientList> list = mList.promote();
+        if (list != NULL) {
+            list->remove(this);
+        }
     }
 
     bool matches(jobject obj) {
@@ -424,7 +428,7 @@
 private:
     JavaVM* const   mVM;
     jobject const   mObject;
-    sp<DeathRecipientList> mList;
+    wp<DeathRecipientList> mList;
 };
 
 // ----------------------------------------------------------------------------
@@ -436,7 +440,7 @@
     // to the list are holding references on the list object.  Only when they are torn
     // down can the list header be destroyed.
     if (mList.size() > 0) {
-        LOGE("Retiring binder %p with extant death recipients\n", this);
+        LOGE("Retiring DRL %p with extant death recipients\n", this);
     }
 }
 
@@ -470,9 +474,6 @@
     return NULL;
 }
 
-static KeyedVector<IBinder*, sp<DeathRecipientList> > gDeathRecipientsByIBinder;
-static Mutex gDeathRecipientMapLock;
-
 // ----------------------------------------------------------------------------
 
 namespace android {
@@ -517,7 +518,7 @@
 
     object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
     if (object != NULL) {
-        LOGV("objectForBinder %p: created new %p!\n", val.get(), object);
+        LOGV("objectForBinder %p: created new proxy %p !\n", val.get(), object);
         // The proxy holds a reference to the native object.
         env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
         val->incStrong(object);
@@ -529,6 +530,11 @@
         val->attachObject(&gBinderProxyOffsets, refObject,
                 jnienv_to_javavm(env), proxy_cleanup);
 
+        // Also remember the death recipients registered on this proxy
+        sp<DeathRecipientList> drl = new DeathRecipientList;
+        drl->incStrong((void*)javaObjectForIBinder);
+        env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get()));
+
         // Note that a new object reference has been created.
         android_atomic_inc(&gNumProxyRefs);
         incRefsCreated(env);
@@ -1027,24 +1033,9 @@
     LOGV("linkToDeath: binder=%p recipient=%p\n", target, recipient);
 
     if (!target->localBinder()) {
-        sp<JavaDeathRecipient> jdr;
-
-        {
-            sp<DeathRecipientList> list;
-            AutoMutex _maplocker(gDeathRecipientMapLock);
-
-            ssize_t listIndex = gDeathRecipientsByIBinder.indexOfKey(target);
-            if (listIndex < 0) {
-                // Set up the death notice bookkeeping for this binder lazily
-                list = new DeathRecipientList;
-                gDeathRecipientsByIBinder.add(target, list);
-            } else {
-                list = gDeathRecipientsByIBinder.valueAt(listIndex);
-            }
-
-            jdr = new JavaDeathRecipient(env, recipient, list);
-        }
-
+        DeathRecipientList* list = (DeathRecipientList*)
+                env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
+        sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
         status_t err = target->linkToDeath(jdr, NULL, flags);
         if (err != NO_ERROR) {
             // Failure adding the death recipient, so clear its reference
@@ -1075,20 +1066,11 @@
 
     if (!target->localBinder()) {
         status_t err = NAME_NOT_FOUND;
-        sp<JavaDeathRecipient> origJDR;
-        {
-            AutoMutex _maplocker(gDeathRecipientMapLock);
-            ssize_t listIndex = gDeathRecipientsByIBinder.indexOfKey(target);
-            if (listIndex >= 0) {
-                sp<DeathRecipientList> list = gDeathRecipientsByIBinder.valueAt(listIndex);
-                origJDR = list->find(recipient);
-            } else {
-                // If there is no DeathRecipientList for this binder, it means the binder
-                // is dead and in the process of being cleaned up.
-                err = DEAD_OBJECT;
-            }
-        }
-        // If we found the matching recipient, proceed to unlink using that
+
+        // If we find the matching recipient, proceed to unlink using that
+        DeathRecipientList* list = (DeathRecipientList*)
+                env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
+        sp<JavaDeathRecipient> origJDR = list->find(recipient);
         if (origJDR != NULL) {
             wp<IBinder::DeathRecipient> dr;
             err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
@@ -1115,20 +1097,17 @@
 static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
 {
     IBinder* b = (IBinder*)
-        env->GetIntField(obj, gBinderProxyOffsets.mObject);
-    LOGV("Destroying BinderProxy %p: binder=%p\n", obj, b);
-    env->SetIntField(obj, gBinderProxyOffsets.mObject, 0);
-    b->decStrong(obj);
-    IPCThreadState::self()->flushCommands();
+            env->GetIntField(obj, gBinderProxyOffsets.mObject);
+    DeathRecipientList* drl = (DeathRecipientList*)
+            env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
 
-    // tear down the death recipient bookkeeping
-    {
-        AutoMutex _maplocker(gDeathRecipientMapLock);
-        ssize_t listIndex = gDeathRecipientsByIBinder.indexOfKey(b);
-        if (listIndex >= 0) {
-            gDeathRecipientsByIBinder.removeItemsAt((size_t)listIndex);
-        }
-    }
+    LOGV("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
+    env->SetIntField(obj, gBinderProxyOffsets.mObject, 0);
+    env->SetIntField(obj, gBinderProxyOffsets.mOrgue, 0);
+    drl->decStrong((void*)javaObjectForIBinder);
+    b->decStrong(obj);
+
+    IPCThreadState::self()->flushCommands();
 }
 
 // ----------------------------------------------------------------------------
@@ -1178,6 +1157,9 @@
     gBinderProxyOffsets.mSelf
         = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;");
     assert(gBinderProxyOffsets.mSelf);
+    gBinderProxyOffsets.mOrgue
+        = env->GetFieldID(clazz, "mOrgue", "I");
+    assert(gBinderProxyOffsets.mOrgue);
 
     return AndroidRuntime::registerNativeMethods(
         env, kBinderProxyPathName,
diff --git a/core/res/res/drawable-hdpi/btn_check_off_holo.png b/core/res/res/drawable-hdpi/btn_check_off_holo.png
new file mode 100644
index 0000000..4021a3b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_off_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_holo.png b/core/res/res/drawable-hdpi/btn_check_on_holo.png
new file mode 100644
index 0000000..4c1bfbc
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_on_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_off_holo.png b/core/res/res/drawable-hdpi/btn_radio_off_holo.png
new file mode 100644
index 0000000..f159c62
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_radio_off_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_on_holo.png b/core/res/res/drawable-hdpi/btn_radio_on_holo.png
new file mode 100644
index 0000000..0fcfbe1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_radio_on_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_holo.png b/core/res/res/drawable-mdpi/btn_check_off_holo.png
new file mode 100644
index 0000000..67d70b4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_off_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_holo.png b/core/res/res/drawable-mdpi/btn_check_on_holo.png
new file mode 100644
index 0000000..38ab51a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_on_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_off_holo.png b/core/res/res/drawable-mdpi/btn_radio_off_holo.png
new file mode 100644
index 0000000..ba90d96
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_radio_off_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_on_holo.png b/core/res/res/drawable-mdpi/btn_radio_on_holo.png
new file mode 100644
index 0000000..41b603c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_radio_on_holo.png
Binary files differ
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 7af64e4..5d28ef7 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -769,9 +769,9 @@
             return doneFlag;
         }
 
-        public void packageDeleted(boolean succeeded) throws RemoteException {
+        public void packageDeleted(String packageName, int returnCode) throws RemoteException {
             synchronized(this) {
-                this.succeeded = succeeded;
+                this.succeeded = returnCode == PackageManager.DELETE_SUCCEEDED;
                 doneFlag = true;
                 notifyAll();
             }
diff --git a/data/etc/android.hardware.usb.accessory.xml b/data/etc/android.hardware.usb.accessory.xml
index 29df966..80a0904 100644
--- a/data/etc/android.hardware.usb.accessory.xml
+++ b/data/etc/android.hardware.usb.accessory.xml
@@ -17,4 +17,6 @@
 <!-- This is the standard feature indicating that the device supports USB accessories. -->
 <permissions>
     <feature name="android.hardware.usb.accessory" />
+    <library name="com.android.future.usb.accessory"
+            file="/system/framework/com.android.future.usb.accessory.jar" />
 </permissions>
diff --git a/data/etc/com.google.android.usb.xml b/data/etc/com.google.android.usb.xml
deleted file mode 100644
index fae3d23..0000000
--- a/data/etc/com.google.android.usb.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-
-<permissions>
-    <library name="com.google.android.usb"
-            file="/system/framework/com.google.android.usb.jar" />
-</permissions>
diff --git a/data/sounds/AudioPackage2.mk b/data/sounds/AudioPackage2.mk
index d7f7c7e..1a36cba 100644
--- a/data/sounds/AudioPackage2.mk
+++ b/data/sounds/AudioPackage2.mk
@@ -23,7 +23,31 @@
 	$(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
 	$(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
 	$(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \
+	$(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
+	$(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
+	$(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
+	$(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
+	$(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
+	$(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
+	$(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
+	$(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
+	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+	$(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
+	$(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
+	$(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
+	$(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
+	$(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \
+	$(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
+	$(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
+	$(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \
 	$(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \
+	$(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg
+
+ifneq ($(MINIMAL_NEWWAVELABS),true)
+PRODUCT_COPY_FILES += \
 	$(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \
 	$(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \
 	$(LOCAL_PATH)/newwavelabs/CaribbeanIce.ogg:system/media/audio/ringtones/CaribbeanIce.ogg \
@@ -49,29 +73,12 @@
 	$(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \
 	$(LOCAL_PATH)/newwavelabs/VeryAlarmed.ogg:system/media/audio/ringtones/VeryAlarmed.ogg \
 	$(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg \
-	$(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg \
 	$(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \
 	$(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \
 	$(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \
 	$(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \
 	$(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \
 	$(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \
-	$(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
-	$(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
-	$(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
-	$(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
-	$(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
-	$(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
-	$(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
-	$(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
-	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
-	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
-	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
-	$(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
-	$(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
-	$(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
-	$(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
-	$(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
 	$(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:system/media/audio/ringtones/CrazyDream.ogg \
 	$(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:system/media/audio/ringtones/DreamTheme.ogg \
 	$(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \
@@ -93,9 +100,5 @@
 	$(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:system/media/audio/ringtones/Shes_All_That.ogg \
 	$(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:system/media/audio/ringtones/Steppin_Out.ogg \
 	$(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:system/media/audio/ringtones/Third_Eye.ogg \
-	$(LOCAL_PATH)/newwavelabs/Thunderfoot.ogg:system/media/audio/ringtones/Thunderfoot.ogg \
-	$(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \
-	$(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
-	$(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
-	$(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg
-
+	$(LOCAL_PATH)/newwavelabs/Thunderfoot.ogg:system/media/audio/ringtones/Thunderfoot.ogg
+endif
diff --git a/data/sounds/AudioPackage3.mk b/data/sounds/AudioPackage3.mk
index 64d6717..146c2e4 100644
--- a/data/sounds/AudioPackage3.mk
+++ b/data/sounds/AudioPackage3.mk
@@ -1,5 +1,5 @@
 #
-# Audio Package 2
+# Audio Package 3
 # 
 # Include this file in a product makefile to include these audio files
 #
@@ -23,7 +23,31 @@
 	$(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
 	$(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
 	$(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \
+	$(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
+	$(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
+	$(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
+	$(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
+	$(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
+	$(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
+	$(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
+	$(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
+	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+	$(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
+	$(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
+	$(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
+	$(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
+	$(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \
+	$(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
+	$(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
+	$(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \
 	$(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \
+	$(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg
+
+ifneq ($(MINIMAL_NEWWAVELABS),true)
+PRODUCT_COPY_FILES += \
 	$(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \
 	$(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \
 	$(LOCAL_PATH)/newwavelabs/CurveBall.ogg:system/media/audio/ringtones/CurveBall.ogg \
@@ -41,29 +65,12 @@
 	$(LOCAL_PATH)/newwavelabs/Terminated.ogg:system/media/audio/ringtones/Terminated.ogg \
 	$(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \
 	$(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg \
-	$(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg \
 	$(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \
 	$(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \
 	$(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \
 	$(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \
 	$(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \
 	$(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \
-	$(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
-	$(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
-	$(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
-	$(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
-	$(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
-	$(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
-	$(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
-	$(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
-	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
-	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
-	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
-	$(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
-	$(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
-	$(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
-	$(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
-	$(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
 	$(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \
 	$(LOCAL_PATH)/newwavelabs/Bollywood.ogg:system/media/audio/ringtones/Bollywood.ogg \
 	$(LOCAL_PATH)/newwavelabs/Cairo.ogg:system/media/audio/ringtones/Cairo.ogg \
@@ -89,8 +96,5 @@
 	$(LOCAL_PATH)/newwavelabs/BussaMove.ogg:system/media/audio/ringtones/BussaMove.ogg \
 	$(LOCAL_PATH)/newwavelabs/DonMessWivIt.ogg:system/media/audio/ringtones/DonMessWivIt.ogg \
 	$(LOCAL_PATH)/newwavelabs/SilkyWay.ogg:system/media/audio/ringtones/SilkyWay.ogg \
-	$(LOCAL_PATH)/newwavelabs/Playa.ogg:system/media/audio/ringtones/Playa.ogg \
-	$(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \
-	$(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
-	$(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
-	$(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg
+	$(LOCAL_PATH)/newwavelabs/Playa.ogg:system/media/audio/ringtones/Playa.ogg
+endif
diff --git a/data/sounds/AudioPackage4.mk b/data/sounds/AudioPackage4.mk
index b011b78..712d7aa 100644
--- a/data/sounds/AudioPackage4.mk
+++ b/data/sounds/AudioPackage4.mk
@@ -1,5 +1,5 @@
 #
-# Audio Package 2
+# Audio Package 4
 # 
 # Include this file in a product makefile to include these audio files
 #
@@ -27,13 +27,6 @@
 	$(LOCAL_PATH)/notifications/SpaceSeed.ogg:system/media/audio/notifications/SpaceSeed.ogg \
 	$(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
 	$(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
-	$(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg \
-	$(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \
-	$(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \
-	$(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \
-	$(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \
-	$(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \
-	$(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \
 	$(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \
 	$(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
 	$(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
@@ -55,7 +48,18 @@
 	$(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
 	$(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
 	$(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \
+	$(LOCAL_PATH)/ringtones/FreeFlight.ogg:system/media/audio/ringtones/FreeFlight.ogg \
 	$(LOCAL_PATH)/newwavelabs/Backroad.ogg:system/media/audio/ringtones/Backroad.ogg \
+	$(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg
+
+ifneq ($(MINIMAL_NEWWAVELABS),true)
+PRODUCT_COPY_FILES += \
+	$(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \
+	$(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \
+	$(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \
+	$(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \
+	$(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \
+	$(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \
 	$(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \
 	$(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \
 	$(LOCAL_PATH)/newwavelabs/Bollywood.ogg:system/media/audio/ringtones/Bollywood.ogg \
@@ -72,7 +76,6 @@
 	$(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:system/media/audio/ringtones/Eastern_Sky.ogg \
 	$(LOCAL_PATH)/newwavelabs/Enter_the_Nexus.ogg:system/media/audio/ringtones/Enter_the_Nexus.ogg \
 	$(LOCAL_PATH)/newwavelabs/EtherShake.ogg:system/media/audio/ringtones/EtherShake.ogg \
-	$(LOCAL_PATH)/ringtones/FreeFlight.ogg:system/media/audio/ringtones/FreeFlight.ogg \
 	$(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:system/media/audio/ringtones/Funk_Yall.ogg \
 	$(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:system/media/audio/ringtones/Gimme_Mo_Town.ogg \
 	$(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:system/media/audio/ringtones/Glacial_Groove.ogg \
@@ -97,5 +100,5 @@
 	$(LOCAL_PATH)/newwavelabs/Terminated.ogg:system/media/audio/ringtones/Terminated.ogg \
 	$(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:system/media/audio/ringtones/Third_Eye.ogg \
 	$(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \
-	$(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg 
-
+	$(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg
+endif
diff --git a/data/sounds/OriginalAudio.mk b/data/sounds/OriginalAudio.mk
index 291f0b6..e1ca24b 100644
--- a/data/sounds/OriginalAudio.mk
+++ b/data/sounds/OriginalAudio.mk
@@ -22,7 +22,22 @@
 	$(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
 	$(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
 	$(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \
+	$(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
+	$(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
+	$(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
+	$(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
+	$(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
+	$(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
+	$(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
+	$(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
+	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \
+	$(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg
+
+ifneq ($(MINIMAL_NEWWAVELABS),true)
+PRODUCT_COPY_FILES += \
 	$(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \
 	$(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \
 	$(LOCAL_PATH)/newwavelabs/CaribbeanIce.ogg:system/media/audio/ringtones/CaribbeanIce.ogg \
@@ -48,23 +63,12 @@
 	$(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \
 	$(LOCAL_PATH)/newwavelabs/VeryAlarmed.ogg:system/media/audio/ringtones/VeryAlarmed.ogg \
 	$(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg \
-	$(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg \
 	$(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \
 	$(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \
 	$(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \
 	$(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \
 	$(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \
 	$(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \
-	$(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
-	$(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
-	$(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
-	$(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
-	$(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
-	$(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
-	$(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
-	$(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
-	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
-	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
-	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:system/media/audio/ringtones/CrazyDream.ogg \
 	$(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:system/media/audio/ringtones/DreamTheme.ogg
+endif
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index 3f9f961..b8e9384 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -17,83 +17,93 @@
 package android.graphics;
 
 public class ImageFormat {
-	/*
-	 * these constants are chosen to be binary compatible with their previous
-	 * location in PixelFormat.java
-	 */
+    /*
+     * these constants are chosen to be binary compatible with their previous
+     * location in PixelFormat.java
+     */
 
-	public static final int UNKNOWN = 0;
+    public static final int UNKNOWN = 0;
 
-	/**
-	 * RGB format used for pictures encoded as RGB_565 see
-	 * {@link android.hardware.Camera.Parameters#setPictureFormat(int)}.
-	 */
-	public static final int RGB_565 = 4;
+    /**
+     * RGB format used for pictures encoded as RGB_565 see
+     * {@link android.hardware.Camera.Parameters#setPictureFormat(int)}.
+     */
+    public static final int RGB_565 = 4;
 
-	/**
-	 * Planar 4:2:0 YCrCb format. This format assumes an horizontal stride of 16
-	 * pixels for all planes and an implicit vertical stride of the image
-	 * height's next multiple of two.
-	 *   y_size = stride * ALIGN(height, 2)
-	 *   c_size = ALIGN(stride/2, 16) * height
-	 *   size = y_size + c_size * 2
-	 *   cr_offset = y_size
-	 *   cb_offset = y_size + c_size
-	 * 
-	 * Whether this format is supported by the camera hardware can be determined
-	 * by
-	 * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
-	 */
-	public static final int YV12 = 0x32315659;
+    /**
+     * Android YUV format:
+     *
+     * This format is exposed to software decoders and applications.
+     *
+     * YV12 is a 4:2:0 YCrCb planar format comprised of a WxH Y plane followed
+     * by (W/2) x (H/2) Cr and Cb planes.
+     *
+     * This format assumes
+     * - an even width
+     * - an even height
+     * - a horizontal stride multiple of 16 pixels
+     * - a vertical stride equal to the height
+     *
+     *   y_size = stride * height
+     *   c_size = ALIGN(stride/2, 16) * height/2
+     *   size = y_size + c_size * 2
+     *   cr_offset = y_size
+     *   cb_offset = y_size + c_size
+     *
+     * Whether this format is supported by the camera hardware can be determined
+     * by
+     * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
+     */
+    public static final int YV12 = 0x32315659;
 
-	/**
-	 * YCbCr format, used for video. Whether this format is supported by the
-	 * camera hardware can be determined by
-	 * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
-	 */
-	public static final int NV16 = 0x10;
+    /**
+     * YCbCr format, used for video. Whether this format is supported by the
+     * camera hardware can be determined by
+     * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
+     */
+    public static final int NV16 = 0x10;
 
-	/**
-	 * YCrCb format used for images, which uses the NV21 encoding format. This
-	 * is the default format for camera preview images, when not otherwise set
-	 * with {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}.
-	 */
-	public static final int NV21 = 0x11;
+    /**
+     * YCrCb format used for images, which uses the NV21 encoding format. This
+     * is the default format for camera preview images, when not otherwise set
+     * with {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}.
+     */
+    public static final int NV21 = 0x11;
 
-	/**
-	 * YCbCr format used for images, which uses YUYV (YUY2) encoding format.
-	 * This is an alternative format for camera preview images. Whether this
-	 * format is supported by the camera hardware can be determined by
-	 * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
-	 */
-	public static final int YUY2 = 0x14;
+    /**
+     * YCbCr format used for images, which uses YUYV (YUY2) encoding format.
+     * This is an alternative format for camera preview images. Whether this
+     * format is supported by the camera hardware can be determined by
+     * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
+     */
+    public static final int YUY2 = 0x14;
 
-	/**
-	 * Encoded formats. These are not necessarily supported by the hardware.
-	 */
-	public static final int JPEG = 0x100;
+    /**
+     * Encoded formats. These are not necessarily supported by the hardware.
+     */
+    public static final int JPEG = 0x100;
 
-	/**
-	 * Use this function to retrieve the number of bits per pixel of an
-	 * ImageFormat.
-	 * 
-	 * @param format
-	 * @return the number of bits per pixel of the given format or -1 if the
-	 *         format doesn't exist or is not supported.
-	 */
-	public static int getBitsPerPixel(int format) {
-		switch (format) {
-		case RGB_565:
-			return 16;
-		case NV16:
-			return 16;
-		case YUY2:
-			return 16;
-		case YV12:
-			return 12;
-		case NV21:
-			return 12;
-		}
-		return -1;
-	}
+    /**
+     * Use this function to retrieve the number of bits per pixel of an
+     * ImageFormat.
+     * 
+     * @param format
+     * @return the number of bits per pixel of the given format or -1 if the
+     *         format doesn't exist or is not supported.
+     */
+    public static int getBitsPerPixel(int format) {
+        switch (format) {
+            case RGB_565:
+                return 16;
+            case NV16:
+                return 16;
+            case YUY2:
+                return 16;
+            case YV12:
+                return 12;
+            case NV21:
+                return 12;
+        }
+        return -1;
+    }
 }
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index aa97874..f2107ec 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -24,6 +24,7 @@
 namespace android {
 
 enum camcorder_quality {
+    CAMCORDER_QUALITY_LIST_START = 0,
     CAMCORDER_QUALITY_LOW  = 0,
     CAMCORDER_QUALITY_HIGH = 1,
     CAMCORDER_QUALITY_QCIF = 2,
@@ -31,14 +32,17 @@
     CAMCORDER_QUALITY_480P = 4,
     CAMCORDER_QUALITY_720P = 5,
     CAMCORDER_QUALITY_1080P = 6,
+    CAMCORDER_QUALITY_LIST_END = 6,
 
+    CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000,
     CAMCORDER_QUALITY_TIME_LAPSE_LOW  = 1000,
     CAMCORDER_QUALITY_TIME_LAPSE_HIGH = 1001,
     CAMCORDER_QUALITY_TIME_LAPSE_QCIF = 1002,
     CAMCORDER_QUALITY_TIME_LAPSE_CIF = 1003,
     CAMCORDER_QUALITY_TIME_LAPSE_480P = 1004,
     CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005,
-    CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006
+    CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006,
+    CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1006,
 };
 
 enum video_decoder {
@@ -147,6 +151,11 @@
     Vector<int> getImageEncodingQualityLevels(int cameraId) const;
 
 private:
+    enum {
+        // Camcorder profiles (high/low) and timelapse profiles (high/low)
+        kNumRequiredProfiles = 4,
+    };
+
     MediaProfiles& operator=(const MediaProfiles&);  // Don't call me
     MediaProfiles(const MediaProfiles&);             // Don't call me
     MediaProfiles() {}                               // Dummy default constructor
@@ -160,6 +169,14 @@
               mFrameHeight(frameHeight),
               mFrameRate(frameRate) {}
 
+        VideoCodec(const VideoCodec& copy) {
+            mCodec = copy.mCodec;
+            mBitRate = copy.mBitRate;
+            mFrameWidth = copy.mFrameWidth;
+            mFrameHeight = copy.mFrameHeight;
+            mFrameRate = copy.mFrameRate;
+        }
+
         ~VideoCodec() {}
 
         video_encoder mCodec;
@@ -176,6 +193,13 @@
               mSampleRate(sampleRate),
               mChannels(channels) {}
 
+        AudioCodec(const AudioCodec& copy) {
+            mCodec = copy.mCodec;
+            mBitRate = copy.mBitRate;
+            mSampleRate = copy.mSampleRate;
+            mChannels = copy.mChannels;
+        }
+
         ~AudioCodec() {}
 
         audio_encoder mCodec;
@@ -193,6 +217,15 @@
               mVideoCodec(0),
               mAudioCodec(0) {}
 
+        CamcorderProfile(const CamcorderProfile& copy) {
+            mCameraId = copy.mCameraId;
+            mFileFormat = copy.mFileFormat;
+            mQuality = copy.mQuality;
+            mDuration = copy.mDuration;
+            mVideoCodec = new VideoCodec(*copy.mVideoCodec);
+            mAudioCodec = new AudioCodec(*copy.mAudioCodec);
+        }
+
         ~CamcorderProfile() {
             delete mVideoCodec;
             delete mAudioCodec;
@@ -272,6 +305,8 @@
     };
 
     int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;
+    void initRequiredProfileRefs(const Vector<int>& cameraIds);
+    int getRequiredProfileRefIndex(int cameraId);
 
     // Debug
     static void logVideoCodec(const VideoCodec& codec);
@@ -291,7 +326,10 @@
     static VideoDecoderCap* createVideoDecoderCap(const char **atts);
     static VideoEncoderCap* createVideoEncoderCap(const char **atts);
     static AudioEncoderCap* createAudioEncoderCap(const char **atts);
-    static CamcorderProfile* createCamcorderProfile(int cameraId, const char **atts);
+
+    static CamcorderProfile* createCamcorderProfile(
+                int cameraId, const char **atts, Vector<int>& cameraIds);
+
     static int getCameraId(const char **atts);
 
     ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const;
@@ -335,6 +373,21 @@
 
     static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name);
 
+    /**
+     * Check on existing profiles with the following criteria:
+     * 1. Low quality profile must have the lowest video
+     *    resolution product (width x height)
+     * 2. High quality profile must have the highest video
+     *    resolution product (width x height)
+     *
+     * and add required low/high quality camcorder/timelapse
+     * profiles if they are not found. This allows to remove
+     * duplicate profile definitions in the media_profiles.xml
+     * file.
+     */
+    void checkAndAddRequiredProfilesIfNecessary();
+
+
     // Mappings from name (for instance, codec name) to enum value
     static const NameToTagMap sVideoEncoderNameMap[];
     static const NameToTagMap sAudioEncoderNameMap[];
@@ -355,6 +408,20 @@
     Vector<VideoDecoderCap*>  mVideoDecoders;
     Vector<output_format>     mEncoderOutputFileFormats;
     Vector<ImageEncodingQualityLevels *>  mImageEncodingQualityLevels;
+
+    typedef struct {
+        bool mHasRefProfile;      // Refers to an existing profile
+        int  mRefProfileIndex;    // Reference profile index
+        int  mResolutionProduct;  // width x height
+    } RequiredProfileRefInfo;     // Required low and high profiles
+
+    typedef struct {
+        RequiredProfileRefInfo mRefs[kNumRequiredProfiles];
+        int mCameraId;
+    } RequiredProfiles;
+
+    RequiredProfiles *mRequiredProfileRefs;
+    Vector<int>              mCameraIds;
 };
 
 }; // namespace android
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index eb599b5..717f837 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -65,7 +65,7 @@
     // When changing these values, the COMPILE_TIME_ASSERT at the end of this
     // file need to be updated.
     static const unsigned int NUM_LAYERS_MAX  = 31;
-    static const unsigned int NUM_BUFFER_MAX  = 16;
+    static const unsigned int NUM_BUFFER_MAX  = 32;
     static const unsigned int NUM_BUFFER_MIN  = 2;
     static const unsigned int NUM_DISPLAY_MAX = 4;
 
@@ -123,7 +123,7 @@
 
 // ----------------------------------------------------------------------------
 
-// 32 KB max
+// 64 KB max
 class SharedClient
 {
 public:
@@ -394,7 +394,7 @@
 
 // ---------------------------------------------------------------------------
 
-COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 32768)
+COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 65536)
 COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
 
 // ---------------------------------------------------------------------------
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 8bae684..aa9b40e 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -40,9 +40,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Font::Font(FontRenderer* state, uint32_t fontId, float fontSize,
-        int flags, uint32_t italicStyle) :
+        int flags, uint32_t italicStyle, uint32_t scaleX) :
         mState(state), mFontId(fontId), mFontSize(fontSize),
-        mFlags(flags), mItalicStyle(italicStyle) {
+        mFlags(flags), mItalicStyle(italicStyle), mScaleX(scaleX) {
 }
 
 
@@ -279,18 +279,19 @@
 }
 
 Font* Font::create(FontRenderer* state, uint32_t fontId, float fontSize,
-        int flags, uint32_t italicStyle) {
+        int flags, uint32_t italicStyle, uint32_t scaleX) {
     Vector<Font*> &activeFonts = state->mActiveFonts;
 
     for (uint32_t i = 0; i < activeFonts.size(); i++) {
         Font* font = activeFonts[i];
         if (font->mFontId == fontId && font->mFontSize == fontSize &&
-                font->mFlags == flags && font->mItalicStyle == italicStyle) {
+                font->mFlags == flags && font->mItalicStyle == italicStyle &&
+                font->mScaleX == scaleX) {
             return font;
         }
     }
 
-    Font* newFont = new Font(state, fontId, fontSize, flags, italicStyle);
+    Font* newFont = new Font(state, fontId, fontSize, flags, italicStyle, scaleX);
     activeFonts.push(newFont);
     return newFont;
 }
@@ -657,7 +658,9 @@
 
     const float skewX = paint->getTextSkewX();
     uint32_t italicStyle = *(uint32_t*) &skewX;
-    mCurrentFont = Font::create(this, fontId, fontSize, flags, italicStyle);
+    const float scaleXFloat = paint->getTextScaleX();
+    uint32_t scaleX = *(uint32_t*) &scaleXFloat;
+    mCurrentFont = Font::create(this, fontId, fontSize, flags, italicStyle, scaleX);
 
     const float maxPrecacheFontSize = 40.0f;
     bool isNewFont = currentNumFonts != mActiveFonts.size();
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 46f332e..3a7aa96 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -58,7 +58,7 @@
      * Creates a new font associated with the specified font state.
      */
     static Font* create(FontRenderer* state, uint32_t fontId, float fontSize,
-            int flags, uint32_t italicStyle);
+            int flags, uint32_t italicStyle, uint32_t scaleX);
 
 protected:
     friend class FontRenderer;
@@ -104,7 +104,8 @@
         SkFixed mRsbDelta;
     };
 
-    Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle);
+    Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle,
+            uint32_t scaleX);
 
     DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs;
 
@@ -124,6 +125,7 @@
     float mFontSize;
     int mFlags;
     uint32_t mItalicStyle;
+    uint32_t mScaleX;
 };
 
 class FontRenderer {
diff --git a/libs/usb/Android.mk b/libs/usb/Android.mk
index d0ef6f0..b4e1fbf 100644
--- a/libs/usb/Android.mk
+++ b/libs/usb/Android.mk
@@ -22,6 +22,6 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_MODULE:= com.google.android.usb
+LOCAL_MODULE:= com.android.future.usb.accessory
 
 include $(BUILD_JAVA_LIBRARY)
diff --git a/libs/usb/src/com/google/android/usb/UsbAccessory.java b/libs/usb/src/com/android/future/usb/UsbAccessory.java
similarity index 98%
rename from libs/usb/src/com/google/android/usb/UsbAccessory.java
rename to libs/usb/src/com/android/future/usb/UsbAccessory.java
index 931f42e..cdd2b73 100644
--- a/libs/usb/src/com/google/android/usb/UsbAccessory.java
+++ b/libs/usb/src/com/android/future/usb/UsbAccessory.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.usb;
+package com.android.future.usb;
 
 /**
  * A class representing a USB accessory.
diff --git a/libs/usb/src/com/google/android/usb/UsbManager.java b/libs/usb/src/com/android/future/usb/UsbManager.java
similarity index 98%
rename from libs/usb/src/com/google/android/usb/UsbManager.java
rename to libs/usb/src/com/android/future/usb/UsbManager.java
index d7afb95..f74b291 100644
--- a/libs/usb/src/com/google/android/usb/UsbManager.java
+++ b/libs/usb/src/com/android/future/usb/UsbManager.java
@@ -15,7 +15,7 @@
  */
 
 
-package com.google.android.usb;
+package com.android.future.usb;
 
 import android.content.Context;
 import android.content.Intent;
diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk
index b854569..98b6090 100644
--- a/libs/usb/tests/AccessoryChat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/Android.mk
@@ -7,7 +7,7 @@
 
 LOCAL_PACKAGE_NAME := AccessoryChatGB
 
-LOCAL_JAVA_LIBRARIES := com.google.android.usb
+LOCAL_JAVA_LIBRARIES := com.android.future.usb.accessory
 
 # Force an old SDK version to make sure we aren't using newer UsbManager APIs
 LOCAL_SDK_VERSION := 8
diff --git a/libs/usb/tests/AccessoryChat/AndroidManifest.xml b/libs/usb/tests/AccessoryChat/AndroidManifest.xml
index 5922421..97e2ade 100644
--- a/libs/usb/tests/AccessoryChat/AndroidManifest.xml
+++ b/libs/usb/tests/AccessoryChat/AndroidManifest.xml
@@ -1,8 +1,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.google.android.accessorychat">
+        package="com.android.accessorychat">
 
     <application>
-        <uses-library android:name="com.google.android.usb" />
+        <uses-library android:name="com.android.future.usb.accessory" />
 
         <activity android:name="AccessoryChat" android:label="Accessory Chat GB">
             <intent-filter>
@@ -19,5 +19,5 @@
                 android:resource="@xml/accessory_filter" />
         </activity>
     </application>
-    <uses-sdk android:minSdkVersion="8" />
+    <uses-sdk android:minSdkVersion="10" />
 </manifest>
diff --git a/libs/usb/tests/AccessoryChat/src/com/google/android/accessorychat/AccessoryChat.java b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
similarity index 97%
rename from libs/usb/tests/AccessoryChat/src/com/google/android/accessorychat/AccessoryChat.java
rename to libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
index 0a5701c..5cf02c7 100644
--- a/libs/usb/tests/AccessoryChat/src/com/google/android/accessorychat/AccessoryChat.java
+++ b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.accessorychat;
+package com.android.accessorychat;
 
 import android.app.Activity;
 import android.content.BroadcastReceiver;
@@ -31,8 +31,8 @@
 import android.widget.EditText;
 import android.widget.TextView;
 
-import com.google.android.usb.UsbAccessory;
-import com.google.android.usb.UsbManager;
+import com.android.future.usb.UsbAccessory;
+import com.android.future.usb.UsbManager;
 
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 53bbb0f..29c4b89 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -1919,14 +1919,14 @@
                 overlayData = null;
             }
 
-            mPreviewProgressListener.onProgress(mVideoEditor, progress, overlayData);
-
             if (progress != 0) {
                 mPreviewProgress = progress;
             }
 
             if (isFinished) {
                 mPreviewProgressListener.onStop(mVideoEditor);
+            } else {
+                mPreviewProgressListener.onProgress(mVideoEditor, progress, overlayData);
             }
         }
     }
diff --git a/media/jni/mediaeditor/VideoBrowserMain.c b/media/jni/mediaeditor/VideoBrowserMain.c
index bb13fba..caf4497 100755
--- a/media/jni/mediaeditor/VideoBrowserMain.c
+++ b/media/jni/mediaeditor/VideoBrowserMain.c
@@ -206,8 +206,8 @@
                 pContext->m_pReaderCtx, &mediaFamily, &pStreamHandler);
 
         /*in case we found a bifs stream or something else...*/
-        if ((err == M4ERR_READER_UNKNOWN_STREAM_TYPE) ||
-            (err == M4WAR_TOO_MUCH_STREAMS))
+        if ((err == (M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE) ||
+            (err == (M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS))
         {
             err = M4NO_ERROR;
             continue;
@@ -251,7 +251,7 @@
                             &decoderType, &pContext->m_pDecoder);
 #else
                         err = VideoEditorVideoDecoder_getInterface_MPEG4(
-                            &decoderType, &pContext->m_pDecoder);
+                            &decoderType, (void **)&pContext->m_pDecoder);
 #endif
                     CHECK_ERR(videoBrowserCreate, err) ;
 
@@ -277,7 +277,7 @@
                             &decoderType, &pContext->m_pDecoder);
 #else
                         err = VideoEditorVideoDecoder_getInterface_H264(
-                            &decoderType, &pContext->m_pDecoder);
+                            &decoderType, (void **)&pContext->m_pDecoder);
 #endif
                    CHECK_ERR(videoBrowserCreate, err) ;
 
diff --git a/media/jni/mediaeditor/VideoEditorClasses.cpp b/media/jni/mediaeditor/VideoEditorClasses.cpp
index 8a35041..ea73e11 100755
--- a/media/jni/mediaeditor/VideoEditorClasses.cpp
+++ b/media/jni/mediaeditor/VideoEditorClasses.cpp
@@ -896,8 +896,9 @@
                 jobject                             object,
                 M4xVSS_AlphaMagicSettings**         ppSettings)
 {
-    VideoEditJava_AlphaMagicFieldIds   fieldIds  = {NULL, NULL, NULL, NULL, NULL};
+    VideoEditJava_AlphaMagicFieldIds fieldIds;
     M4xVSS_AlphaMagicSettings* pSettings = M4OSA_NULL;
+    memset(&fieldIds, 0, sizeof(VideoEditJava_AlphaMagicFieldIds));
 
     // Check if the previous action succeeded.
     if (*pResult)
@@ -1036,11 +1037,10 @@
                 jobject                             object,
                 M4xVSS_BGMSettings**                ppSettings)
 {
-    VideoEditJava_BackgroundMusicFieldIds fieldIds  = {NULL, NULL, NULL, NULL,
-                                                       NULL, NULL,NULL,NULL,NULL,NULL};
+    VideoEditJava_BackgroundMusicFieldIds fieldIds;
     M4xVSS_BGMSettings*           pSettings = M4OSA_NULL;
     bool                          converted = true;
-
+    memset(&fieldIds, 0, sizeof(VideoEditJava_BackgroundMusicFieldIds));
     // Check if the previous action succeeded.
     if (*pResult)
     {
@@ -1324,12 +1324,12 @@
                 jobject                             object,
                 M4VSS3GPP_ClipSettings**            ppSettings)
 {
-    VideoEditJava_ClipSettingsFieldIds fieldIds  = {NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                             NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+
+    VideoEditJava_ClipSettingsFieldIds fieldIds;
     M4VSS3GPP_ClipSettings*    pSettings = M4OSA_NULL;
     M4OSA_ERR                  result    = M4NO_ERROR;
     bool                       converted = true;
-
+    memset(&fieldIds, 0, sizeof(VideoEditJava_ClipSettingsFieldIds));
     // Check if the previous action succeeded.
     if (*pResult)
     {
@@ -1500,10 +1500,10 @@
                 M4VSS3GPP_ClipSettings*             pSettings,
                 jobject*                            pObject)
 {
-    VideoEditJava_ClipSettingsFieldIds fieldIds = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                           NULL, NULL, NULL, NULL, NULL, NULL};
+    VideoEditJava_ClipSettingsFieldIds fieldIds;
     jclass                     clazz    = NULL;
     jobject                    object   = NULL;
+    memset(&fieldIds, 0, sizeof(VideoEditJava_ClipSettingsFieldIds));
 
     // Check if the previous action succeeded.
     if (*pResult)
@@ -1600,11 +1600,10 @@
                 VideoEditPropClass_Properties*      pProperties,
                 jobject*                            pObject)
 {
-    VideoEditJava_PropertiesFieldIds fieldIds = {NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                                     NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+    VideoEditJava_PropertiesFieldIds fieldIds;
     jclass                   clazz    = NULL;
     jobject                  object   = NULL;
-
+    memset(&fieldIds, 0, sizeof(VideoEditJava_PropertiesFieldIds));
     // Check if the previous action succeeded.
     if (*pResult)
     {
@@ -1783,9 +1782,7 @@
                 M4VSS3GPP_EditSettings**            ppSettings,
                 bool                                flag)
 {
-    VideoEditJava_EditSettingsFieldIds fieldIds            ={NULL, NULL, NULL, NULL, NULL, NULL,
-                                                            NULL, NULL, NULL, NULL, NULL, NULL,
-                                                            NULL, NULL,NULL};
+    VideoEditJava_EditSettingsFieldIds fieldIds;
     jobjectArray               clipSettingsArray           = NULL;
     jsize                      clipSettingsArraySize       = 0;
     jobject                    clipSettings                = NULL;
@@ -1799,7 +1796,7 @@
     int                        audioChannels               = 0;
     M4VSS3GPP_EditSettings*    pSettings                   = M4OSA_NULL;
     bool                       converted                   = true;
-
+    memset(&fieldIds, 0, sizeof(VideoEditJava_EditSettingsFieldIds));
     // Check if the previous action succeeded.
     if (*pResult)
     {
@@ -2304,10 +2301,10 @@
                 jobject                             object,
                 M4VSS3GPP_EffectSettings*           pSettings)
 {
-    VideoEditJava_EffectSettingsFieldIds fieldIds  = {NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                  NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+
+    VideoEditJava_EffectSettingsFieldIds fieldIds;
     bool                         converted = true;
+    memset(&fieldIds, 0, sizeof(VideoEditJava_EffectSettingsFieldIds));
 
     // Check if the previous action succeeded.
     if (*pResult)
@@ -2736,11 +2733,13 @@
                 jobject                             object,
                 M4VSS3GPP_TransitionSettings**      ppSettings)
 {
-    VideoEditJava_TransitionSettingsFieldIds fieldIds      = {NULL, NULL, NULL, NULL, NULL, NULL};
+
+    VideoEditJava_TransitionSettingsFieldIds fieldIds;
     jobject                          alphaSettings = NULL;
     jobject                          slideSettings = NULL;
     M4VSS3GPP_TransitionSettings*    pSettings     = M4OSA_NULL;
     bool                             converted     = true;
+    memset(&fieldIds, 0, sizeof(VideoEditJava_TransitionSettingsFieldIds));
 
     // Check if the previous action succeeded.
     if (*pResult)
@@ -3025,10 +3024,11 @@
                 M4_VersionInfo*                     pVersionInfo,
                 jobject*                            pObject)
 {
-    VideoEditJava_VersionFieldIds fieldIds = {NULL, NULL, NULL};
+
+    VideoEditJava_VersionFieldIds fieldIds;
     jclass                clazz    = NULL;
     jobject               object   = NULL;
-
+    memset(&fieldIds, 0, sizeof(VideoEditJava_VersionFieldIds));
     // Check if the previous action succeeded.
     if (*pResult)
     {
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index ebe3302..0b061db 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -53,6 +53,11 @@
 namespace android {
 namespace {
 
+// Flag to allow a one time init of global memory, only happens on first call ever
+int LvmInitFlag = LVM_FALSE;
+SessionContext GlobalSessionMemory[LVM_MAX_SESSIONS];
+int SessionIndex[LVM_MAX_SESSIONS];
+
 /* local functions */
 #define CHECK_ARG(cond) {                     \
     if (!(cond)) {                            \
@@ -61,11 +66,6 @@
     }                                         \
 }
 
-// Flag to allow a one time init of global memory, only happens on first call ever
-int LvmInitFlag = LVM_FALSE;
-SessionContext GlobalSessionMemory[LVM_MAX_SESSIONS];
-
-int SessionIndex[LVM_MAX_SESSIONS];
 
 // NXP SW BassBoost UUID
 const effect_descriptor_t gBassBoostDescriptor = {
@@ -2588,9 +2588,11 @@
             pContext->pBundledContext->SamplesToExitCountBb -= outBuffer->frameCount * 2; // STEREO
             //LOGV("\tEffect_process: Waiting to turn off BASS_BOOST, %d samples left",
             //    pContext->pBundledContext->SamplesToExitCountBb);
-        } else {
+        }
+        if(pContext->pBundledContext->SamplesToExitCountBb <= 0) {
             status = -ENODATA;
             pContext->pBundledContext->NumberEffectsEnabled--;
+            LOGV("\tEffect_process() this is the last frame for LVM_BASS_BOOST");
         }
     }
     if ((pContext->pBundledContext->bVolumeEnabled == LVM_FALSE)&&
@@ -2606,9 +2608,11 @@
             pContext->pBundledContext->SamplesToExitCountEq -= outBuffer->frameCount * 2; // STEREO
             //LOGV("\tEffect_process: Waiting to turn off EQUALIZER, %d samples left",
             //    pContext->pBundledContext->SamplesToExitCountEq);
-        } else {
+        }
+        if(pContext->pBundledContext->SamplesToExitCountEq <= 0) {
             status = -ENODATA;
             pContext->pBundledContext->NumberEffectsEnabled--;
+            LOGV("\tEffect_process() this is the last frame for LVM_EQUALIZER");
         }
     }
     if ((pContext->pBundledContext->bVirtualizerEnabled == LVM_FALSE)&&
@@ -2618,9 +2622,11 @@
             pContext->pBundledContext->SamplesToExitCountVirt -= outBuffer->frameCount * 2;// STEREO
             //LOGV("\tEffect_process: Waiting for to turn off VIRTUALIZER, %d samples left",
             //    pContext->pBundledContext->SamplesToExitCountVirt);
-        } else {
+        }
+        if(pContext->pBundledContext->SamplesToExitCountVirt <= 0) {
             status = -ENODATA;
             pContext->pBundledContext->NumberEffectsEnabled--;
+            LOGV("\tEffect_process() this is the last frame for LVM_VIRTUALIZER");
         }
     }
 
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 9ad63f0..7fb7aed 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -284,8 +284,17 @@
     return static_cast<output_format>(format);
 }
 
+static bool isCameraIdFound(int cameraId, const Vector<int>& cameraIds) {
+    for (int i = 0, n = cameraIds.size(); i < n; ++i) {
+        if (cameraId == cameraIds[i]) {
+            return true;
+        }
+    }
+    return false;
+}
+
 /*static*/ MediaProfiles::CamcorderProfile*
-MediaProfiles::createCamcorderProfile(int cameraId, const char **atts)
+MediaProfiles::createCamcorderProfile(int cameraId, const char **atts, Vector<int>& cameraIds)
 {
     CHECK(!strcmp("quality",    atts[0]) &&
           !strcmp("fileFormat", atts[2]) &&
@@ -301,6 +310,9 @@
 
     MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile;
     profile->mCameraId = cameraId;
+    if (!isCameraIdFound(cameraId, cameraIds)) {
+        cameraIds.add(cameraId);
+    }
     profile->mFileFormat = static_cast<output_format>(fileFormat);
     profile->mQuality = static_cast<camcorder_quality>(quality);
     profile->mDuration = atoi(atts[5]);
@@ -370,12 +382,167 @@
         profiles->mCurrentCameraId = getCameraId(atts);
     } else if (strcmp("EncoderProfile", name) == 0) {
         profiles->mCamcorderProfiles.add(
-            createCamcorderProfile(profiles->mCurrentCameraId, atts));
+            createCamcorderProfile(profiles->mCurrentCameraId, atts, profiles->mCameraIds));
     } else if (strcmp("ImageEncoding", name) == 0) {
         profiles->addImageEncodingQualityLevel(profiles->mCurrentCameraId, atts);
     }
 }
 
+static bool isCamcorderProfile(camcorder_quality quality) {
+    return quality >= CAMCORDER_QUALITY_LIST_START &&
+           quality <= CAMCORDER_QUALITY_LIST_END;
+}
+
+static bool isTimelapseProfile(camcorder_quality quality) {
+    return quality >= CAMCORDER_QUALITY_TIME_LAPSE_LIST_START &&
+           quality <= CAMCORDER_QUALITY_TIME_LAPSE_LIST_END;
+}
+
+void MediaProfiles::initRequiredProfileRefs(const Vector<int>& cameraIds) {
+    LOGV("Number of camera ids: %d", cameraIds.size());
+    CHECK(cameraIds.size() > 0);
+    mRequiredProfileRefs = new RequiredProfiles[cameraIds.size()];
+    for (size_t i = 0, n = cameraIds.size(); i < n; ++i) {
+        mRequiredProfileRefs[i].mCameraId = cameraIds[i];
+        for (size_t j = 0; j < kNumRequiredProfiles; ++j) {
+            mRequiredProfileRefs[i].mRefs[j].mHasRefProfile = false;
+            mRequiredProfileRefs[i].mRefs[j].mRefProfileIndex = -1;
+            if ((j & 1) == 0) {  // low resolution
+                mRequiredProfileRefs[i].mRefs[j].mResolutionProduct = 0x7FFFFFFF;
+            } else {             // high resolution
+                mRequiredProfileRefs[i].mRefs[j].mResolutionProduct = 0;
+            }
+        }
+    }
+}
+
+int MediaProfiles::getRequiredProfileRefIndex(int cameraId) {
+    for (size_t i = 0, n = mCameraIds.size(); i < n; ++i) {
+        if (mCameraIds[i] == cameraId) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+void MediaProfiles::checkAndAddRequiredProfilesIfNecessary() {
+    if (sIsInitialized) {
+        return;
+    }
+
+    initRequiredProfileRefs(mCameraIds);
+
+    for (size_t i = 0, n = mCamcorderProfiles.size(); i < n; ++i) {
+        int product = mCamcorderProfiles[i]->mVideoCodec->mFrameWidth *
+                      mCamcorderProfiles[i]->mVideoCodec->mFrameHeight;
+
+        camcorder_quality quality = mCamcorderProfiles[i]->mQuality;
+        int cameraId = mCamcorderProfiles[i]->mCameraId;
+        int index = -1;
+        int refIndex = getRequiredProfileRefIndex(cameraId);
+        CHECK(refIndex != -1);
+        RequiredProfileRefInfo *info;
+        camcorder_quality refQuality;
+        VideoCodec *codec = NULL;
+
+        // Check high and low from either camcorder profile or timelapse profile
+        // but not both. Default, check camcorder profile
+        size_t j = 0;
+        size_t n = 2;
+        if (isTimelapseProfile(quality)) {
+            // Check timelapse profile instead.
+            j = 2;
+            n = kNumRequiredProfiles;
+        } else {
+            // Must be camcorder profile.
+            CHECK(isCamcorderProfile(quality));
+        }
+        for (; j < n; ++j) {
+            info = &(mRequiredProfileRefs[refIndex].mRefs[j]);
+            if ((j % 2 == 0 && product > info->mResolutionProduct) ||  // low
+                (j % 2 != 0 && product < info->mResolutionProduct)) {  // high
+                continue;
+            }
+            switch (j) {
+                case 0:
+                   refQuality = CAMCORDER_QUALITY_LOW;
+                   break;
+                case 1:
+                   refQuality = CAMCORDER_QUALITY_HIGH;
+                   break;
+                case 2:
+                   refQuality = CAMCORDER_QUALITY_TIME_LAPSE_LOW;
+                   break;
+                case 3:
+                   refQuality = CAMCORDER_QUALITY_TIME_LAPSE_HIGH;
+                   break;
+                default:
+                    CHECK(!"Should never reach here");
+            }
+
+            if (!info->mHasRefProfile) {
+                index = getCamcorderProfileIndex(cameraId, refQuality);
+            }
+            if (index == -1) {
+                // New high or low quality profile is found.
+                // Update its reference.
+                info->mHasRefProfile = true;
+                info->mRefProfileIndex = i;
+                info->mResolutionProduct = product;
+            }
+        }
+    }
+
+    for (size_t cameraId = 0; cameraId < mCameraIds.size(); ++cameraId) {
+        for (size_t j = 0; j < kNumRequiredProfiles; ++j) {
+            int refIndex = getRequiredProfileRefIndex(cameraId);
+            CHECK(refIndex != -1);
+            RequiredProfileRefInfo *info =
+                    &mRequiredProfileRefs[refIndex].mRefs[j];
+
+            if (info->mHasRefProfile) {
+
+                CamcorderProfile *profile =
+                    new CamcorderProfile(
+                            *mCamcorderProfiles[info->mRefProfileIndex]);
+
+                // Overwrite the quality
+                switch (j % kNumRequiredProfiles) {
+                    case 0:
+                        profile->mQuality = CAMCORDER_QUALITY_LOW;
+                        break;
+                    case 1:
+                        profile->mQuality = CAMCORDER_QUALITY_HIGH;
+                        break;
+                    case 2:
+                        profile->mQuality = CAMCORDER_QUALITY_TIME_LAPSE_LOW;
+                        break;
+                    case 3:
+                        profile->mQuality = CAMCORDER_QUALITY_TIME_LAPSE_HIGH;
+                        break;
+                    default:
+                        CHECK(!"Should never come here");
+                }
+
+                int index = getCamcorderProfileIndex(cameraId, profile->mQuality);
+                if (index != -1) {
+                    LOGV("Profile quality %d for camera %d already exists",
+                        profile->mQuality, cameraId);
+                    CHECK(index == refIndex);
+                    continue;
+                }
+
+                // Insert the new profile
+                LOGV("Add a profile: quality %d=>%d for camera %d",
+                        mCamcorderProfiles[info->mRefProfileIndex]->mQuality,
+                        profile->mQuality, cameraId);
+
+                mCamcorderProfiles.add(profile);
+            }
+        }
+    }
+}
+
 /*static*/ MediaProfiles*
 MediaProfiles::getInstance()
 {
@@ -396,6 +563,9 @@
         } else {
             sInstance = createInstanceFromXmlFile(value);
         }
+        CHECK(sInstance != NULL);
+        sInstance->checkAndAddRequiredProfilesIfNecessary();
+        sIsInitialized = true;
     }
 
     return sInstance;
@@ -613,7 +783,6 @@
     createDefaultAudioDecoders(profiles);
     createDefaultEncoderOutputFileFormats(profiles);
     createDefaultImageEncodingQualityLevels(profiles);
-    sIsInitialized = true;
     return profiles;
 }
 
@@ -667,9 +836,6 @@
 exit:
     ::XML_ParserFree(parser);
     ::fclose(fp);
-    if (profiles) {
-        sIsInitialized = true;
-    }
     return profiles;
 }
 
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index 0e51caf..6538a05 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -73,6 +73,7 @@
     // Returns an approximate bitrate in bits per second.
     uint64_t approxBitrate();
 
+    status_t seekToTime(int64_t timeUs);
     status_t seekToOffset(off64_t offset);
     status_t readNextPacket(MediaBuffer **buffer);
 
@@ -90,6 +91,11 @@
         uint8_t mLace[255];
     };
 
+    struct TOCEntry {
+        off64_t mPageOffset;
+        int64_t mTimeUs;
+    };
+
     sp<DataSource> mSource;
     off64_t mOffset;
     Page mCurrentPage;
@@ -107,6 +113,8 @@
     sp<MetaData> mMeta;
     sp<MetaData> mFileMeta;
 
+    Vector<TOCEntry> mTableOfContents;
+
     ssize_t readPage(off64_t offset, Page *page);
     status_t findNextPage(off64_t startOffset, off64_t *pageOffset);
 
@@ -115,7 +123,9 @@
 
     void parseFileMetaData();
 
-    uint64_t findPrevGranulePosition(off64_t pageOffset);
+    status_t findPrevGranulePosition(off64_t pageOffset, uint64_t *granulePos);
+
+    void buildTableOfContents();
 
     MyVorbisExtractor(const MyVorbisExtractor &);
     MyVorbisExtractor &operator=(const MyVorbisExtractor &);
@@ -164,10 +174,7 @@
     int64_t seekTimeUs;
     ReadOptions::SeekMode mode;
     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
-        off64_t pos = seekTimeUs * mExtractor->mImpl->approxBitrate() / 8000000ll;
-        LOGV("seeking to offset %ld", pos);
-
-        if (mExtractor->mImpl->seekToOffset(pos) != OK) {
+        if (mExtractor->mImpl->seekToTime(seekTimeUs) != OK) {
             return ERROR_END_OF_STREAM;
         }
     }
@@ -237,7 +244,7 @@
 
         if (!memcmp(signature, "OggS", 4)) {
             if (*pageOffset > startOffset) {
-                LOGV("skipped %ld bytes of junk to reach next frame",
+                LOGV("skipped %lld bytes of junk to reach next frame",
                      *pageOffset - startOffset);
             }
 
@@ -252,7 +259,10 @@
 // it (if any) and return its granule position.
 // To do this we back up from the "current" page's offset until we find any
 // page preceding it and then scan forward to just before the current page.
-uint64_t MyVorbisExtractor::findPrevGranulePosition(off64_t pageOffset) {
+status_t MyVorbisExtractor::findPrevGranulePosition(
+        off64_t pageOffset, uint64_t *granulePos) {
+    *granulePos = 0;
+
     off64_t prevPageOffset = 0;
     off64_t prevGuess = pageOffset;
     for (;;) {
@@ -262,9 +272,12 @@
             prevGuess = 0;
         }
 
-        LOGV("backing up %ld bytes", pageOffset - prevGuess);
+        LOGV("backing up %lld bytes", pageOffset - prevGuess);
 
-        CHECK_EQ(findNextPage(prevGuess, &prevPageOffset), (status_t)OK);
+        status_t err = findNextPage(prevGuess, &prevPageOffset);
+        if (err != OK) {
+            return err;
+        }
 
         if (prevPageOffset < pageOffset || prevGuess == 0) {
             break;
@@ -273,27 +286,64 @@
 
     if (prevPageOffset == pageOffset) {
         // We did not find a page preceding this one.
-        return 0;
+        return UNKNOWN_ERROR;
     }
 
-    LOGV("prevPageOffset at %ld, pageOffset at %ld", prevPageOffset, pageOffset);
+    LOGV("prevPageOffset at %lld, pageOffset at %lld",
+         prevPageOffset, pageOffset);
 
     for (;;) {
         Page prevPage;
         ssize_t n = readPage(prevPageOffset, &prevPage);
 
         if (n <= 0) {
-            return 0;
+            return (status_t)n;
         }
 
         prevPageOffset += n;
 
         if (prevPageOffset == pageOffset) {
-            return prevPage.mGranulePosition;
+            *granulePos = prevPage.mGranulePosition;
+            return OK;
         }
     }
 }
 
+status_t MyVorbisExtractor::seekToTime(int64_t timeUs) {
+    if (mTableOfContents.isEmpty()) {
+        // Perform approximate seeking based on avg. bitrate.
+
+        off64_t pos = timeUs * approxBitrate() / 8000000ll;
+
+        LOGV("seeking to offset %lld", pos);
+        return seekToOffset(pos);
+    }
+
+    size_t left = 0;
+    size_t right = mTableOfContents.size();
+    while (left < right) {
+        size_t center = left / 2 + right / 2 + (left & right & 1);
+
+        const TOCEntry &entry = mTableOfContents.itemAt(center);
+
+        if (timeUs < entry.mTimeUs) {
+            right = center;
+        } else if (timeUs > entry.mTimeUs) {
+            left = center + 1;
+        } else {
+            left = right = center;
+            break;
+        }
+    }
+
+    const TOCEntry &entry = mTableOfContents.itemAt(left);
+
+    LOGV("seeking to entry %d / %d at offset %lld",
+         left, mTableOfContents.size(), entry.mPageOffset);
+
+    return seekToOffset(entry.mPageOffset);
+}
+
 status_t MyVorbisExtractor::seekToOffset(off64_t offset) {
     if (mFirstDataOffset >= 0 && offset < mFirstDataOffset) {
         // Once we know where the actual audio data starts (past the headers)
@@ -311,7 +361,7 @@
     // We found the page we wanted to seek to, but we'll also need
     // the page preceding it to determine how many valid samples are on
     // this page.
-    mPrevGranulePosition = findPrevGranulePosition(pageOffset);
+    findPrevGranulePosition(pageOffset, &mPrevGranulePosition);
 
     mOffset = pageOffset;
 
@@ -330,7 +380,8 @@
     uint8_t header[27];
     if (mSource->readAt(offset, header, sizeof(header))
             < (ssize_t)sizeof(header)) {
-        LOGV("failed to read %d bytes at offset 0x%08lx", sizeof(header), offset);
+        LOGV("failed to read %d bytes at offset 0x%016llx",
+             sizeof(header), offset);
 
         return ERROR_IO;
     }
@@ -447,7 +498,8 @@
                     packetSize);
 
             if (n < (ssize_t)packetSize) {
-                LOGV("failed to read %d bytes at 0x%08lx", packetSize, dataOffset);
+                LOGV("failed to read %d bytes at 0x%016llx",
+                     packetSize, dataOffset);
                 return ERROR_IO;
             }
 
@@ -563,9 +615,66 @@
 
     mFirstDataOffset = mOffset + mCurrentPageSize;
 
+    off64_t size;
+    uint64_t lastGranulePosition;
+    if (!(mSource->flags() & DataSource::kIsCachingDataSource)
+            && mSource->getSize(&size) == OK
+            && findPrevGranulePosition(size, &lastGranulePosition) == OK) {
+        // Let's assume it's cheap to seek to the end.
+        // The granule position of the final page in the stream will
+        // give us the exact duration of the content, something that
+        // we can only approximate using avg. bitrate if seeking to
+        // the end is too expensive or impossible (live streaming).
+
+        int64_t durationUs = lastGranulePosition * 1000000ll / mVi.rate;
+
+        mMeta->setInt64(kKeyDuration, durationUs);
+
+        buildTableOfContents();
+    }
+
     return OK;
 }
 
+void MyVorbisExtractor::buildTableOfContents() {
+    off64_t offset = mFirstDataOffset;
+    Page page;
+    ssize_t pageSize;
+    while ((pageSize = readPage(offset, &page)) > 0) {
+        mTableOfContents.push();
+
+        TOCEntry &entry =
+            mTableOfContents.editItemAt(mTableOfContents.size() - 1);
+
+        entry.mPageOffset = offset;
+        entry.mTimeUs = page.mGranulePosition * 1000000ll / mVi.rate;
+
+        offset += (size_t)pageSize;
+    }
+
+    // Limit the maximum amount of RAM we spend on the table of contents,
+    // if necessary thin out the table evenly to trim it down to maximum
+    // size.
+
+    static const size_t kMaxTOCSize = 8192;
+    static const size_t kMaxNumTOCEntries = kMaxTOCSize / sizeof(TOCEntry);
+
+    size_t numerator = mTableOfContents.size();
+
+    if (numerator > kMaxNumTOCEntries) {
+        size_t denom = numerator - kMaxNumTOCEntries;
+
+        size_t accum = 0;
+        for (ssize_t i = mTableOfContents.size() - 1; i >= 0; --i) {
+            accum += denom;
+            if (accum >= numerator) {
+                mTableOfContents.removeAt(i);
+                accum -= numerator;
+            }
+        }
+    }
+}
+
 status_t MyVorbisExtractor::verifyHeader(
         MediaBuffer *buffer, uint8_t type) {
     const uint8_t *data =
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
index 8b0250a..d443b7c 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
@@ -121,9 +121,11 @@
     uint32  temp;
 
     /*
-     *  Verify that at least the header is complete
+     * Verify that at least the header is complete
+     * Note that SYNC_WORD_LNGTH is in unit of bits, but inputBufferCurrentLength
+     * is in unit of bytes.
      */
-    if (inputStream->inputBufferCurrentLength < (SYNC_WORD_LNGTH + 21))
+    if (inputStream->inputBufferCurrentLength < ((SYNC_WORD_LNGTH + 21) >> 3))
     {
         return NO_ENOUGH_MAIN_DATA_ERROR;
     }
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png
index 7f86fb3..a1c39e6 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_bg_holo.xml b/packages/SystemUI/res/drawable/recents_thumbnail_bg_holo.xml
new file mode 100644
index 0000000..f9bba2a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/recents_thumbnail_bg_holo.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** 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.
+*/
+-->
+<transition xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/recents_thumbnail_bg_press"/>
+    <item android:drawable="@drawable/recents_thumbnail_bg_press"/>
+</transition>
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_bg_selector.xml b/packages/SystemUI/res/drawable/recents_thumbnail_bg_selector.xml
new file mode 100644
index 0000000..0e58e12
--- /dev/null
+++ b/packages/SystemUI/res/drawable/recents_thumbnail_bg_selector.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+	android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+
+    <item android:state_window_focused="false" android:drawable="@android:color/transparent" />
+
+    <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
+    <item android:state_focused="true"                                android:state_pressed="true" android:drawable="@drawable/recents_thumbnail_bg_holo" />
+    <item android:state_focused="false"                               android:state_pressed="true" android:drawable="@drawable/recents_thumbnail_bg_holo" />
+    <item android:state_focused="true"                                                             android:drawable="@drawable/recents_thumbnail_bg_holo" />
+</selector>
+
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 6c173c9..d9f3f23 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -32,7 +32,6 @@
             android:id="@+id/bar_contents"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:animateLayoutChanges="true"
             >
 
             <!-- notification icons & panel access -->
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_panel.xml
index efbf359..f6ed804 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_panel.xml
@@ -85,7 +85,9 @@
                 android:layout_height="wrap_content"
                 android:overScrollMode="ifContentScrolls"
                 android:layout_marginTop="3dip"
-                android:layout_weight="1">
+                android:layout_weight="1"
+                android:scrollbarAlwaysDrawVerticalTrack="true"
+                android:scrollbarDefaultDelayBeforeFade="75000">
                 <LinearLayout
                     android:id="@+id/input_method_menu_list"
                     android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
index 4be57a2..eda19b7 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
@@ -36,7 +36,7 @@
         <LinearLayout android:id="@+id/recents_glow"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginBottom="-52dip"
+            android:layout_marginBottom="-49dip"
             android:layout_gravity="bottom"
             android:background="@drawable/recents_blue_glow"
             android:orientation="horizontal"
@@ -52,7 +52,7 @@
                 android:fadingEdge="vertical"
                 android:scrollbars="none"
                 android:fadingEdgeLength="30dip"
-                android:listSelector="@drawable/recents_thumbnail_bg_press"
+                android:listSelector="@drawable/recents_thumbnail_bg_selector"
             />
 
         </LinearLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
index 75bbb3a..677988d 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
@@ -21,7 +21,6 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical"
-        android:paddingRight="48dp"
         >
 
     <!-- Airplane mode -->
@@ -80,7 +79,7 @@
         <TextView
                 android:id="@+id/rotate_label"
                 style="@style/StatusBarPanelSettingsContents"
-                android:text="@string/status_bar_settings_rotation_lock"
+                android:text="@string/status_bar_settings_auto_rotation"
                 />
         <Switch
                 android:id="@+id/rotate_checkbox"
diff --git a/packages/SystemUI/res/values-xlarge/styles.xml b/packages/SystemUI/res/values-xlarge/styles.xml
index c1cd533..12c8950 100644
--- a/packages/SystemUI/res/values-xlarge/styles.xml
+++ b/packages/SystemUI/res/values-xlarge/styles.xml
@@ -22,9 +22,11 @@
     </style>
 
     <style name="StatusBarPanelSettingsRow">
+        <item name="android:paddingRight">48dp</item>
         <item name="android:layout_height">64dp</item>
         <item name="android:layout_width">match_parent</item>
         <item name="android:orientation">horizontal</item>
+        <item name="android:background">?android:attr/listChoiceBackgroundIndicator</item>
     </style>
 
     <style name="StatusBarPanelSettingsIcon">
@@ -43,6 +45,7 @@
     </style>
 
     <style name="StatusBarPanelSettingsPanelSeparator">
+        <item name="android:layout_marginRight">48dp</item>
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">1dp</item>
         <item name="android:background">@android:drawable/divider_horizontal_dark</item>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 0923570..ebd48e7 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -81,7 +81,7 @@
     <string name="status_bar_settings_airplane">Airplane mode</string>
 
     <!-- Label in system panel saying the device will use the orientation sensor to rotate [CHAR LIMIT=30] -->
-    <string name="status_bar_settings_rotation_lock">Lock screen orientation</string>
+    <string name="status_bar_settings_auto_rotation">Auto-rotate screen</string>
 
     <!-- Abbreviation / label for mute brightness mode button. Should be all caps. [CHAR LIMIT=6] -->
     <string name="status_bar_settings_mute_label">MUTE</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java
index b0a6d7a..5ac5ad0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java
@@ -35,39 +35,39 @@
     private Context mContext;
     private CompoundButton mCheckBox;
 
-    private boolean mLockRotation;
+    private boolean mAutoRotation;
 
     public AutoRotateController(Context context, CompoundButton checkbox) {
         mContext = context;
-        mLockRotation = getLockRotation();
+        mAutoRotation = getAutoRotation();
         mCheckBox = checkbox;
-        checkbox.setChecked(mLockRotation);
+        checkbox.setChecked(mAutoRotation);
         checkbox.setOnCheckedChangeListener(this);
     }
 
     public void onCheckedChanged(CompoundButton view, boolean checked) {
-        if (checked != mLockRotation) {
-            setLockRotation(checked);
+        if (checked != mAutoRotation) {
+            setAutoRotation(checked);
         }
     }
 
-    private boolean getLockRotation() {
+    private boolean getAutoRotation() {
         ContentResolver cr = mContext.getContentResolver();
-        return 0 == Settings.System.getInt(cr, Settings.System.ACCELEROMETER_ROTATION, 0);
+        return 0 != Settings.System.getInt(cr, Settings.System.ACCELEROMETER_ROTATION, 0);
     }
 
-    private void setLockRotation(final boolean locked) {
-        mLockRotation = locked;
+    private void setAutoRotation(final boolean autorotate) {
+        mAutoRotation = autorotate;
         AsyncTask.execute(new Runnable() {
                 public void run() {
                     try {
                         IWindowManager wm = IWindowManager.Stub.asInterface(
                                 ServiceManager.getService(Context.WINDOW_SERVICE));
                         ContentResolver cr = mContext.getContentResolver();
-                        if (locked) {
-                            wm.freezeRotation();
-                        } else {
+                        if (autorotate) {
                             wm.thawRotation();
+                        } else {
+                            wm.freezeRotation();
                         }
                     } catch (RemoteException exc) {
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 8ab231b..e81cec2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -25,12 +25,14 @@
 import android.os.ServiceManager;
 import android.util.AttributeSet;
 import android.util.Slog;
+import android.view.accessibility.AccessibilityEvent;
 import android.view.HapticFeedbackConstants;
 import android.view.IWindowManager;
 import android.view.InputDevice;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
+import android.view.SoundEffectConstants;
 import android.view.ViewConfiguration;
 import android.widget.ImageView;
 import android.widget.RemoteViews.RemoteView;
@@ -45,6 +47,8 @@
     boolean mSending;
     int mCode;
     int mRepeat;
+    int mTouchSlop;
+
     Runnable mCheckLongPress = new Runnable() {
         public void run() {
             if (isPressed()) {
@@ -53,6 +57,9 @@
                         KeyEvent.FLAG_FROM_SYSTEM
                         | KeyEvent.FLAG_VIRTUAL_HARD_KEY
                         | KeyEvent.FLAG_LONG_PRESS);
+
+                sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
+                //playSoundEffect(SoundEffectConstants.CLICK);
             }
         }
     };
@@ -78,6 +85,7 @@
                 ServiceManager.getService(Context.WINDOW_SERVICE));
 
         setClickable(true);
+        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
     }
 
     public boolean onTouchEvent(MotionEvent ev) {
@@ -100,7 +108,10 @@
                 if (mSending) {
                     x = (int)ev.getX();
                     y = (int)ev.getY();
-                    setPressed(x >= 0 && x < getWidth() && y >= 0 &&  y < getHeight());
+                    setPressed(x >= -mTouchSlop
+                            && x < getWidth() + mTouchSlop
+                            && y >= -mTouchSlop
+                            && y < getHeight() + mTouchSlop);
                 }
                 break;
             case MotionEvent.ACTION_CANCEL:
@@ -114,12 +125,18 @@
                 }
                 break;
             case MotionEvent.ACTION_UP:
+                final boolean doIt = isPressed();
                 setPressed(false);
                 if (mSending) {
                     mSending = false;
-                    sendEvent(KeyEvent.ACTION_UP,
-                            KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY);
                     removeCallbacks(mCheckLongPress);
+                    if (doIt) {
+                        sendEvent(KeyEvent.ACTION_UP,
+                                KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY);
+
+                        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+                        playSoundEffect(SoundEffectConstants.CLICK);
+                    }
                 }
                 break;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 35ae118..326cd74 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -105,6 +105,8 @@
     private int mInetCondition = 0;
     private static final int INET_CONDITION_THRESHOLD = 50;
 
+    private boolean mAirplaneMode = false;
+
     // our ui
     Context mContext;
     ArrayList<ImageView> mPhoneSignalIconViews = new ArrayList<ImageView>();
@@ -170,8 +172,12 @@
         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
         filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+        filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
         context.registerReceiver(this, filter);
 
+        // AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
+        updateAirplaneMode();
+
         // yuck
         mBatteryStats = BatteryStatsService.getService();
     }
@@ -228,6 +234,9 @@
             refreshViews();
         } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
             refreshViews();
+        } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
+            updateAirplaneMode();
+            refreshViews();
         }
     }
 
@@ -343,18 +352,17 @@
         return (! "wifi-only".equals(SystemProperties.get("ro.carrier")));
     }
 
+
+    private void updateAirplaneMode() {
+        mAirplaneMode = (Settings.System.getInt(mContext.getContentResolver(),
+            Settings.System.AIRPLANE_MODE_ON, 0) == 1);
+    }
+
     private final void updateTelephonySignalStrength() {
-        // Display signal strength while in "emergency calls only" mode
-        if (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly())) {
+        if (!hasService()) {
             //Slog.d(TAG, "updateTelephonySignalStrength: no service");
-            if (Settings.System.getInt(mContext.getContentResolver(),
-                    Settings.System.AIRPLANE_MODE_ON, 0) == 1) {
-                mPhoneSignalIconId = R.drawable.stat_sys_signal_flightmode;
-                mDataSignalIconId = R.drawable.stat_sys_signal_flightmode;
-            } else {
-                mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
-                mDataSignalIconId = R.drawable.stat_sys_signal_0; // note we use 0 instead of null
-            }
+            mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
+            mDataSignalIconId = R.drawable.stat_sys_signal_0; // note we use 0 instead of null
         } else {
             if (mSignalStrength == null) {
                 mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
@@ -719,6 +727,12 @@
             label = mContext.getString(R.string.bluetooth_tethered);
             combinedSignalIconId = mBluetoothTetherIconId;
             dataTypeIconId = 0;
+        } else if (mAirplaneMode &&
+                (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly()))) {
+            // Only display the flight-mode icon if not in "emergency calls only" mode.
+            label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
+            combinedSignalIconId = R.drawable.stat_sys_signal_flightmode;
+            dataTypeIconId = 0;
         } else {
             label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
             // On devices without mobile radios, we want to show the wifi icon
@@ -732,6 +746,7 @@
                     + Integer.toHexString(combinedSignalIconId)
                     + "/" + getResourceName(combinedSignalIconId)
                     + " dataDirectionOverlayIconId=0x" + Integer.toHexString(dataDirectionOverlayIconId)
+                    + " mAirplaneMode=" + mAirplaneMode
                     + " mDataActivity=" + mDataActivity
                     + " mPhoneSignalIconId=0x" + Integer.toHexString(mPhoneSignalIconId)
                     + " mDataDirectionIconId=0x" + Integer.toHexString(mDataDirectionIconId)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index 2ec2af0..8a88792 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -164,7 +164,7 @@
     }
 
     public void setNotificationCount(int n) {
-        Slog.d(TAG, "notificationCount=" + n);
+//        Slog.d(TAG, "notificationCount=" + n);
         if (!mShowing) {
             // just do it, already
             setContentFrameVisible(n > 0, false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
index ebe1a7c..1135b73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
@@ -40,7 +40,6 @@
 import android.graphics.Shader.TileMode;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
-import android.os.Parcelable;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -64,7 +63,6 @@
     private static final boolean DEBUG = TabletStatusBar.DEBUG;
     private static final int DISPLAY_TASKS = 20;
     private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps
-    private static final int BOTTOM_OFFSET = 28; // TODO: Get from dimens.xml
     private TabletStatusBar mBar;
     private ArrayList<ActivityDescription> mActivityDescriptions;
     private int mIconDpi;
@@ -104,7 +102,7 @@
         }
     };
 
-    private static class ViewHolder {
+    /* package */ final static class ViewHolder {
         private ImageView thumbnailView;
         private ImageView iconView;
         private TextView labelView;
@@ -112,7 +110,7 @@
         private ActivityDescription activityDescription;
     }
 
-    private class ActvityDescriptionAdapter extends BaseAdapter {
+    /* package */ final class ActvityDescriptionAdapter extends BaseAdapter {
         private LayoutInflater mInflater;
 
         public ActvityDescriptionAdapter(Context context) {
@@ -361,7 +359,7 @@
         View footer = inflater.inflate(R.layout.status_bar_recent_panel_footer,
                 mRecentsContainer, false);
         mRecentsContainer.setScrollbarFadingEnabled(true);
-        mRecentsContainer.addFooterView(footer);
+        mRecentsContainer.addFooterView(footer, null, false);
         mRecentsContainer.setAdapter(mListAdapter = new ActvityDescriptionAdapter(mContext));
         mRecentsContainer.setOnItemClickListener(this);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index f0408a2..4557105 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -42,11 +42,13 @@
 import android.os.ServiceManager;
 import android.text.TextUtils;
 import android.util.Slog;
+import android.view.accessibility.AccessibilityEvent;
 import android.view.Gravity;
 import android.view.IWindowManager;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
+import android.view.SoundEffectConstants;
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
@@ -113,7 +115,7 @@
     View mNotificationArea;
     View mNotificationTrigger;
     NotificationIconArea mNotificationIconArea;
-    View mNavigationArea;
+    ViewGroup mNavigationArea;
 
     boolean mNotificationDNDMode;
     NotificationData.Entry mNotificationDNDDummyEntry;
@@ -144,7 +146,8 @@
     LocationController mLocationController;
     NetworkController mNetworkController;
 
-    View mBarContents;
+    ViewGroup mBarContents;
+    LayoutTransition mBarContentsLayoutTransition;
 
     // hide system chrome ("lights out") support
     View mShadow;
@@ -344,7 +347,20 @@
 
         sb.setHandler(mHandler);
 
-        mBarContents = sb.findViewById(R.id.bar_contents);
+        mBarContents = (ViewGroup) sb.findViewById(R.id.bar_contents);
+        // layout transitions for the status bar's contents
+        mBarContentsLayoutTransition = new LayoutTransition();
+        // add/removal will fade as normal
+        mBarContentsLayoutTransition.setAnimator(LayoutTransition.APPEARING,
+                ObjectAnimator.ofFloat(null, "alpha", 0f, 1f));
+        mBarContentsLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING,
+                ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
+        // no animations for siblings on change: just jump into place please
+        mBarContentsLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, null);
+        mBarContentsLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, null);
+        // quick like bunny
+        mBarContentsLayoutTransition.setDuration(250 * (DEBUG?10:1));
+        mBarContents.setLayoutTransition(mBarContentsLayoutTransition);
 
         // the whole right-hand side of the bar
         mNotificationArea = sb.findViewById(R.id.notificationArea);
@@ -383,11 +399,12 @@
 
         // The navigation buttons
         mBackButton = (ImageView)sb.findViewById(R.id.back);
-        mNavigationArea = sb.findViewById(R.id.navigationArea);
+        mNavigationArea = (ViewGroup) sb.findViewById(R.id.navigationArea);
         mHomeButton = mNavigationArea.findViewById(R.id.home);
         mMenuButton = mNavigationArea.findViewById(R.id.menu);
         mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
         mRecentButton.setOnClickListener(mOnClickListener);
+        mNavigationArea.setLayoutTransition(mBarContentsLayoutTransition);
 
         // The bar contents buttons
         mNotificationAndImeArea = (ViewGroup)sb.findViewById(R.id.notificationAndImeArea);
@@ -572,7 +589,7 @@
                     if (!mNotificationPanel.isShowing()) {
                         mNotificationPeekWindow.setVisibility(View.GONE);
                         mNotificationPanel.show(true, true);
-                        mNotificationArea.setVisibility(View.GONE);
+                        mNotificationArea.setVisibility(View.INVISIBLE);
                         mTicker.halt();
                     }
                     break;
@@ -586,8 +603,7 @@
                 case MSG_OPEN_RECENTS_PANEL:
                     if (DEBUG) Slog.d(TAG, "opening recents panel");
                     if (mRecentsPanel != null) {
-                        disable(StatusBarManager.DISABLE_NAVIGATION
-                                | StatusBarManager.DISABLE_BACK);
+                        disable(StatusBarManager.DISABLE_BACK);
                         mRecentsPanel.setVisibility(View.VISIBLE);
                         mRecentsPanel.show(true, true);
                     }
@@ -831,7 +847,7 @@
         if ((diff & StatusBarManager.DISABLE_NAVIGATION) != 0) {
             if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) {
                 Slog.i(TAG, "DISABLE_NAVIGATION: yes");
-                mNavigationArea.setVisibility(View.GONE);
+                mNavigationArea.setVisibility(View.INVISIBLE);
                 mInputMethodSwitchButton.setScreenLocked(true);
             } else {
                 Slog.i(TAG, "DISABLE_NAVIGATION: no");
@@ -1182,6 +1198,8 @@
                          // dragging off the bottom doesn't count
                          && (int)event.getY() < v.getBottom()) {
                             animateExpand();
+                            v.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+                            v.playSoundEffect(SoundEffectConstants.CLICK);
                         }
 
                         mVT.recycle();
@@ -1265,17 +1283,23 @@
                 case MotionEvent.ACTION_UP:
                 case MotionEvent.ACTION_CANCEL:
                     mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
-                    if (action == MotionEvent.ACTION_UP
-                            // was this a sloppy tap?
-                            && Math.abs(event.getX() - mInitialTouchX) < mTouchSlop 
-                            && Math.abs(event.getY() - mInitialTouchY) < (mTouchSlop / 3)
-                            // dragging off the bottom doesn't count
-                            && (int)event.getY() < v.getBottom()) {
-                        Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK);
-                        peekMsg.arg1 = mPeekIndex;
-                        mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
-                        mHandler.sendMessage(peekMsg);
-                        peeking = true; // not technically true yet, but the next line will run
+                    if (!peeking) {
+                        if (action == MotionEvent.ACTION_UP
+                                // was this a sloppy tap?
+                                && Math.abs(event.getX() - mInitialTouchX) < mTouchSlop 
+                                && Math.abs(event.getY() - mInitialTouchY) < (mTouchSlop / 3)
+                                // dragging off the bottom doesn't count
+                                && (int)event.getY() < v.getBottom()) {
+                            Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK);
+                            peekMsg.arg1 = mPeekIndex;
+                            mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
+                            mHandler.sendMessage(peekMsg);
+
+                            v.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+                            v.playSoundEffect(SoundEffectConstants.CLICK);
+
+                            peeking = true; // not technically true yet, but the next line will run
+                        }
                     }
 
                     if (peeking) {
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 886b85f..2fda3aa 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -163,6 +163,12 @@
      */
     private Configuration mConfiguration;
 
+    private Runnable mRecreateRunnable = new Runnable() {
+        public void run() {
+            recreateScreens();
+        }
+    };
+
     /**
      * @return Whether we are stuck on the lock screen because the sim is
      *   missing.
@@ -244,7 +250,8 @@
 
             public void recreateMe(Configuration config) {
                 mConfiguration = config;
-                recreateScreens();
+                removeCallbacks(mRecreateRunnable);
+                post(mRecreateRunnable);
             }
 
             public void takeEmergencyCallAction() {
@@ -463,6 +470,12 @@
     }
 
     @Override
+    protected void onDetachedFromWindow() {
+        removeCallbacks(mRecreateRunnable);
+        super.onDetachedFromWindow();
+    }
+
+    @Override
     public void wakeWhenReadyTq(int keyCode) {
         if (DEBUG) Log.d(TAG, "onWakeKey");
         if (keyCode == KeyEvent.KEYCODE_MENU && isSecure() && (mMode == Mode.LockScreen)
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index d342d669..ec89db3 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -222,7 +222,7 @@
         }
         mLayoutInflater.inflate(layoutResID, mContentParent);
         final Callback cb = getCallback();
-        if (cb != null) {
+        if (cb != null && !isDestroyed()) {
             cb.onContentChanged();
         }
     }
@@ -241,7 +241,7 @@
         }
         mContentParent.addView(view, params);
         final Callback cb = getCallback();
-        if (cb != null) {
+        if (cb != null && !isDestroyed()) {
             cb.onContentChanged();
         }
     }
@@ -253,7 +253,7 @@
         }
         mContentParent.addView(view, params);
         final Callback cb = getCallback();
-        if (cb != null) {
+        if (cb != null && !isDestroyed()) {
             cb.onContentChanged();
         }
     }
@@ -316,6 +316,10 @@
      *         returns false.
      */
     public final boolean preparePanel(PanelFeatureState st, KeyEvent event) {
+        if (isDestroyed()) {
+            return false;
+        }
+
         // Already prepared (isPrepared will be reset to false later)
         if (st.isPrepared)
             return true;
@@ -437,7 +441,7 @@
         // System.out.println("Open panel: isOpen=" + st.isOpen);
 
         // Already open, return
-        if (st.isOpen) {
+        if (st.isOpen || isDestroyed()) {
             return;
         }
 
@@ -609,7 +613,7 @@
             closed = true;
         }
         Callback cb = getCallback();
-        if (cb != null && closed) {
+        if (cb != null && closed && !isDestroyed()) {
             cb.onPanelClosed(FEATURE_ACTION_BAR, menu);
         }
         mClosingActionMenu = false;
@@ -688,7 +692,7 @@
                 if (mActionBar.getVisibility() == View.VISIBLE) {
                     if (!mActionBar.isOverflowMenuShowing()) {
                         final Callback cb = getCallback();
-                        if (cb != null &&
+                        if (cb != null && !isDestroyed() &&
                                 cb.onPreparePanel(featureId, st.createdPanelView, st.menu)) {
                             playSoundEffect = mActionBar.showOverflowMenu();
                         }
@@ -837,7 +841,7 @@
 
     public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
         final Callback cb = getCallback();
-        if (cb != null) {
+        if (cb != null && !isDestroyed()) {
             final PanelFeatureState panel = findMenuPanel(menu.getRootMenu());
             if (panel != null) {
                 return cb.onMenuItemSelected(panel.featureId, item);
@@ -881,7 +885,7 @@
                     mActionButtonPopup = new ActionButtonSubmenu(getContext(), subMenu);
                     mActionButtonPopup.show();
                     Callback cb = getCallback();
-                    if (cb != null) {
+                    if (cb != null && !isDestroyed()) {
                         cb.onMenuOpened(FEATURE_ACTION_BAR, subMenu);
                     }
                 }
@@ -902,7 +906,7 @@
         if (mActionBar != null) {
             final Callback cb = getCallback();
             if (!mActionBar.isOverflowMenuShowing() || !toggleMenuMode) {
-                if (cb != null && mActionBar.getVisibility() == View.VISIBLE) {
+                if (cb != null && !isDestroyed() && mActionBar.getVisibility() == View.VISIBLE) {
                     final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
                     if (cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) {
                         cb.onMenuOpened(FEATURE_ACTION_BAR, st.menu);
@@ -911,7 +915,7 @@
                 }
             } else {
                 mActionBar.hideOverflowMenu();
-                if (cb != null) {
+                if (cb != null && !isDestroyed()) {
                     final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
                     cb.onPanelClosed(FEATURE_ACTION_BAR, st.menu);
                 }
@@ -1641,11 +1645,13 @@
                 return true;
             }
 
-            final Callback cb = getCallback();
-            final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event)
-                    : super.dispatchKeyEvent(event);
-            if (handled) {
-                return true;
+            if (!isDestroyed()) {
+                final Callback cb = getCallback();
+                final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event)
+                        : super.dispatchKeyEvent(event);
+                if (handled) {
+                    return true;
+                }
             }
             return isDown ? PhoneWindow.this.onKeyDown(mFeatureId, event.getKeyCode(), event)
                     : PhoneWindow.this.onKeyUp(mFeatureId, event.getKeyCode(), event);
@@ -1667,29 +1673,29 @@
 
             // Shortcut not handled by the panel.  Dispatch to the view hierarchy.
             final Callback cb = getCallback();
-            return cb != null && mFeatureId < 0 ? cb.dispatchKeyShortcutEvent(ev) : super
-                    .dispatchKeyShortcutEvent(ev);
+            return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchKeyShortcutEvent(ev)
+                    : super.dispatchKeyShortcutEvent(ev);
         }
 
         @Override
         public boolean dispatchTouchEvent(MotionEvent ev) {
             final Callback cb = getCallback();
-            return cb != null && mFeatureId < 0 ? cb.dispatchTouchEvent(ev) : super
-                    .dispatchTouchEvent(ev);
+            return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev)
+                    : super.dispatchTouchEvent(ev);
         }
 
         @Override
         public boolean dispatchTrackballEvent(MotionEvent ev) {
             final Callback cb = getCallback();
-            return cb != null && mFeatureId < 0 ? cb.dispatchTrackballEvent(ev) : super
-                    .dispatchTrackballEvent(ev);
+            return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTrackballEvent(ev)
+                    : super.dispatchTrackballEvent(ev);
         }
 
         @Override
         public boolean dispatchGenericMotionEvent(MotionEvent ev) {
             final Callback cb = getCallback();
-            return cb != null && mFeatureId < 0 ? cb.dispatchGenericMotionEvent(ev) : super
-                    .dispatchGenericMotionEvent(ev);
+            return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchGenericMotionEvent(ev)
+                    : super.dispatchGenericMotionEvent(ev);
         }
 
         public boolean superDispatchKeyEvent(KeyEvent event) {
@@ -1822,7 +1828,7 @@
         @Override
         public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
             final Callback cb = getCallback();
-            if (cb != null) {
+            if (cb != null && !isDestroyed()) {
                 if (cb.dispatchPopulateAccessibilityEvent(event)) {
                     return true;
                 }
@@ -1953,10 +1959,12 @@
 
             final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
             ActionMode mode = null;
-            try {
-                mode = getCallback().onWindowStartingActionMode(wrappedCallback);
-            } catch (AbstractMethodError ame) {
-                // Older apps might not implement this callback method.
+            if (getCallback() != null && !isDestroyed()) {
+                try {
+                    mode = getCallback().onWindowStartingActionMode(wrappedCallback);
+                } catch (AbstractMethodError ame) {
+                    // Older apps might not implement this callback method.
+                }
             }
             if (mode != null) {
                 mActionMode = mode;
@@ -2008,7 +2016,7 @@
                     }
                 }
             }
-            if (mActionMode != null) {
+            if (mActionMode != null && getCallback() != null && !isDestroyed()) {
                 try {
                     getCallback().onActionModeStarted(mActionMode);
                 } catch (AbstractMethodError ame) {
@@ -2140,7 +2148,7 @@
             }
 
             final Callback cb = getCallback();
-            if (cb != null && mFeatureId < 0) {
+            if (cb != null && !isDestroyed() && mFeatureId < 0) {
                 cb.onWindowFocusChanged(hasWindowFocus);
             }
         }
@@ -2158,7 +2166,7 @@
             updateWindowResizeState();
             
             final Callback cb = getCallback();
-            if (cb != null && mFeatureId < 0) {
+            if (cb != null && !isDestroyed() && mFeatureId < 0) {
                 cb.onAttachedToWindow();
             }
 
@@ -2179,7 +2187,7 @@
             super.onDetachedFromWindow();
             
             final Callback cb = getCallback();
-            if (cb != null && mFeatureId < 0) {
+            if (cb != null && !isDestroyed() && mFeatureId < 0) {
                 cb.onDetachedFromWindow();
             }
 
@@ -2268,10 +2276,12 @@
                 if (mActionModeView != null) {
                     mActionModeView.removeAllViews();
                 }
-                try {
-                    getCallback().onActionModeFinished(mActionMode);
-                } catch (AbstractMethodError ame) {
-                    // Older apps might not implement this callback method.
+                if (getCallback() != null && !isDestroyed()) {
+                    try {
+                        getCallback().onActionModeFinished(mActionMode);
+                    } catch (AbstractMethodError ame) {
+                        // Older apps might not implement this callback method.
+                    }
                 }
                 mActionMode = null;
             }
@@ -2820,7 +2830,9 @@
         if ((panel != null) && (!panel.isOpen))
             return;
 
-        cb.onPanelClosed(featureId, menu);
+        if (!isDestroyed()) {
+            cb.onPanelClosed(featureId, menu);
+        }
     }
 
     /**
@@ -2831,7 +2843,7 @@
      */
     private boolean launchDefaultSearch() {
         final Callback cb = getCallback();
-        if (cb == null) {
+        if (cb == null || isDestroyed()) {
             return false;
         } else {
             sendCloseSystemWindows("search");
@@ -3065,7 +3077,9 @@
         public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
             if (allMenusAreClosing) {
                 Callback callback = getCallback();
-                if (callback != null) callback.onPanelClosed(mFeatureId, menu);
+                if (callback != null && !isDestroyed()) {
+                    callback.onPanelClosed(mFeatureId, menu);
+                }
 
                 if (menu == mContextMenu) {
                     dismissContextMenu();
@@ -3081,12 +3095,15 @@
 
         public void onCloseSubMenu(SubMenuBuilder menu) {
             Callback callback = getCallback();
-            if (callback != null) callback.onPanelClosed(mFeatureId, menu.getRootMenu());
+            if (callback != null && !isDestroyed()) {
+                callback.onPanelClosed(mFeatureId, menu.getRootMenu());
+            }
         }
 
         public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
             Callback callback = getCallback();
-            return (callback != null) && callback.onMenuItemSelected(mFeatureId, item);
+            return (callback != null && !isDestroyed())
+                    && callback.onMenuItemSelected(mFeatureId, item);
         }
 
         public void onMenuModeChange(MenuBuilder menu) {
@@ -3145,7 +3162,7 @@
         public void run() {
             if (tryShow()) {
                 Callback cb = getCallback();
-                if (cb != null) {
+                if (cb != null && !isDestroyed()) {
                     cb.onMenuOpened(FEATURE_ACTION_BAR, mSubMenu);
                 }
             }
diff --git a/policy/src/com/android/internal/policy/impl/StatusView.java b/policy/src/com/android/internal/policy/impl/StatusView.java
index 2aff4a8..46ce5a3 100644
--- a/policy/src/com/android/internal/policy/impl/StatusView.java
+++ b/policy/src/com/android/internal/policy/impl/StatusView.java
@@ -20,7 +20,7 @@
 
 class StatusView {
     public static final int LOCK_ICON = 0; // R.drawable.ic_lock_idle_lock;
-    public static final int ALARM_ICON = 0; // R.drawable.ic_lock_idle_alarm;
+    public static final int ALARM_ICON = R.drawable.ic_lock_idle_alarm;
     public static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
     public static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
 
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index c061a83..b7d0a8f 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -286,8 +286,8 @@
                     com.android.internal.R.string.config_default_dns_server);
         }
         try {
-            mDefaultDns = InetAddress.getByName(dns);
-        } catch (UnknownHostException e) {
+            mDefaultDns = NetworkUtils.numericToInetAddress(dns);
+        } catch (IllegalArgumentException e) {
             loge("Error setting defaultDns using " + dns);
         }
 
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index eaf68b0..44f5df2 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -270,9 +270,9 @@
             InetAddress addr = null;
             int prefixLength = 0;
             try {
-                addr = InetAddress.getByName(st.nextToken(" "));
-            } catch (UnknownHostException uhe) {
-                Slog.e(TAG, "Failed to parse ipaddr", uhe);
+                addr = NetworkUtils.numericToInetAddress(st.nextToken(" "));
+            } catch (IllegalArgumentException iae) {
+                Slog.e(TAG, "Failed to parse ipaddr", iae);
             }
 
             try {
@@ -451,7 +451,7 @@
         try {
             String cmd = "tether dns set";
             for (String s : dns) {
-                cmd += " " + InetAddress.getByName(s).getHostAddress();
+                cmd += " " + NetworkUtils.numericToInetAddress(s).getHostAddress();
             }
             try {
                 mConnector.doCommand(cmd);
@@ -459,7 +459,7 @@
                 throw new IllegalStateException(
                         "Unable to communicate to native daemon for setting tether dns");
             }
-        } catch (UnknownHostException e) {
+        } catch (IllegalArgumentException e) {
             throw new IllegalStateException("Error resolving dns name", e);
         }
     }
@@ -519,11 +519,11 @@
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
             mConnector.doCommand(String.format("pppd attach %s %s %s %s %s", tty,
-                    InetAddress.getByName(localAddr).getHostAddress(),
-                    InetAddress.getByName(remoteAddr).getHostAddress(),
-                    InetAddress.getByName(dns1Addr).getHostAddress(),
-                    InetAddress.getByName(dns2Addr).getHostAddress()));
-        } catch (UnknownHostException e) {
+                    NetworkUtils.numericToInetAddress(localAddr).getHostAddress(),
+                    NetworkUtils.numericToInetAddress(remoteAddr).getHostAddress(),
+                    NetworkUtils.numericToInetAddress(dns1Addr).getHostAddress(),
+                    NetworkUtils.numericToInetAddress(dns2Addr).getHostAddress()));
+        } catch (IllegalArgumentException e) {
             throw new IllegalStateException("Error resolving addr", e);
         } catch (NativeDaemonConnectorException e) {
             throw new IllegalStateException("Error communicating to native daemon to attach pppd", e);
diff --git a/services/java/com/android/server/NetworkTimeUpdateService.java b/services/java/com/android/server/NetworkTimeUpdateService.java
index 52f84eb..15f22c0 100644
--- a/services/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/java/com/android/server/NetworkTimeUpdateService.java
@@ -26,6 +26,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
 import android.net.SntpClient;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -58,6 +60,7 @@
 
     private static final int EVENT_AUTO_TIME_CHANGED = 1;
     private static final int EVENT_POLL_NETWORK_TIME = 2;
+    private static final int EVENT_WIFI_CONNECTED = 3;
 
     /** Normal polling frequency */
     private static final long POLLING_INTERVAL_MS = 24L * 60 * 60 * 1000; // 24 hrs
@@ -113,6 +116,7 @@
 
         registerForTelephonyIntents();
         registerForAlarms();
+        registerForConnectivityIntents();
 
         mThread = new HandlerThread(TAG);
         mThread.start();
@@ -162,6 +166,12 @@
             }, new IntentFilter(ACTION_POLL));
     }
 
+    private void registerForConnectivityIntents() {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+        mContext.registerReceiver(mConnectivityReceiver, intentFilter);
+    }
+
     private void onPollNetworkTime(int event) {
         // If Automatic time is not set, don't bother.
         if (!isAutomaticTimeRequested()) return;
@@ -253,6 +263,27 @@
         }
     };
 
+    /** Receiver for ConnectivityManager events */
+    private BroadcastReceiver mConnectivityReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
+                // There is connectivity
+                NetworkInfo netInfo = (NetworkInfo)intent.getParcelableExtra(
+                        ConnectivityManager.EXTRA_NETWORK_INFO);
+                if (netInfo != null) {
+                    // Verify that it's a WIFI connection
+                    if (netInfo.getState() == NetworkInfo.State.CONNECTED &&
+                            netInfo.getType() == ConnectivityManager.TYPE_WIFI ) {
+                        mHandler.obtainMessage(EVENT_WIFI_CONNECTED).sendToTarget();
+                    }
+                }
+            }
+        }
+    };
+
     /** Handler to do the network accesses on */
     private class MyHandler extends Handler {
 
@@ -265,6 +296,7 @@
             switch (msg.what) {
                 case EVENT_AUTO_TIME_CHANGED:
                 case EVENT_POLL_NETWORK_TIME:
+                case EVENT_WIFI_CONNECTED:
                     onPollNetworkTime(msg.what);
                     break;
             }
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index f1a6e15..461a3e5 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -6204,10 +6204,10 @@
         mHandler.post(new Runnable() {
             public void run() {
                 mHandler.removeCallbacks(this);
-                final boolean succeded = deletePackageX(packageName, true, true, flags);
+                final int returnCode = deletePackageX(packageName, true, true, flags);
                 if (observer != null) {
                     try {
-                        observer.packageDeleted(succeded);
+                        observer.packageDeleted(packageName, returnCode);
                     } catch (RemoteException e) {
                         Log.i(TAG, "Observer no longer exists.");
                     } //end catch
@@ -6230,17 +6230,17 @@
      *  persisting settings for later use
      *  sending a broadcast if necessary
      */
-    private boolean deletePackageX(String packageName, boolean sendBroadCast,
+    private int deletePackageX(String packageName, boolean sendBroadCast,
                                    boolean deleteCodeAndResources, int flags) {
-        PackageRemovedInfo info = new PackageRemovedInfo();
-        boolean res;
+        final PackageRemovedInfo info = new PackageRemovedInfo();
+        final boolean res;
 
         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
         try {
             if (dpm != null && dpm.packageHasActiveAdmins(packageName)) {
                 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
-                return false;
+                return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
             }
         } catch (RemoteException e) {
         }
@@ -6250,7 +6250,7 @@
                     flags | REMOVE_CHATTY, info, true);
         }
 
-        if(res && sendBroadCast) {
+        if (res && sendBroadCast) {
             boolean systemUpdate = info.isRemovedPackageSystemUpdate;
             info.sendBroadcast(deleteCodeAndResources, systemUpdate);
 
@@ -6278,7 +6278,8 @@
                 info.args.doPostDeleteLI(deleteCodeAndResources);
             }
         }
-        return res;
+
+        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
     }
 
     static class PackageRemovedInfo {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index ea49661..e6dfb7f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -180,6 +180,7 @@
     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
     
     private static final String SYSTEM_SECURE = "ro.secure";
+    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
 
     // This is the maximum number of application processes we would like
     // to have running.  Due to the asynchronous nature of things, we can
@@ -12940,8 +12941,8 @@
                     throw new IllegalArgumentException("Unknown process: " + process);
                 }
                 
-                boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
-                if (isSecure) {
+                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
+                if (!isDebuggable) {
                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
                         throw new SecurityException("Process not debuggable: " + proc);
                     }
@@ -13002,8 +13003,8 @@
                     throw new IllegalArgumentException("Unknown process: " + process);
                 }
 
-                boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
-                if (isSecure) {
+                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
+                if (!isDebuggable) {
                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
                         throw new SecurityException("Process not debuggable: " + proc);
                     }
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 1eb5141..5853696 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -34,6 +34,7 @@
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.NetworkInfo;
+import android.net.NetworkUtils;
 import android.os.Binder;
 import android.os.Environment;
 import android.os.Handler;
@@ -567,7 +568,7 @@
                 try {
                     ifcg = service.getInterfaceConfig(iface);
                     if (ifcg != null) {
-                        InetAddress addr = InetAddress.getByName(USB_NEAR_IFACE_ADDR);
+                        InetAddress addr = NetworkUtils.numericToInetAddress(USB_NEAR_IFACE_ADDR);
                         ifcg.addr = new LinkAddress(addr, USB_PREFIX_LENGTH);
                         if (enabled) {
                             ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up");
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index e0b9603..89513fd 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -23,6 +23,7 @@
 import android.net.LinkAddress;
 import android.net.LinkCapabilities;
 import android.net.LinkProperties;
+import android.net.NetworkUtils;
 import android.os.AsyncResult;
 import android.os.Message;
 import android.os.SystemProperties;
@@ -415,11 +416,13 @@
                             } else {
                                 addrPrefixLen = 0;
                             }
-                            if (!InetAddress.isNumeric(addr)) {
+                            InetAddress ia;
+                            try {
+                                ia = NetworkUtils.numericToInetAddress(addr);
+                            } catch (IllegalArgumentException e) {
                                 EventLogTags.writeBadIpAddress(addr);
                                 throw new UnknownHostException("Non-numeric ip addr=" + addr);
                             }
-                            InetAddress ia = InetAddress.getByName(addr);
                             if (addrPrefixLen == 0) {
                                 // Assume point to point
                                 addrPrefixLen = (ia instanceof Inet4Address) ? 32 : 128;
@@ -434,11 +437,13 @@
                     }
                     if (response.dnses != null && response.dnses.length > 0) {
                         for (String addr : response.dnses) {
-                            if (!InetAddress.isNumeric(addr)) {
+                            InetAddress ia;
+                            try {
+                                ia = NetworkUtils.numericToInetAddress(addr);
+                            } catch (IllegalArgumentException e) {
                                 EventLogTags.writePdpBadDnsAddress("dns=" + addr); 
                                 throw new UnknownHostException("Non-numeric dns addr=" + addr);
                             }
-                            InetAddress ia = InetAddress.getByName(addr);
                             linkProperties.addDns(ia);
                         }
                         result = SetupResult.SUCCESS;
@@ -448,12 +453,14 @@
                         dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
                         if (isDnsOk(dnsServers)) {
                             for (String dnsAddr : dnsServers) {
-                                if (!InetAddress.isNumeric(dnsAddr)) {
+                                InetAddress ia;
+                                try {
+                                    ia = NetworkUtils.numericToInetAddress(dnsAddr);
+                                } catch (IllegalArgumentException e) {
                                     EventLogTags.writePdpBadDnsAddress("dnsAddr=" + dnsAddr);
                                     throw new UnknownHostException("Non-numeric dns addr="
                                                 + dnsAddr);
                                 }
-                                InetAddress ia = InetAddress.getByName(dnsAddr);
                                 linkProperties.addDns(ia);
                             }
                             result = SetupResult.SUCCESS;
@@ -476,11 +483,13 @@
                         }
                     }
                     for (String addr : response.gateways) {
-                        if (!InetAddress.isNumeric(addr)) {
+                        InetAddress ia;
+                        try {
+                            ia = NetworkUtils.numericToInetAddress(addr);
+                        } catch (IllegalArgumentException e) {
                             EventLogTags.writePdpBadDnsAddress("gateway=" + addr);
                             throw new UnknownHostException("Non-numeric gateway addr=" + addr);
                         }
-                        InetAddress ia = InetAddress.getByName(addr);
                         linkProperties.addGateway(ia);
                     }
                     result = SetupResult.SUCCESS;
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index d411715..f6317f5 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -686,13 +686,15 @@
                         } else if (key.equals(IP_ASSIGNMENT_KEY)) {
                             ipAssignment = IpAssignment.valueOf(in.readUTF());
                         } else if (key.equals(LINK_ADDRESS_KEY)) {
-                            LinkAddress linkAddr = new LinkAddress(InetAddress.getByName(
-                                    in.readUTF()), in.readInt());
+                            LinkAddress linkAddr = new LinkAddress(
+                                    NetworkUtils.numericToInetAddress(in.readUTF()), in.readInt());
                             linkProperties.addLinkAddress(linkAddr);
                         } else if (key.equals(GATEWAY_KEY)) {
-                            linkProperties.addGateway(InetAddress.getByName(in.readUTF()));
+                            linkProperties.addGateway(
+                                    NetworkUtils.numericToInetAddress(in.readUTF()));
                         } else if (key.equals(DNS_KEY)) {
-                            linkProperties.addDns(InetAddress.getByName(in.readUTF()));
+                            linkProperties.addDns(
+                                    NetworkUtils.numericToInetAddress(in.readUTF()));
                         } else if (key.equals(PROXY_SETTINGS_KEY)) {
                             proxySettings = ProxySettings.valueOf(in.readUTF());
                         } else if (key.equals(PROXY_HOST_KEY)) {
@@ -706,7 +708,7 @@
                         } else {
                             Log.e(TAG, "Ignore unknown key " + key + "while reading");
                         }
-                    } catch (UnknownHostException e) {
+                    } catch (IllegalArgumentException e) {
                         Log.e(TAG, "Ignore invalid address while reading" + e);
                     }
                 } while (true);
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index d6f8e51..e89858c9 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -996,7 +996,8 @@
                         ifcg = service.getInterfaceConfig(intf);
                         if (ifcg != null) {
                             /* IP/netmask: 192.168.43.1/255.255.255.0 */
-                            ifcg.addr = new LinkAddress(InetAddress.getByName("192.168.43.1"), 24);
+                            ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress(
+                                    "192.168.43.1"), 24);
                             ifcg.interfaceFlags = "[up]";
 
                             service.setInterfaceConfig(intf, ifcg);