Merge "PV's mp3 decoder mistreated inputBufferCurrentLength in unit of bytes as in unit of bits"
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/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/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/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/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/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/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
index fbb3c78..677988d 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
@@ -79,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/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/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/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/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/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);