Merge "Allow transitionTo in enter/exit."
diff --git a/api/current.xml b/api/current.xml
index e982dfcb..d3e673e 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -11732,6 +11732,17 @@
  visibility="public"
 >
 </field>
+<field name="custom"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16908331"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="cut"
  type="int"
  transient="false"
@@ -121973,7 +121984,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="message" type="java.lang.String">
+<parameter name="text" type="java.lang.String">
 </parameter>
 </method>
 </class>
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index 2603579..2714de5 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -35,12 +35,12 @@
 /**
  * A subclass of Dialog that can display one, two or three buttons. If you only want to
  * display a String in this dialog box, use the setMessage() method.  If you
- * want to display a more complex view, look up the FrameLayout called "body"
+ * want to display a more complex view, look up the FrameLayout called "custom"
  * and add your view to it:
  *
  * <pre>
- * FrameLayout fl = (FrameLayout) findViewById(R.id.body);
- * fl.add(myView, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));
+ * FrameLayout fl = (FrameLayout) findViewById(android.R.id.custom);
+ * fl.addView(myView, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));
  * </pre>
  * 
  * <p>The AlertDialog class takes care of automatically setting
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index afe4191..1254782 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -167,11 +167,15 @@
     /**
      * Start Wifi Access Point
      */
-    void startAccessPoint(in WifiConfiguration wifiConfig, String intf);
+    void startAccessPoint(in WifiConfiguration wifiConfig, String wlanIface, String softapIface);
 
     /**
      * Stop Wifi Access Point
      */
     void stopAccessPoint();
 
+    /**
+     * Set Access Point config
+     */
+    void setAccessPoint(in WifiConfiguration wifiConfig, String wlanIface, String softapIface);
 }
diff --git a/core/java/android/pim/vcard/VCardEntry.java b/core/java/android/pim/vcard/VCardEntry.java
index 61012c9..e40a7ba 100644
--- a/core/java/android/pim/vcard/VCardEntry.java
+++ b/core/java/android/pim/vcard/VCardEntry.java
@@ -1055,6 +1055,8 @@
     public Uri pushIntoContentResolver(ContentResolver resolver) {
         ArrayList<ContentProviderOperation> operationList =
             new ArrayList<ContentProviderOperation>();
+        // After applying the batch the first result's Uri is returned so it is important that
+        // the RawContact is the first operation that gets inserted into the list
         ContentProviderOperation.Builder builder =
             ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
         String myGroupsId = null;
@@ -1290,8 +1292,11 @@
             ContentProviderResult[] results = resolver.applyBatch(
                         ContactsContract.AUTHORITY, operationList);
             // the first result is always the raw_contact. return it's uri so
-            // that it can be found later
-            return results[0].uri;
+            // that it can be found later. do null checking for badly behaving
+            // ContentResolvers
+            return (results == null || results.length == 0 || results[0] == null)
+                ? null
+                : results[0].uri;
         } catch (RemoteException e) {
             Log.e(LOG_TAG, String.format("%s: %s", e.toString(), e.getMessage()));
             return null;
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index dda9018..1d27828 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -870,6 +870,13 @@
             public static final String ARTIST = "artist";
 
             /**
+             * The artist credited for the album that contains the audio file
+             * <P>Type: TEXT</P>
+             * @hide
+             */
+            public static final String ALBUM_ARTIST = "album_artist";
+
+            /**
              * A non human readable key calculated from the ARTIST, used for
              * searching, sorting and grouping
              * <P>Type: TEXT</P>
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index d8010bc..53c238c 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -124,6 +124,13 @@
         }
     };
     
+    final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener
+            = new ViewTreeObserver.OnScrollChangedListener() {
+                    public void onScrollChanged() {
+                        updateWindow(false);
+                    }
+            };
+            
     boolean mRequestedVisible = false;
     boolean mWindowVisibility = false;
     boolean mViewVisibility = false;
@@ -180,6 +187,7 @@
         mLayout.token = getWindowToken();
         mLayout.setTitle("SurfaceView");
         mViewVisibility = getVisibility() == VISIBLE;
+        getViewTreeObserver().addOnScrollChangedListener(mScrollChangedListener);
     }
 
     @Override
@@ -200,6 +208,7 @@
     
     @Override
     protected void onDetachedFromWindow() {
+        getViewTreeObserver().removeOnScrollChangedListener(mScrollChangedListener);
         mRequestedVisible = false;
         updateWindow(false);
         mHaveFrame = false;
@@ -224,12 +233,6 @@
     }
     
     @Override
-    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
-        super.onScrollChanged(l, t, oldl, oldt);
-        updateWindow(false);
-    }
-
-    @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
         updateWindow(false);
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index ded0559..531d9fe 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -64,6 +64,7 @@
     private static final int STATE_PLAYBACK_COMPLETED = 5;
     private static final int STATE_SUSPEND            = 6;
     private static final int STATE_RESUME             = 7;
+    private static final int STATE_SUSPEND_UNSUPPORTED = 8;
 
     // mCurrentState is a VideoView object's current state.
     // mTargetState is the state that a method caller intends to reach.
@@ -586,8 +587,9 @@
                 mCurrentState = STATE_SUSPEND;
                 mTargetState = STATE_SUSPEND;
             } else {
-                Log.w(TAG, "Unable to suspend video");
-                mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
+                release(false);
+                mCurrentState = STATE_SUSPEND_UNSUPPORTED;
+                Log.w(TAG, "Unable to suspend video. Release MediaPlayer.");
             }
         }
     }
@@ -603,8 +605,11 @@
                 mTargetState = mStateWhenSuspended;
             } else {
                 Log.w(TAG, "Unable to resume video");
-                mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
             }
+            return;
+        }
+        if (mCurrentState == STATE_SUSPEND_UNSUPPORTED) {
+            openVideo();
         }
     }
 
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index f00572d..4e2f9c3 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -531,8 +531,8 @@
         <!-- The screen orientation has changed, that is the user has
              rotated the device. -->
         <flag name="orientation" value="0x0080" />
-        <!-- The screen orientation has changed, that is the user has
-             rotated the device. -->
+        <!-- The screen layout has changed.  This might be caused by a
+             different display being activated. -->
         <flag name="screenLayout" value="0x0100" />
         <!-- The font scaling factor has changed, that is the user has
              selected a new global font size. -->
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index cac26b9..8b6af71 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -67,4 +67,5 @@
   <item type="id" name="addToDictionary" />
   <item type="id" name="accountPreferences" />
   <item type="id" name="smallIcon" />
+  <item type="id" name="custom" />
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 8c00884..a7336fc 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1238,6 +1238,8 @@
   <public type="attr" name="overscrollHeader" id="0x010102bf" />
   <public type="attr" name="overscrollFooter" id="0x010102c0" />
 
-  <public type="anim" name="cycle_interpolator" id="0x010a000c" />
+  <public type="id" name="custom" id="0x0102002b" />
     
+  <public type="anim" name="cycle_interpolator" id="0x010a000c" />
+
 </resources>
diff --git a/core/tests/coretests/src/android/pim/vcard/ImportTestResolver.java b/core/tests/coretests/src/android/pim/vcard/ImportTestResolver.java
index 019b9e3..c3f6f79 100644
--- a/core/tests/coretests/src/android/pim/vcard/ImportTestResolver.java
+++ b/core/tests/coretests/src/android/pim/vcard/ImportTestResolver.java
@@ -215,7 +215,7 @@
                 mTestCase.fail("Unexpected Uri has come: " + uri);
             }
         }  // for (int i = 0; i < size; i++) {
-        return null;
+        return fakeResultArray;
     }
 
     public void verify() {
diff --git a/libs/rs/java/Fountain/res/raw/fountain2.rs b/libs/rs/java/Fountain/res/raw/fountain2.rs
new file mode 100644
index 0000000..3301140
--- /dev/null
+++ b/libs/rs/java/Fountain/res/raw/fountain2.rs
@@ -0,0 +1,73 @@
+// Fountain test script
+#pragma version(1)
+
+#include "rs_types.rsh"
+#include "rs_math.rsh"
+#include "rs_graphics.rsh"
+
+static int newPart = 0;
+
+typedef struct Control_s {
+    int x, y;
+    int rate;
+    int count;
+    float r, g, b;
+    rs_allocation partBuffer;
+    rs_mesh partMesh;
+} Control_t;
+Control_t *Control;
+
+typedef struct Point_s{
+    float2 delta;
+    float2 position;
+    unsigned int color;
+} Point_t;
+Point_t *point;
+
+int main(int launchID) {
+    int ct;
+    int count = Control->count;
+    int rate = Control->rate;
+    float height = getHeight();
+    Point_t * p = point;
+
+    if (rate) {
+        float rMax = ((float)rate) * 0.005f;
+        int x = Control->x;
+        int y = Control->y;
+        int color = ((int)(Control->r * 255.f)) |
+                    ((int)(Control->g * 255.f)) << 8 |
+                    ((int)(Control->b * 255.f)) << 16 |
+                    (0xf0 << 24);
+        Point_t * np = &p[newPart];
+
+        while (rate--) {
+            np->delta = vec2Rand(rMax);
+            np->position.x = x;
+            np->position.y = y;
+            np->color = color;
+            newPart++;
+            np++;
+            if (newPart >= count) {
+                newPart = 0;
+                np = &p[newPart];
+            }
+        }
+    }
+
+    for (ct=0; ct < count; ct++) {
+        float dy = p->delta.y + 0.15f;
+        float posy = p->position.y + dy;
+        if ((posy > height) && (dy > 0)) {
+            dy *= -0.3f;
+        }
+        p->delta.y = dy;
+        p->position.x += p->delta.x;
+        p->position.y = posy;
+        p++;
+    }
+
+    uploadToBufferObject(Control->partBuffer);
+    drawSimpleMesh(Control->partMesh);
+    return 1;
+}
diff --git a/libs/rs/scriptc/rs_graphics.rsh b/libs/rs/scriptc/rs_graphics.rsh
new file mode 100644
index 0000000..70cd562
--- /dev/null
+++ b/libs/rs/scriptc/rs_graphics.rsh
@@ -0,0 +1,65 @@
+
+
+extern float2 vec2Rand(float len);
+
+extern float3 float3Norm(float3);
+extern float float3Length(float3);
+extern float3 float3Add(float3 lhs, float3 rhs);
+extern float3 float3Sub(float3 lhs, float3 rhs);
+extern float3 float3Cross(float3 lhs, float3 rhs);
+extern float float3Dot(float3 lhs, float3 rhs);
+extern float3 float3Scale(float3 v, float scale);
+
+extern float4 float4Add(float4 lhs, float4 rhs);
+extern float4 float4Sub(float4 lhs, float4 rhs);
+extern float4 float4Cross(float4 lhs, float4 rhs);
+extern float float4Dot(float4 lhs, float4 rhs);
+extern float4 float4Scale(float4 v, float scale);
+
+    // context
+extern void bindProgramFragment(rs_program_fragment);
+extern void bindProgramStore(rs_program_store);
+extern void bindProgramVertex(rs_program_vertex);
+
+extern void bindSampler(rs_program_fragment, int slot, rs_sampler);
+extern void bindSampler(rs_program_fragment, int slot, rs_allocation);
+
+extern void vpLoadModelMatrix(const float *);
+extern void vpLoadTextureMatrix(const float *);
+
+
+// drawing
+extern void drawRect(float x1, float y1, float x2, float y2, float z);
+extern void drawQuad(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4);
+extern void drawQuadTexCoords(float x1, float y1, float z1, float u1, float v1, float x2, float y2, float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3, float x4, float y4, float z4, float u4, float v4);
+extern void drawSprite(float x, float y, float z, float w, float h);
+extern void drawSpriteScreenspace(float x, float y, float z, float w, float h);
+extern void drawLine(float x1, float y1, float z1, float x2, float y2, float z2);
+extern void drawPoint(float x1, float y1, float z1);
+extern void drawSimpleMesh(int ism);
+extern void drawSimpleMeshRange(int ism, int start, int len);
+
+// misc
+extern void pfClearColor(float, float, float, float);
+extern void color(float, float, float, float);
+extern void hsb(float, float, float, float);
+extern void hsbToRgb(float, float, float, float*);
+extern int hsbToAbgr(float, float, float, float);
+
+extern void uploadToTexture(int, int);
+extern void uploadToBufferObject(int);
+
+extern int colorFloatRGBAtoUNorm8(float, float, float, float);
+extern int colorFloatRGBto565(float, float, float);
+
+extern int getWidth();
+extern int getHeight();
+
+extern int sendToClient(void *data, int cmdID, int len, int waitForSpace);
+
+extern void debugF(const char *, float);
+extern void debugI32(const char *, int);
+extern void debugHexI32(const char *, int);
+
+
+
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
index ae1acdb..4198a74 100644
--- a/libs/rs/scriptc/rs_types.rsh
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -14,16 +14,16 @@
 typedef uint32_t uint;
 //typedef uint64_t ulong;
 
-typedef void * rs_element;
-typedef void * rs_type;
-typedef void * rs_allocation;
-typedef void * rs_sampler;
-typedef void * rs_script;
-typedef void * rs_mesh;
-typedef void * rs_program_fragment;
-typedef void * rs_program_vertex;
-typedef void * rs_program_raster;
-typedef void * rs_program_store;
+typedef int rs_element;
+typedef int rs_type;
+typedef int rs_allocation;
+typedef int rs_sampler;
+typedef int rs_script;
+typedef int rs_mesh;
+typedef int rs_program_fragment;
+typedef int rs_program_vertex;
+typedef int rs_program_raster;
+typedef int rs_program_store;
 
 typedef float float2 __attribute__((ext_vector_type(2)));
 typedef float float3 __attribute__((ext_vector_type(3)));
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 1047fa4..e9bcafe 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -634,7 +634,11 @@
             } else if (MediaFile.isImageFileType(mFileType)) {
                 // FIXME - add DESCRIPTION
             } else if (MediaFile.isAudioFileType(mFileType)) {
-                map.put(Audio.Media.ARTIST, (mArtist != null && mArtist.length() > 0 ? mArtist : MediaStore.UNKNOWN_STRING));
+                String artist = mArtist != null && mArtist.length() > 0 ?
+                        mArtist : MediaStore.UNKNOWN_STRING;
+                map.put(Audio.Media.ARTIST, artist);
+                map.put(Audio.Media.ALBUM_ARTIST, mAlbumArtist != null &&
+                        mAlbumArtist.length() > 0 ? mAlbumArtist : artist);
                 map.put(Audio.Media.ALBUM, (mAlbum != null && mAlbum.length() > 0 ? mAlbum : MediaStore.UNKNOWN_STRING));
                 map.put(Audio.Media.COMPOSER, mComposer);
                 if (mYear != 0) {
diff --git a/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp b/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp
index fbb6598..553be87 100644
--- a/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp
@@ -21,6 +21,7 @@
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDebug.h>
 #include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
 
 namespace android {
@@ -161,7 +162,14 @@
 
     buffer->set_range(0, kNumSamplesPerFrame * sizeof(int16_t));
 
-    CHECK(numBytesRead <= mInputBuffer->range_length());
+    if (numBytesRead > mInputBuffer->range_length()) {
+        // This is bad, should never have happened, but did. Abort now.
+
+        buffer->release();
+        buffer = NULL;
+
+        return ERROR_MALFORMED;
+    }
 
     mInputBuffer->set_range(
             mInputBuffer->range_offset() + numBytesRead,
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index c05d90a..fcf506d 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -595,6 +595,9 @@
 
     static const int32_t kNumIterations = 5000;
 
+    // We are always going to seek beyond EOS in the first iteration (i == 0)
+    // followed by a linear read for the second iteration (i == 1).
+    // After that it's all random.
     for (int32_t i = 0; i < kNumIterations; ++i) {
         int64_t requestedSeekTimeUs;
         int64_t actualSeekTimeUs;
@@ -602,14 +605,14 @@
 
         double r = uniform_rand();
 
-        if (i > 0 && r < 0.5) {
+        if ((i == 1) || (i > 0 && r < 0.5)) {
             // 50% chance of just continuing to decode from last position.
 
             requestedSeekTimeUs = -1;
 
             LOGI("requesting linear read");
         } else {
-            if (i > 0 && r < 0.55) {
+            if (i == 0 || r < 0.55) {
                 // 5% chance of seeking beyond end of stream.
 
                 requestedSeekTimeUs = durationUs;
@@ -674,7 +677,15 @@
                 buffer = NULL;
             }
         } else if (actualSeekTimeUs < 0) {
-            CHECK(err != OK);
+            EXPECT(err != OK,
+                   "We attempted to seek beyond EOS and expected "
+                   "ERROR_END_OF_STREAM to be returned, but instead "
+                   "we got a valid buffer.");
+            EXPECT(err == ERROR_END_OF_STREAM,
+                   "We attempted to seek beyond EOS and expected "
+                   "ERROR_END_OF_STREAM to be returned, but instead "
+                   "we found some other error.");
+            CHECK_EQ(err, ERROR_END_OF_STREAM);
             CHECK_EQ(buffer, NULL);
         } else {
             EXPECT(err == OK,
diff --git a/packages/TtsService/src/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java
index 2a0bbeb..525a504 100755
--- a/packages/TtsService/src/android/tts/SynthProxy.java
+++ b/packages/TtsService/src/android/tts/SynthProxy.java
@@ -108,7 +108,7 @@
      * Updates the engine configuration.
      */
     public int setConfig(String engineConfig) {
-        return native_setConfig(engineConfig);
+        return native_setConfig(mJniData, engineConfig);
     }
 
     /**
@@ -205,7 +205,7 @@
     private native final int native_loadLanguage(int jniData, String language, String country,
             String variant);
 
-    private native final int native_setConfig(String engineConfig);
+    private native final int native_setConfig(int jniData, String engineConfig);
 
     private native final int native_setSpeechRate(int jniData, int speechRate);
 
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index b114ca2..5be919d 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -460,17 +460,17 @@
         throw new IllegalStateException("Got an empty response");
     }
 
-    public void startAccessPoint(WifiConfiguration wifiConfig, String intf)
+    public void startAccessPoint(WifiConfiguration wifiConfig, String wlanIface, String softapIface)
              throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
         mContext.enforceCallingOrSelfPermission(
-            android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
-        mConnector.doCommand(String.format("softap stop " + intf));
-        mConnector.doCommand(String.format("softap fwreload " + intf + " AP"));
-        mConnector.doCommand(String.format("softap start " + intf));
+                android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
+        mConnector.doCommand(String.format("softap stop " + wlanIface));
+        mConnector.doCommand(String.format("softap fwreload " + wlanIface + " AP"));
+        mConnector.doCommand(String.format("softap start " + wlanIface));
         if (wifiConfig == null) {
-            mConnector.doCommand(String.format("softap set " + intf + " wl0.1"));
+            mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface));
         } else {
             /**
              * softap set arg1 arg2 arg3 [arg4 arg5 arg6 arg7 arg8]
@@ -482,10 +482,9 @@
              * argv6 - Channel
              * argv7 - Preamble
              * argv8 - Max SCB
-             *
-             * TODO: get a configurable softap interface from driver
              */
-            String str = String.format("softap set " + intf + " wl0.1 %s %s %s", wifiConfig.SSID,
+            String str = String.format("softap set " + wlanIface + " " + softapIface + " %s %s %s",
+                                       wifiConfig.SSID,
                                        wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ?
                                        "wpa2-psk" : "open",
                                        wifiConfig.preSharedKey);
@@ -498,8 +497,25 @@
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
         mContext.enforceCallingOrSelfPermission(
-            android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
+                android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
         mConnector.doCommand("softap stopap");
     }
 
+    public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface, String softapIface)
+            throws IllegalStateException {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+        mContext.enforceCallingOrSelfPermission(
+            android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
+        if (wifiConfig == null) {
+            mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface));
+        } else {
+            String str = String.format("softap set " + wlanIface + " " + softapIface +
+                                       " %s %s %s", wifiConfig.SSID,
+                                       wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ?
+                                       "wpa2-psk" : "open",
+                                       wifiConfig.preSharedKey);
+            mConnector.doCommand(str);
+        }
+    }
 }
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 12666927..90529e5 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -96,6 +96,8 @@
     private static final boolean DBG = false;
     private static final Pattern scanResultPattern = Pattern.compile("\t+");
     private final WifiStateTracker mWifiStateTracker;
+    /* TODO: fetch a configurable interface */
+    private static final String SOFTAP_IFACE = "wl0.1";
 
     private Context mContext;
     private int mWifiApState;
@@ -582,9 +584,10 @@
     }
 
     /**
-     * see {@link android.net.wifi.WifiManager#startAccessPoint(WifiConfiguration)}
+     * see {@link android.net.wifi.WifiManager#setWifiApEnabled(WifiConfiguration, boolean)}
      * @param wifiConfig SSID, security and channel details as
      *        part of WifiConfiguration
+     * @param enabled, true to enable and false to disable
      * @return {@code true} if the start operation was
      *         started or is already in the queue.
      */
@@ -656,11 +659,16 @@
             if(enable && (wifiConfig != null)) {
                 try {
                     persistApConfiguration(wifiConfig);
-                    nwService.stopAccessPoint();
-                    nwService.startAccessPoint(wifiConfig, mWifiStateTracker.getInterfaceName());
+                    nwService.setAccessPoint(wifiConfig, mWifiStateTracker.getInterfaceName(),
+                                             SOFTAP_IFACE);
                     return true;
                 } catch(Exception e) {
                     Slog.e(TAG, "Exception in nwService during AP restart");
+                    try {
+                        nwService.stopAccessPoint();
+                    } catch (Exception ee) {
+                        Slog.e(TAG, "Could not stop AP, :" + ee);
+                    }
                     setWifiApEnabledState(WIFI_AP_STATE_FAILED, uid, DriverAction.DRIVER_UNLOAD);
                     return false;
                 }
@@ -696,7 +704,8 @@
             }
 
             try {
-                nwService.startAccessPoint(wifiConfig, mWifiStateTracker.getInterfaceName());
+                nwService.startAccessPoint(wifiConfig, mWifiStateTracker.getInterfaceName(),
+                                           SOFTAP_IFACE);
             } catch(Exception e) {
                 Slog.e(TAG, "Exception in startAccessPoint()");
                 setWifiApEnabledState(WIFI_AP_STATE_FAILED, uid, DriverAction.DRIVER_UNLOAD);
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index 44e0dad..55840e2 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -991,10 +991,10 @@
             // asu = 0 (-113dB or less) is very weak
             // signal, its better to show 0 bars to the user in such cases.
             // asu = 99 is a special case, where the signal strength is unknown.
-            if (asu <= 0 || asu == 99) iconLevel = 0;
-            else if (asu >= 16) iconLevel = 4;
+            if (asu <= 2 || asu == 99) iconLevel = 0;
+            else if (asu >= 12) iconLevel = 4;
             else if (asu >= 8)  iconLevel = 3;
-            else if (asu >= 4)  iconLevel = 2;
+            else if (asu >= 5)  iconLevel = 2;
             else iconLevel = 1;
 
             // Though mPhone is a Manager, this call is not an IPC
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 08530a0..c8b6837 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -37,12 +37,12 @@
           mForce(false), mGrayscaleTolerance(0), mMakePackageDirs(false),
           mUpdate(false), mExtending(false),
           mRequireLocalization(false), mPseudolocalize(false),
-          mUTF8(false), mEncodingSpecified(false), mValues(false),
+          mWantUTF16(false), mValues(false),
           mCompressionMethod(0), mOutputAPKFile(NULL),
           mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
           mAutoAddOverlay(false), mAssetSourceDir(NULL), mProguardFile(NULL),
           mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
-          mRClassDir(NULL), mResourceIntermediatesDir(NULL),
+          mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
           mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
           mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL),
           mArgc(0), mArgv(NULL)
@@ -77,10 +77,8 @@
     void setRequireLocalization(bool val) { mRequireLocalization = val; }
     bool getPseudolocalize(void) const { return mPseudolocalize; }
     void setPseudolocalize(bool val) { mPseudolocalize = val; }
-    bool getUTF8(void) const { return mUTF8; }
-    void setUTF8(bool val) { mUTF8 = val; }
-    bool getEncodingSpecified(void) const { return mEncodingSpecified; }
-    void setEncodingSpecified(bool val) { mEncodingSpecified = val; }
+    bool getWantUTF16(void) const { return mWantUTF16; }
+    void setWantUTF16(bool val) { mWantUTF16 = val; }
     bool getValues(void) const { return mValues; }
     void setValues(bool val) { mValues = val; }
     int getCompressionMethod(void) const { return mCompressionMethod; }
@@ -122,13 +120,10 @@
     const android::Vector<const char*>& getNoCompressExtensions() const { return mNoCompressExtensions; }
     void addNoCompressExtension(const char* ext) { mNoCompressExtensions.add(ext); }
 
+    const char*  getManifestMinSdkVersion() const { return mManifestMinSdkVersion; }
+    void setManifestMinSdkVersion(const char*  val) { mManifestMinSdkVersion = val; }
     const char*  getMinSdkVersion() const { return mMinSdkVersion; }
-    void setMinSdkVersion(const char*  val) {
-        mMinSdkVersion = val;
-        if (!mEncodingSpecified) {
-            setUTF8(isUTF8Available());
-        }
-    }
+    void setMinSdkVersion(const char*  val) { mMinSdkVersion = val; }
     const char*  getTargetSdkVersion() const { return mTargetSdkVersion; }
     void setTargetSdkVersion(const char*  val) { mTargetSdkVersion = val; }
     const char*  getMaxSdkVersion() const { return mMaxSdkVersion; }
@@ -167,6 +162,34 @@
     void setPackageCount(int val) { mPackageCount = val; }
 #endif
 
+    /* UTF-8 is only available on APIs 7 or above or
+     * SDK levels that have code names.
+     */
+    bool isUTF8Available() {
+        /* If the application specifies a minSdkVersion in the manifest
+         * then use that. Otherwise, check what the user specified on
+         * the command line. If neither, it's not available since
+         * the minimum SDK version is assumed to be 1.
+         */
+        const char *minVer;
+        if (mManifestMinSdkVersion != NULL) {
+            minVer = mManifestMinSdkVersion;
+        } else if (mMinSdkVersion != NULL) {
+            minVer = mMinSdkVersion;
+        } else {
+            return false;
+        }
+
+        char *end;
+        int minSdkNum = (int)strtol(minVer, &end, 0);
+        if (*end == '\0') {
+            if (minSdkNum < 7) {
+                return false;
+            }
+        }
+        return true;
+    }
+
 private:
     /* commands & modifiers */
     Command     mCmd;
@@ -179,8 +202,7 @@
     bool        mExtending;
     bool        mRequireLocalization;
     bool        mPseudolocalize;
-    bool        mUTF8;
-    bool        mEncodingSpecified;
+    bool        mWantUTF16;
     bool        mValues;
     int         mCompressionMethod;
     bool        mJunkPath;
@@ -200,6 +222,7 @@
     android::Vector<const char*> mNoCompressExtensions;
     android::Vector<const char*> mResourceSourceDirs;
 
+    const char* mManifestMinSdkVersion;
     const char* mMinSdkVersion;
     const char* mTargetSdkVersion;
     const char* mMaxSdkVersion;
@@ -216,19 +239,6 @@
     int         mPackageCount;
 #endif
 
-    /* UTF-8 is only available on APIs 7 or above or
-     * SDK levels that have code names.
-     */
-    bool isUTF8Available() {
-        char *end;
-        int minSdkNum = (int)strtol(mMinSdkVersion, &end, 0);
-        if (*end == '\0') {
-            if (minSdkNum < 7) {
-                return false;
-            }
-        }
-        return true;
-    }
 };
 
 #endif // __BUNDLE_H
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index dd98c85..b0c6e39 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -446,8 +446,7 @@
                     }
                     bundle.setCustomPackage(argv[0]);
                 } else if (strcmp(cp, "-utf16") == 0) {
-                    bundle.setEncodingSpecified(true);
-                    bundle.setUTF8(false);
+                    bundle.setWantUTF16(true);
                 } else if (strcmp(cp, "-rename-manifest-package") == 0) {
                     argc--;
                     argv++;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index c0ebb59..87f2420 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -226,7 +226,7 @@
                 if (minSdkIndex >= 0) {
                     const uint16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len);
                     const char* minSdk8 = strdup(String8(minSdk16).string());
-                    bundle->setMinSdkVersion(minSdk8);
+                    bundle->setManifestMinSdkVersion(minSdk8);
                 }
             }
         }
@@ -768,7 +768,13 @@
 
     // Standard flags for compiled XML and optional UTF-8 encoding
     int xmlFlags = XML_COMPILE_STANDARD_RESOURCE;
-    if (bundle->getUTF8()) {
+
+    /* Only enable UTF-8 if the caller of aapt didn't specifically
+     * request UTF-16 encoding and the parameters of this package
+     * allow UTF-8 to be used.
+     */
+    if (!bundle->getWantUTF16()
+            && bundle->isUTF8Available()) {
         xmlFlags |= XML_COMPILE_UTF8;
     }
 
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index ab5e937..66db450 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2527,9 +2527,11 @@
     const size_t N = mOrderedPackages.size();
     size_t pi;
 
+    bool useUTF8 = !bundle->getWantUTF16() && bundle->isUTF8Available();
+
     // Iterate through all data, collecting all values (strings,
     // references, etc).
-    StringPool valueStrings = StringPool(false, bundle->getUTF8());
+    StringPool valueStrings = StringPool(false, useUTF8);
     for (pi=0; pi<N; pi++) {
         sp<Package> p = mOrderedPackages.itemAt(pi);
         if (p->getTypes().size() == 0) {
@@ -2537,8 +2539,8 @@
             continue;
         }
 
-        StringPool typeStrings = StringPool(false, bundle->getUTF8());
-        StringPool keyStrings = StringPool(false, bundle->getUTF8());
+        StringPool typeStrings = StringPool(false, useUTF8);
+        StringPool keyStrings = StringPool(false, useUTF8);
 
         const size_t N = p->getOrderedTypes().size();
         for (size_t ti=0; ti<N; ti++) {
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 9339428..abae65d 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -1074,7 +1074,11 @@
                 break;
 
             case EVENT_DEFERRED_RECONNECT:
-                String BSSID = msg.obj.toString();
+                /**
+                 * mLastBssid can be null when there is a reconnect
+                 * request on the first BSSID we connect to
+                 */
+                String BSSID = (msg.obj != null) ? msg.obj.toString() : null;
                 /**
                  * If we've exceeded the maximum number of retries for reconnecting
                  * to a given network, blacklist the BSSID to allow a connection attempt on