Merge change 20493

* changes:
  unhide postUrl
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index ee3ec1a..6b6d3c9 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -268,7 +268,7 @@
 
     private void printRestoreSets(RestoreSet[] sets) {
         for (RestoreSet s : sets) {
-            System.out.println("  " + s.token + " : " + s.name);
+            System.out.println("  " + Long.toHexString(s.token) + " : " + s.name);
         }
     }
 
@@ -294,7 +294,7 @@
     private void doRestore() {
         long token;
         try {
-            token = Long.parseLong(nextArg());
+            token = Long.parseLong(nextArg(), 16);
         } catch (NumberFormatException e) {
             showUsage();
             return;
@@ -311,12 +311,14 @@
                 return;
             }
             RestoreSet[] sets = mRestore.getAvailableRestoreSets();
-            for (RestoreSet s : sets) {
-                if (s.token == token) {
-                    System.out.println("Scheduling restore: " + s.name);
-                    mRestore.performRestore(token, observer);
-                    didRestore = true;
-                    break;
+            if (sets != null) {
+                for (RestoreSet s : sets) {
+                    if (s.token == token) {
+                        System.out.println("Scheduling restore: " + s.name);
+                        mRestore.performRestore(token, observer);
+                        didRestore = true;
+                        break;
+                    }
                 }
             }
             if (!didRestore) {
@@ -327,21 +329,24 @@
                     printRestoreSets(sets);
                 }
             }
+
+            // now wait for it to be done
+            synchronized (observer) {
+                while (!observer.done) {
+                    try {
+                        observer.wait();
+                    } catch (InterruptedException ex) {
+                    }
+                }
+            }
+
+            // once the restore has finished, close down the session and we're done
             mRestore.endRestoreSession();
         } catch (RemoteException e) {
             System.err.println(e.toString());
             System.err.println(BMGR_NOT_RUNNING_ERR);
         }
 
-        // now wait for it to be done
-        synchronized (observer) {
-            while (!observer.done) {
-                try {
-                    observer.wait();
-                } catch (InterruptedException ex) {
-                }
-            }
-        }
         System.out.println("done");
     }
 
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index fd681a2..e6d0503 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -1,5 +1,3 @@
-ifeq ($(BUILD_WITH_STAGEFRIGHT),true)
-
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
@@ -62,5 +60,3 @@
 # LOCAL_MODULE:= play
 # 
 # include $(BUILD_EXECUTABLE)
-
-endif
diff --git a/core/java/android/content/AsyncQueryHandler.java b/core/java/android/content/AsyncQueryHandler.java
index ac851cc..c5606ac 100644
--- a/core/java/android/content/AsyncQueryHandler.java
+++ b/core/java/android/content/AsyncQueryHandler.java
@@ -85,6 +85,7 @@
                             cursor.getCount();
                         }
                     } catch (Exception e) {
+                        Log.d(TAG, e.toString());
                         cursor = null;
                     }
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1db17c8..3e818eb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2992,6 +2992,12 @@
                 "vending_require_sim_for_purchase";
 
         /**
+         * Indicates the Vending Machine backup state. It is set if the
+         * Vending application has been backed up at least once.
+         */
+        public static final String VENDING_BACKUP_STATE = "vending_backup_state";
+
+        /**
          * The current version id of the Vending Machine terms of service.
          */
         public static final String VENDING_TOS_VERSION = "vending_tos_version";
@@ -3298,39 +3304,6 @@
                 "short_keylight_delay_ms";
 
         /**
-         * URL that points to the voice search servers. To be factored out of this class.
-         */
-        public static final String VOICE_SEARCH_URL = "voice_search_url";
-
-        /**
-         * Speech encoding used with voice search on 3G networks. To be factored out of this class.
-         */
-        public static final String VOICE_SEARCH_ENCODING_THREE_G = "voice_search_encoding_three_g";
-
-        /**
-         * Speech encoding used with voice search on WIFI networks. To be factored out of this class.
-         */
-        public static final String VOICE_SEARCH_ENCODING_WIFI = "voice_search_encoding_wifi";
-
-        /**
-         * Whether to use automatic gain control in voice search (0 = disable, 1 = enable).
-         * To be factored out of this class.
-         */
-        public static final String VOICE_SEARCH_ENABLE_AGC = "voice_search_enable_agc";
-
-        /**
-         * Whether to use noise suppression in voice search (0 = disable, 1 = enable).
-         * To be factored out of this class.
-         */
-        public static final String VOICE_SEARCH_ENABLE_NS = "voice_search_enable_ns";
-
-        /**
-         * Whether to use the IIR filter in voice search (0 = disable, 1 = enable).
-         * To be factored out of this class.
-         */
-        public static final String VOICE_SEARCH_ENABLE_IIR = "voice_search_enable_iir";
-
-        /**
          * List of test suites (local disk filename) for the automatic instrumentation test runner.
          * The file format is similar to automated_suites.xml, see AutoTesterService.
          * If this setting is missing or empty, the automatic test runner will not start.
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index 45bd0cf..e4aaf38 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -233,6 +233,8 @@
             if (c.moveToFirst()) {
                 long contactId = c.getLong(EMAIL_LOOKUP_CONTACT_ID_COLUMN_INDEX);
                 bindFromContactId(contactId);
+            } else {
+                bindStatic(emailAddress, "");
             }
         } finally {
             if (c != null) {
@@ -257,6 +259,8 @@
             if (c.moveToFirst()) {
                 long contactId = c.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX);
                 bindFromContactId(contactId);
+            } else {
+                bindStatic(number, "");
             }
         } finally {
             if (c != null) {
@@ -265,6 +269,13 @@
         }
     }
 
+    public void bindStatic(String main, String secondary) {
+        mDisplayNameView.setText(main);
+        mStatusView.setText(secondary);
+        mStarredView.setVisibility(View.GONE);
+        mPhotoView.setImageBitmap(loadPlaceholderPhoto(null));
+    }
+
     protected void redrawHeader() {
         if (mContactDataUri != null) {
             mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, mContactDataUri, HEADER_PROJECTION,
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 4a13e80..527bf07 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -711,6 +711,7 @@
                                 method_onDeviceFound,
                                 env->NewStringUTF(c_address),
                                 str_array);
+            env->DeleteLocalRef(str_array);
         } else
             LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
         return DBUS_HANDLER_RESULT_HANDLED;
@@ -774,6 +775,7 @@
             env->CallVoidMethod(nat->me,
                               method_onPropertyChanged,
                               str_array);
+            env->DeleteLocalRef(str_array);
         } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
         return DBUS_HANDLER_RESULT_HANDLED;
     } else if (dbus_message_is_signal(msg,
@@ -786,6 +788,7 @@
                             method_onDevicePropertyChanged,
                             env->NewStringUTF(remote_device_path),
                             str_array);
+            env->DeleteLocalRef(str_array);
         } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
         return DBUS_HANDLER_RESULT_HANDLED;
 
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index bd3c805..02677f4 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -242,11 +242,12 @@
 
 static inline SkBitmap::Config convertPixelFormat(PixelFormat format)
 {
-    /* note: if PIXEL_FORMAT_XRGB_8888 means that all alpha bytes are 0xFF, then
+    /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
         we can map to SkBitmap::kARGB_8888_Config, and optionally call
         bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
     */
 	switch (format) {
+	case PIXEL_FORMAT_RGBX_8888:    return SkBitmap::kARGB_8888_Config;
     case PIXEL_FORMAT_RGBA_8888:    return SkBitmap::kARGB_8888_Config;
     case PIXEL_FORMAT_RGBA_4444:    return SkBitmap::kARGB_4444_Config;
 	case PIXEL_FORMAT_RGB_565:		return SkBitmap::kRGB_565_Config;
@@ -294,6 +295,9 @@
     SkBitmap bitmap;
     ssize_t bpr = info.s * bytesPerPixel(info.format);
     bitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, bpr);
+    if (info.format == PIXEL_FORMAT_RGBX_8888) {
+        bitmap.setIsOpaque(true);
+    }
     if (info.w > 0 && info.h > 0) {
         bitmap.setPixels(info.bits);
     } else {
diff --git a/core/res/res/values-de/donottranslate-cldr.xml b/core/res/res/values-de/donottranslate-cldr.xml
index babf1a0..8a9c1a7 100644
--- a/core/res/res/values-de/donottranslate-cldr.xml
+++ b/core/res/res/values-de/donottranslate-cldr.xml
@@ -91,17 +91,17 @@
     <string name="today">Heute</string>
     <string name="tomorrow">Morgen</string>
 
-    <string name="hour_minute_24">%-k:%M h</string>
+    <string name="hour_minute_24">%-k:%M</string>
     <string name="hour_minute_ampm">%-l:%M %p</string>
     <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
     <string name="twelve_hour_time_format">h:mm a</string>
-    <string name="twenty_four_hour_time_format">H:mm \'h\'</string>
+    <string name="twenty_four_hour_time_format">H:mm</string>
     <string name="numeric_date">%d.%m.%Y</string>
     <string name="numeric_date_format">dd.MM.yyyy</string>
     <string name="numeric_date_template">"%s.%s.%s"</string>
     <string name="month_day_year">%-e. %B %Y</string>
-    <string name="time_of_day">%H:%M:%S h</string>
-    <string name="date_and_time">%d.%m.%Y, %H:%M:%S h</string>
+    <string name="time_of_day">%H:%M:%S</string>
+    <string name="date_and_time">%d.%m.%Y, %H:%M:%S</string>
     <string name="date_time">%1$s, %2$s</string>
     <string name="time_date">%3$s, %1$s</string>
     <string name="abbrev_month_day_year">%d.%m.%Y</string>
@@ -111,37 +111,37 @@
     <string name="abbrev_month_day">%-e. %b</string>
     <string name="abbrev_month">%-b</string>
     <string name="abbrev_month_year">%b %Y</string>
-    <string name="time1_time2">%1$s bis %2$s</string>
-    <string name="date1_date2">%2$s bis %5$s</string>
-    <string name="numeric_md1_md2">%3$s.%2$s. bis %8$s.%7$s.</string>
-    <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s. bis %6$s, %8$s.%7$s.</string>
-    <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s bis %8$s.%7$s.%9$s</string>
-    <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s bis %6$s, %8$s.%7$s.%9$s</string>
-    <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s.%2$s.%4$s, %5$s bis %6$s, %8$s.%7$s.%9$s, %10$s</string>
-    <string name="numeric_md1_time1_md2_time2">%3$s.%2$s., %5$s bis %8$s.%7$s., %10$s</string>
-    <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %3$s.%2$s., %5$s bis %6$s, %8$s.%7$s., %10$s</string>
-    <string name="numeric_mdy1_time1_mdy2_time2">%3$s.%2$s.%4$s, %5$s bis %8$s.%7$s.%9$s, %10$s</string>
-    <string name="wday1_date1_time1_wday2_date2_time2">%1$s, %2$s, %3$s bis %4$s, %5$s, %6$s</string>
-    <string name="wday1_date1_wday2_date2">%1$s, %2$s bis %4$s, %5$s</string>
-    <string name="date1_time1_date2_time2">%2$s, %3$s bis %5$s, %6$s</string>
+    <string name="time1_time2">%1$s - %2$s</string>
+    <string name="date1_date2">%2$s - %5$s</string>
+    <string name="numeric_md1_md2">%3$s.%2$s. - %8$s.%7$s.</string>
+    <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.</string>
+    <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+    <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+    <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s.%2$s.%4$s, %5$s - %6$s, %8$s.%7$s.%9$s, %10$s</string>
+    <string name="numeric_md1_time1_md2_time2">%3$s.%2$s., %5$s - %8$s.%7$s., %10$s</string>
+    <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %3$s.%2$s., %5$s - %6$s, %8$s.%7$s., %10$s</string>
+    <string name="numeric_mdy1_time1_mdy2_time2">%3$s.%2$s.%4$s, %5$s - %8$s.%7$s.%9$s, %10$s</string>
+    <string name="wday1_date1_time1_wday2_date2_time2">%1$s, %2$s, %3$s - %4$s, %5$s, %6$s</string>
+    <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+    <string name="date1_time1_date2_time2">%2$s, %3$s - %5$s, %6$s</string>
     <string name="time_wday_date">%2$s, %3$s, %1$s</string>
     <string name="wday_date">%2$s, %3$s</string>
     <string name="time_wday">%2$s, %1$s</string>
-    <string name="same_year_md1_md2">%3$s. %2$s bis %8$s. %7$s</string>
-    <string name="same_year_wday1_md1_wday2_md2">%1$s, %3$s. %2$s bis %6$s, %8$s. %7$s</string>
-    <string name="same_year_md1_time1_md2_time2">%3$s. %2$s, %5$s bis %8$s. %7$s, %10$s</string>
-    <string name="same_month_md1_time1_md2_time2">%3$s. %2$s, %5$s bis %8$s. %7$s, %10$s</string>
-    <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s, %3$s. %2$s, %5$s bis %6$s, %8$s. %7$s, %10$s</string>
-    <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s, %3$s. %2$s, %5$s bis %6$s, %8$s. %7$s, %10$s</string>
-    <string name="same_year_mdy1_time1_mdy2_time2">%3$s. %2$s %4$s, %5$s bis %8$s. %7$s %9$s, %10$s</string>
-    <string name="same_month_mdy1_time1_mdy2_time2">%3$s. %2$s %4$s, %5$s bis %8$s. %7$s %9$s, %10$s</string>
-    <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s. %2$s %4$s, %5$s bis %6$s, %8$s. %7$s %9$s, %10$s</string>
-    <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s. %2$s %4$s, %5$s bis %6$s, %8$s. %7$s %9$s, %10$s</string>
-    <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s %4$s bis %6$s, %8$s. %7$s %9$s</string>
-    <string name="same_month_md1_md2">%3$s. bis %8$s. %2$s</string>
-    <string name="same_month_wday1_md1_wday2_md2">%1$s, %3$s. %2$s bis %6$s, %8$s. %7$s</string>
-    <string name="same_year_mdy1_mdy2">%3$s. %2$s bis %8$s. %7$s %9$s</string>
-    <string name="same_month_mdy1_mdy2">%3$s. bis %8$s. %2$s %9$s</string>
-    <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s bis %6$s, %8$s. %7$s %9$s</string>
+    <string name="same_year_md1_md2">%3$s. %2$s - %8$s. %7$s</string>
+    <string name="same_year_wday1_md1_wday2_md2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s</string>
+    <string name="same_year_md1_time1_md2_time2">%3$s. %2$s, %5$s - %8$s. %7$s, %10$s</string>
+    <string name="same_month_md1_time1_md2_time2">%3$s. %2$s, %5$s - %8$s. %7$s, %10$s</string>
+    <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s, %3$s. %2$s, %5$s - %6$s, %8$s. %7$s, %10$s</string>
+    <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s, %3$s. %2$s, %5$s - %6$s, %8$s. %7$s, %10$s</string>
+    <string name="same_year_mdy1_time1_mdy2_time2">%3$s. %2$s %4$s, %5$s - %8$s. %7$s %9$s, %10$s</string>
+    <string name="same_month_mdy1_time1_mdy2_time2">%3$s. %2$s %4$s, %5$s - %8$s. %7$s %9$s, %10$s</string>
+    <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s. %2$s %4$s, %5$s - %6$s, %8$s. %7$s %9$s, %10$s</string>
+    <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s. %2$s %4$s, %5$s - %6$s, %8$s. %7$s %9$s, %10$s</string>
+    <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s %4$s - %6$s, %8$s. %7$s %9$s</string>
+    <string name="same_month_md1_md2">%3$s. - %8$s. %2$s</string>
+    <string name="same_month_wday1_md1_wday2_md2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s</string>
+    <string name="same_year_mdy1_mdy2">%3$s. %2$s - %8$s. %7$s %9$s</string>
+    <string name="same_month_mdy1_mdy2">%3$s. - %8$s. %2$s %9$s</string>
+    <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s</string>
     <string name="short_format_month">%b</string>
 </resources>
diff --git a/include/ui/EGLUtils.h b/include/ui/EGLUtils.h
index 48777b6..a5bff81 100644
--- a/include/ui/EGLUtils.h
+++ b/include/ui/EGLUtils.h
@@ -31,6 +31,8 @@
 {
 public:
 
+    static const char *strerror(EGLint err);
+
     static status_t selectConfigForPixelFormat(
             EGLDisplay dpy,
             EGLint const* attrs,
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 3276cdf..d019097 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -810,7 +810,7 @@
 
 AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output)
     :   ThreadBase(audioFlinger),
-        mMixBuffer(0), mSuspended(false), mBytesWritten(0), mOutput(output),
+        mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output),
         mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
 {
     readOutputParameters();
@@ -829,9 +829,6 @@
 AudioFlinger::PlaybackThread::~PlaybackThread()
 {
     delete [] mMixBuffer;
-    if (mType != DUPLICATING) {
-        mAudioFlinger->mAudioHardware->closeOutputStream(mOutput);
-    }
 }
 
 status_t AudioFlinger::PlaybackThread::dump(int fd, const Vector<String16>& args)
@@ -2855,7 +2852,6 @@
 
 AudioFlinger::RecordThread::~RecordThread()
 {
-    mAudioFlinger->mAudioHardware->closeInputStream(mInput);
     delete[] mRsmpInBuffer;
     if (mResampler != 0) {
         delete mResampler;
@@ -3326,7 +3322,9 @@
 
 status_t AudioFlinger::closeOutput(int output)
 {
-    PlaybackThread *thread;
+    // keep strong reference on the playback thread so that
+    // it is not destroyed while exit() is executed
+    sp <PlaybackThread> thread;
     {
         Mutex::Autolock _l(mLock);
         thread = checkPlaybackThread_l(output);
@@ -3340,7 +3338,7 @@
             for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
                 if (mPlaybackThreads.valueAt(i)->type() == PlaybackThread::DUPLICATING) {
                     DuplicatingThread *dupThread = (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
-                    dupThread->removeOutputTrack((MixerThread *)thread);
+                    dupThread->removeOutputTrack((MixerThread *)thread.get());
                 }
             }
         }
@@ -3348,6 +3346,9 @@
     }
     thread->exit();
 
+    if (thread->type() != PlaybackThread::DUPLICATING) {
+        mAudioHardware->closeOutputStream(thread->getOutput());
+    }
     return NO_ERROR;
 }
 
@@ -3449,7 +3450,9 @@
 
 status_t AudioFlinger::closeInput(int input)
 {
-    RecordThread *thread;
+    // keep strong reference on the record thread so that
+    // it is not destroyed while exit() is executed
+    sp <RecordThread> thread;
     {
         Mutex::Autolock _l(mLock);
         thread = checkRecordThread_l(input);
@@ -3462,6 +3465,8 @@
     }
     thread->exit();
 
+    mAudioHardware->closeInputStream(thread->getInput());
+
     return NO_ERROR;
 }
 
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index c9f3448..4ba5977 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -502,8 +502,8 @@
                     AudioStreamOut* getOutput() { return mOutput; }
 
         virtual     int         type() const { return mType; }
-                    void        suspend() { mSuspended = true; }
-                    void        restore() { mSuspended = false; }
+                    void        suspend() { mSuspended++; }
+                    void        restore() { if (mSuspended) mSuspended--; }
         virtual     String8     getParameters(const String8& keys);
         virtual     void        audioConfigChanged(int event, int param = 0);
 
@@ -520,7 +520,7 @@
     protected:
         int                             mType;
         int16_t*                        mMixBuffer;
-        bool                            mSuspended;
+        int                             mSuspended;
         int                             mBytesWritten;
         bool                            mMasterMute;
         SortedVector< wp<Track> >       mActiveTracks;
diff --git a/libs/rs/java/Fall/AndroidManifest.xml b/libs/rs/java/Fall/AndroidManifest.xml
index f4f96a1..f646d0d 100644
--- a/libs/rs/java/Fall/AndroidManifest.xml
+++ b/libs/rs/java/Fall/AndroidManifest.xml
@@ -5,6 +5,7 @@
     <application android:label="FallRS">
 
         <activity
+            android:screenOrientation="portrait"
             android:name="Fall"
             android:theme="@android:style/Theme.NoTitleBar">
 
diff --git a/libs/rs/java/Fall/res/drawable-hdpi/riverbed.jpg b/libs/rs/java/Fall/res/drawable-hdpi/riverbed.jpg
new file mode 100644
index 0000000..1698f28
--- /dev/null
+++ b/libs/rs/java/Fall/res/drawable-hdpi/riverbed.jpg
Binary files differ
diff --git a/libs/rs/java/Fall/res/raw/fall.c b/libs/rs/java/Fall/res/raw/fall.c
index 267b3ea..ba9dd25 100644
--- a/libs/rs/java/Fall/res/raw/fall.c
+++ b/libs/rs/java/Fall/res/raw/fall.c
@@ -27,6 +27,7 @@
 #define RSID_RIPPLE_INDEX 6
 #define RSID_DROP_X 7
 #define RSID_DROP_Y 8
+#define RSID_RUNNING 9
     
 #define RSID_TEXTURES 1
 
@@ -35,7 +36,7 @@
 #define RSID_REFRACTION_MAP 3
 
 #define REFRACTION 1.333f
-#define DAMP 4
+#define DAMP 3
 
 #define DROP_RADIUS 2
 // The higher, the smaller the ripple
@@ -113,6 +114,20 @@
     }
 }
 
+int refraction(int d, int wave) {
+    int* map = loadArrayI32(RSID_REFRACTION_MAP, 0);
+    int i = d;
+    if (i < 0) i = -i;
+    if (i > 512) i = 512;
+    int w = (wave + 0x10000) >> 8;
+    w &= ~(w >> 31);
+    int r = (map[i] * w) >> 3;
+    if (d < 0) {
+        return -r;
+    }
+    return r;
+}
+
 void generateRipples() {
     int rippleMapSize = loadI32(RSID_STATE, RSID_RIPPLE_MAP_SIZE);
     int width = loadI32(RSID_STATE, RSID_MESH_WIDTH);
@@ -135,6 +150,19 @@
             int dx = nextWave - wave;
             int dy = current[b] - wave;
 
+            int offsetx = refraction(dx, wave) >> 16;
+            int u = (width - w) + offsetx;
+            u &= ~(u >> 31);
+            if (u >= width) u = width - 1;
+
+            int offsety = refraction(dy, wave) >> 16;
+            int v = (height - h) + offsety;
+            v &= ~(v >> 31);
+            if (v >= height) v = height - 1;
+
+            vertices[(offset + w) * 8 + 3] = u / (float) width;
+            vertices[(offset + w) * 8 + 4] = v / (float) height;
+
             // Update Z coordinate of the vertex
             vertices[(offset + w) * 8 + 7] = (dy / 512.0f) / RIPPLE_HEIGHT;
             
@@ -187,13 +215,67 @@
             n3x /= len;
             n3y /= len;
             n3z /= len;
+            
+            // V2
+            v2x = vertices[(yOffset + width + x + 1) * 8 + 5];
+            v2y = vertices[(yOffset + width + x + 1) * 8 + 6];
+            v2z = vertices[(yOffset + width + x + 1) * 8 + 7];
 
-            vertices[(yOffset + x) * 8 + 0] = -n3x;
-            vertices[(yOffset + x) * 8 + 1] = -n3y;
+            // N1
+            n1x = v2x - v1x;
+            n1y = v2y - v1y;
+            n1z = v2z - v1z;
+
+            // N2
+            n2x = v3x - v1x;
+            n2y = v3y - v1y;
+            n2z = v3z - v1z;
+
+            // Avegare of previous normal and N1 x N2
+            n3x = n3x / 2.0f + (n1y * n2z - n1z * n2y) / 2.0f;
+            n3y = n3y / 2.0f + (n1z * n2x - n1x * n2z) / 2.0f;
+            n3z = n3z / 2.0f + (n1x * n2y - n1y * n2x) / 2.0f;
+
+            // Normalize
+            len = magf3(n3x, n3y, n3z);
+            n3x /= len;
+            n3y /= len;
+            n3z /= len;
+
+            vertices[(yOffset + x) * 8 + 0] = n3x;
+            vertices[(yOffset + x) * 8 + 1] = n3y;
             vertices[(yOffset + x) * 8 + 2] = -n3z;
+            
+            // reset Z
+            vertices[(yOffset + x) * 8 + 7] = 0.0f;
         }
     }
-}   
+}
+
+void drawNormals() {
+    int width = loadI32(RSID_STATE, RSID_MESH_WIDTH);
+    int height = loadI32(RSID_STATE, RSID_MESH_HEIGHT);
+
+    float *vertices = loadTriangleMeshVerticesF(NAMED_mesh);
+    
+    bindProgramVertex(NAMED_PVLines);
+    color(1.0f, 0.0f, 0.0f, 1.0f);
+
+    int y = 0;
+    for ( ; y < height; y++) {
+        int yOffset = y * width;
+        int x = 0;
+        for ( ; x < width; x++) {
+            float vx = vertices[(yOffset + x) * 8 + 5];
+            float vy = vertices[(yOffset + x) * 8 + 6];
+            float vz = vertices[(yOffset + x) * 8 + 7];
+            float nx = vertices[(yOffset + x) * 8 + 0];
+            float ny = vertices[(yOffset + x) * 8 + 1];
+            float nz = vertices[(yOffset + x) * 8 + 2];
+            drawLine(vx, vy, vz, vx + nx / 10.0f, vy + ny / 10.0f, vz + nz / 10.0f);
+        }
+    }
+}
 
 int main(int index) {
     int dropX = loadI32(RSID_STATE, RSID_DROP_X);
@@ -204,13 +286,33 @@
         storeI32(RSID_STATE, RSID_DROP_Y, -1);
     }
 
-    updateRipples();
-    generateRipples();
-    updateTriangleMesh(NAMED_mesh);
+    int isRunning = loadI32(RSID_STATE, RSID_RUNNING);
+    if (isRunning) {
+        updateRipples();
+        generateRipples();
+        updateTriangleMesh(NAMED_mesh);
+    }
 
-    ambient(0.0f, 0.1f, 0.9f, 1.0f);
-    diffuse(0.0f, 0.1f, 0.9f, 1.0f);
-    drawTriangleMesh(NAMED_mesh);    
+    bindTexture(NAMED_PFBackground, 0, NAMED_TRiverbed);
+    drawTriangleMesh(NAMED_mesh);
+    
+    ambient(0.0f, 0.0f, 0.0f, 1.0f);
+    diffuse(0.0f, 0.0f, 0.0f, 1.0f);
+    specular(0.44f, 0.44f, 0.44f, 1.0f);
+    shininess(40.0f);
+    bindProgramFragment(NAMED_PFLighting);
+    drawTriangleMesh(NAMED_mesh);
+
+//    bindProgramVertex(NAMED_PVSky);
+//    bindProgramFragment(NAMED_PFSky);
+//    bindProgramFragmentStore(NAMED_PFSSky);
+//    color(1.0f, 1.0f, 1.0f, 0.30f);
+//    bindTexture(NAMED_PFSky, 0, NAMED_TSky);
+//    drawTriangleMesh(NAMED_mesh);
+
+    if (!isRunning) {
+        drawNormals();
+    }
 
     return 1;
 }
diff --git a/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java b/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
index 542f67c..1685a62 100644
--- a/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
+++ b/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
@@ -33,8 +33,6 @@
 import static android.renderscript.ProgramStore.BlendSrcFunc;
 import static android.renderscript.ProgramFragment.EnvMode.*;
 import static android.renderscript.Element.*;
-import android.graphics.BitmapFactory;
-import android.graphics.Bitmap;
 
 import java.util.TimeZone;
 
@@ -51,17 +49,20 @@
     private static final int RSID_STATE_RIPPLE_INDEX = 6;
     private static final int RSID_STATE_DROP_X = 7;
     private static final int RSID_STATE_DROP_Y = 8;
+    private static final int RSID_STATE_RUNNING = 9;
     
     private static final int RSID_TEXTURES = 1;
-    private static final int TEXTURES_COUNT = 0;
+    private static final int TEXTURES_COUNT = 1;
+    private static final int RSID_TEXTURE_RIVERBED = 0;
 
     private static final int RSID_RIPPLE_MAP = 2;
 
     private static final int RSID_REFRACTION_MAP = 3;
 
+    private boolean mIsRunning = true;    
+    
     private Resources mResources;
     private RenderScript mRS;
-    private final BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
 
     private final int mWidth;
     private final int mHeight;
@@ -69,8 +70,10 @@
     private ScriptC mScript;
     private Sampler mSampler;
     private ProgramFragment mPfBackground;
+    private ProgramFragment mPfLighting;
     private ProgramStore mPfsBackground;
     private ProgramVertex mPvBackground;
+    private ProgramVertex mPvLines;
     private ProgramVertex.MatrixAllocation mPvOrthoAlloc;
     private Light mLight;
 
@@ -89,8 +92,6 @@
     public FallRS(int width, int height) {
         mWidth = width;
         mHeight = height;
-        mBitmapOptions.inScaled = false;
-        mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
     }
 
     public void init(RenderScript rs, Resources res) {
@@ -116,6 +117,8 @@
         mLight.destroy();
         mRippleMap.destroy();
         mRefractionMap.destroy();
+        mPvLines.destroy();
+        mPfLighting.destroy();
     }
 
     @Override
@@ -177,10 +180,11 @@
         
         for (int y = 0; y <= hResolution; y++) {
             final float yOffset = y * quadHeight - glHeight / 2.0f - quadHeight;
+            final float t = 1.0f - y / (float) hResolution;
             for (int x = 0; x <= wResolution; x++) {
                 rs.triangleMeshAddVertex_XYZ_ST_NORM(
                         -1.0f + x * quadWidth - quadWidth, yOffset, 0.0f,
-                        x / (float) wResolution, y / (float) wResolution,
+                        x / (float) wResolution, t,
                         0.0f, 0.0f, -1.0f);
             }
         }
@@ -204,7 +208,7 @@
     private void createScriptStructures() {
         final int rippleMapSize = (mMeshWidth + 2) * (mMeshHeight + 2);
 
-        final int[] data = new int[9];
+        final int[] data = new int[10];
         mState = Allocation.createSized(mRS, USER_I32, data.length);
         data[RSID_STATE_FRAMECOUNT] = 0;
         data[RSID_STATE_WIDTH] = mWidth;
@@ -215,6 +219,7 @@
         data[RSID_STATE_RIPPLE_INDEX] = 0;
         data[RSID_STATE_DROP_X] = mMeshWidth / 2;
         data[RSID_STATE_DROP_Y] = mMeshHeight / 2;
+        data[RSID_STATE_RUNNING] = 1;
         mState.data(data);
 
         final int[] rippleMap = new int[rippleMapSize * 2];
@@ -236,7 +241,7 @@
         mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, TEXTURES_COUNT);
 
         final Allocation[] textures = mTextures;
-        // TOOD: Load textures
+        textures[RSID_TEXTURE_RIVERBED] = loadTexture(R.drawable.riverbed, "TRiverbed");
 
         final int[] bufferIds = mTextureBufferIDs;
         final int count = textures.length;
@@ -257,15 +262,6 @@
         return allocation;
     }
 
-    private Allocation loadTextureARGB(int id, String name) {
-        // Forces ARGB 32 bits, because pngcrush sometimes optimize our PNGs to
-        // indexed pictures, which are not well supported
-        final Bitmap b = BitmapFactory.decodeResource(mResources, id, mBitmapOptions);
-        final Allocation allocation = Allocation.createFromBitmap(mRS, b, RGBA_8888, false);
-        allocation.setName(name);
-        return allocation;
-    }
-
     private void createProgramFragment() {
         Sampler.Builder sampleBuilder = new Sampler.Builder(mRS);
         sampleBuilder.setMin(LINEAR);
@@ -280,12 +276,18 @@
         mPfBackground = builder.create();
         mPfBackground.setName("PFBackground");
         mPfBackground.bindSampler(mSampler, 0);
+        
+        builder = new ProgramFragment.Builder(mRS, null, null);
+        builder.setTexEnable(false, 0);
+        mPfLighting = builder.create();
+        mPfLighting.setName("PFLighting");
+        mPfLighting.bindSampler(mSampler, 0);
     }
 
     private void createProgramFragmentStore() {
         ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null);
-        builder.setDepthFunc(LESS);
-        builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+        builder.setDepthFunc(ALWAYS);
+        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
         builder.setDitherEnable(true);
         builder.setDepthMask(true);
         mPfsBackground = builder.create();
@@ -297,7 +299,7 @@
         mPvOrthoAlloc.setupProjectionNormalized(mWidth, mHeight);
 
         mLight = new Light.Builder(mRS).create();
-        mLight.setPosition(0.0f, 0.0f, -1.0f);
+        mLight.setPosition(0.0f, 2.0f, -8.0f);
 
         ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS, null, null);
         builder.setTextureMatrixEnable(true);
@@ -305,11 +307,21 @@
         mPvBackground = builder.create();
         mPvBackground.bindAllocation(mPvOrthoAlloc);
         mPvBackground.setName("PVBackground");
+        
+        builder = new ProgramVertex.Builder(mRS, null, null);
+        mPvLines = builder.create();
+        mPvLines.bindAllocation(mPvOrthoAlloc);
+        mPvLines.setName("PVLines");
     }
 
-    public void addDrop(float x, float y) {
+    void addDrop(float x, float y) {
         mState.subData1D(RSID_STATE_DROP_X, 2, new int[] {
                 (int) ((x / mWidth) * mMeshWidth), (int) ((y / mHeight) * mMeshHeight)
         });
     }
+    
+    void togglePause() {
+        mIsRunning = !mIsRunning;
+        mState.subData1D(RSID_STATE_RUNNING, 1, new int[] { mIsRunning ? 1 : 0 });
+    }
 }
diff --git a/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java b/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java
index bb793c8..d7573be 100644
--- a/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java
+++ b/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.view.SurfaceHolder;
 import android.view.MotionEvent;
+import android.view.KeyEvent;
 import android.renderscript.RenderScript;
 import android.renderscript.RSSurfaceView;
 
@@ -28,6 +29,8 @@
 
     public FallView(Context context) {
         super(context);
+        setFocusable(true);
+        setFocusableInTouchMode(true);
     }
 
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
@@ -44,6 +47,15 @@
     }
 
     @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER ||
+                keyCode == KeyEvent.KEYCODE_MENU) {
+            mRender.togglePause();
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
     public boolean onTouchEvent(MotionEvent event) {
         switch (event.getAction()) {
             case MotionEvent.ACTION_DOWN:
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index b17121f..813af5d 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -544,6 +544,24 @@
     glDrawArrays(GL_TRIANGLES, 0, count * 3);
 }
 
+static void SC_drawLine(float x1, float y1, float z1,
+                        float x2, float y2, float z2)
+{
+    GET_TLS();
+    rsc->setupCheck();
+
+    float vtx[] = { x1, y1, z1, x2, y2, z2 };
+
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glVertexPointer(3, GL_FLOAT, 0, vtx);
+
+    glDisableClientState(GL_NORMAL_ARRAY);
+    glDisableClientState(GL_COLOR_ARRAY);
+
+    glDrawArrays(GL_LINES, 0, 2);
+}
+
 static void SC_drawQuad(float x1, float y1, float z1,
                         float x2, float y2, float z2,
                         float x3, float y3, float z3,
@@ -627,10 +645,9 @@
     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, params);
 }
 
-static void SC_shininess(float r, float g, float b, float a)
+static void SC_shininess(float s)
 {
-    GLfloat params[] = { r, g, b, a };
-    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, params);
+    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, s);
 }
 
 static void SC_hsb(float h, float s, float b, float a)
@@ -686,25 +703,6 @@
     glColor4f(red, green, blue, a);
 }
 
-/*
-extern "C" void materialDiffuse(float r, float g, float b, float a)
-{
-    float v[] = {r, g, b, a};
-    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, v);
-}
-
-extern "C" void materialSpecular(float r, float g, float b, float a)
-{
-    float v[] = {r, g, b, a};
-    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, v);
-}
-
-extern "C" void materialShininess(float s)
-{
-    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &s);
-}
-*/
-
 static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
 {
     GET_TLS();
@@ -903,6 +901,8 @@
         "void", "(int mesh)" },
     { "drawTriangleMeshRange", (void *)&SC_drawTriangleMeshRange,
         "void", "(int mesh, int start, int count)" },
+    { "drawLine", (void *)&SC_drawLine,
+        "void", "(float x1, float y1, float z1, float x2, float y2, float z2)" },
 
 
     // misc
@@ -921,7 +921,7 @@
     { "emission", (void *)&SC_emission,
         "void", "(float, float, float, float)" },
     { "shininess", (void *)&SC_shininess,
-        "void", "(float, float, float, float)" },
+        "void", "(float)" },
 
     { "uploadToTexture", (void *)&SC_uploadToTexture,
         "void", "(int, int)" },
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 002a3ab..a479b4c 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -42,28 +42,6 @@
 
 using namespace android;
 
-static __attribute__((noinline))
-const char *egl_strerror(EGLint err)
-{
-    switch (err){
-        case EGL_SUCCESS:           return "EGL_SUCCESS";
-        case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
-        case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
-        case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
-        case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
-        case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
-        case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
-        case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
-        case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
-        case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
-        case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
-        case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
-        case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
-        case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
-        case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
-        default: return "UNKNOWN";
-    }
-}
 
 static __attribute__((noinline))
 void checkGLErrors()
@@ -80,7 +58,7 @@
     // GLESonGL seems to be returning 0 when there is no errors?
     if (error && error != EGL_SUCCESS)
         LOGE("%s error 0x%04x (%s)",
-                token, int(error), egl_strerror(error));
+                token, int(error), EGLUtils::strerror(error));
 }
 
 
@@ -112,28 +90,22 @@
 
 void DisplayHardware::init(uint32_t dpy)
 {
-    hw_module_t const* module;
-
     mNativeWindow = new FramebufferNativeWindow();
+    framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
 
     mOverlayEngine = NULL;
+    hw_module_t const* module;
     if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
         overlay_control_open(module, &mOverlayEngine);
     }
 
-    framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
-
-    PixelFormatInfo fbFormatInfo;
-    getPixelFormatInfo(PixelFormat(fbDev->format), &fbFormatInfo);
-
     // initialize EGL
     const EGLint attribs[] = {
-            EGL_BUFFER_SIZE,    fbFormatInfo.bitsPerPixel,
-            EGL_DEPTH_SIZE,     0,
+            EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
             EGL_NONE
     };
     EGLint w, h, dummy;
-    EGLint numConfigs=0, n=0;
+    EGLint numConfigs=0;
     EGLSurface surface;
     EGLContext context;
     mFlags = 0;
@@ -146,10 +118,16 @@
     eglGetConfigs(display, NULL, 0, &numConfigs);
 
     EGLConfig config;
-    status_t err = EGLUtils::selectConfigForPixelFormat(
-            display, attribs, fbDev->format, &config);
+    status_t err = EGLUtils::selectConfigForNativeWindow(
+            display, attribs, mNativeWindow.get(), &config);
     LOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
     
+    EGLint r,g,b,a;
+    eglGetConfigAttrib(display, config, EGL_RED_SIZE,   &r);
+    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);
+    eglGetConfigAttrib(display, config, EGL_BLUE_SIZE,  &b);
+    eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);
+
     /*
      * Gather EGL extensions
      */
@@ -163,7 +141,8 @@
     LOGI("version   : %s", eglQueryString(display, EGL_VERSION));
     LOGI("extensions: %s", egl_extensions);
     LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
-
+    LOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config);
+    
 
     if (mNativeWindow->isUpdateOnDemand()) {
         mFlags |= UPDATE_ON_DEMAND;
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 9916158..d1142cc 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -115,16 +115,6 @@
     if (flags & ISurfaceComposer::eSecure)
         bufferFlags |= Buffer::SECURE;
 
-    /* FIXME we need this code for msm7201A
-    if (bufferFlags & Buffer::GPU) {
-        // FIXME: this is msm7201A specific, as its GPU only supports
-        // BGRA_8888.
-        if (format == PIXEL_FORMAT_RGBA_8888) {
-            format = PIXEL_FORMAT_BGRA_8888;
-        }
-    }
-    */
-
     mSecure = (bufferFlags & Buffer::SECURE) ? true : false;
     mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
     for (int i=0 ; i<2 ; i++) {
diff --git a/libs/ui/EGLUtils.cpp b/libs/ui/EGLUtils.cpp
index 80bfdfd..1663313 100644
--- a/libs/ui/EGLUtils.cpp
+++ b/libs/ui/EGLUtils.cpp
@@ -17,6 +17,7 @@
 
 #define LOG_TAG "EGLUtils"
 
+#include <cutils/log.h>
 #include <utils/Errors.h>
 
 #include <ui/EGLUtils.h>
@@ -29,6 +30,28 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
+const char *EGLUtils::strerror(EGLint err)
+{
+    switch (err){
+        case EGL_SUCCESS:           return "EGL_SUCCESS";
+        case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
+        case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
+        case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
+        case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
+        case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
+        case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
+        case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
+        case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
+        case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
+        case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
+        case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
+        case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
+        case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
+        case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
+        default: return "UNKNOWN";
+    }
+}
+
 status_t EGLUtils::selectConfigForPixelFormat(
         EGLDisplay dpy,
         EGLint const* attrs,
@@ -37,6 +60,9 @@
 {
     EGLint numConfigs = -1, n=0;
 
+    if (!attrs)
+        return BAD_VALUE;
+
     if (outConfig == NULL)
         return BAD_VALUE;
     
@@ -65,12 +91,13 @@
     EGLConfig config = NULL;
     for (i=0 ; i<n ; i++) {
         EGLint r,g,b,a;
-        eglGetConfigAttrib(dpy, configs[i], EGL_RED_SIZE,   &r);
-        eglGetConfigAttrib(dpy, configs[i], EGL_GREEN_SIZE, &g);
-        eglGetConfigAttrib(dpy, configs[i], EGL_BLUE_SIZE,  &b);
-        eglGetConfigAttrib(dpy, configs[i], EGL_ALPHA_SIZE, &a);
+        EGLConfig curr = configs[i];
+        eglGetConfigAttrib(dpy, curr, EGL_RED_SIZE,   &r);
+        eglGetConfigAttrib(dpy, curr, EGL_GREEN_SIZE, &g);
+        eglGetConfigAttrib(dpy, curr, EGL_BLUE_SIZE,  &b);
+        eglGetConfigAttrib(dpy, curr, EGL_ALPHA_SIZE, &a);
         if (fbSzA == a && fbSzR == r && fbSzG == g && fbSzB  == b) {
-            config = configs[i];
+            config = curr;
             break;
         }
     }
@@ -93,6 +120,10 @@
 {
     int err;
     int format;
+    
+    if (!window)
+        return BAD_VALUE;
+    
     if ((err = window->query(window, NATIVE_WINDOW_FORMAT, &format)) < 0) {
         return err;
     }
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 7b85c7f..f6c666d 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -25,6 +25,7 @@
 #include <cutils/log.h>
 #include <cutils/atomic.h>
 #include <utils/threads.h>
+#include <utils/RefBase.h>
 
 #include <ui/SurfaceComposerClient.h>
 #include <ui/Rect.h>
@@ -81,10 +82,16 @@
     hw_module_t const* module;
     if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
         int stride;
-        framebuffer_open(module, &fbDev);
-        gralloc_open(module, &grDev);
         int err;
+        err = framebuffer_open(module, &fbDev);
+        LOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));
+        
+        err = gralloc_open(module, &grDev);
+        LOGE_IF(err, "couldn't open gralloc HAL (%s)", strerror(-err));
 
+        // bail out if we can't initialize the modules
+        if (!fbDev || !grDev)
+            return;
         
         mUpdateOnDemand = (fbDev->setUpdateRect != 0);
         
@@ -127,11 +134,19 @@
     android_native_window_t::query = query;
 }
 
-FramebufferNativeWindow::~FramebufferNativeWindow() {
-    grDev->free(grDev, buffers[0]->handle);
-    grDev->free(grDev, buffers[1]->handle);
-    gralloc_close(grDev);
-    framebuffer_close(fbDev);
+FramebufferNativeWindow::~FramebufferNativeWindow() 
+{
+    if (grDev) {
+        if (buffers[0] != NULL)
+            grDev->free(grDev, buffers[0]->handle);
+        if (buffers[1] != NULL)
+            grDev->free(grDev, buffers[1]->handle);
+        gralloc_close(grDev);
+    }
+
+    if (fbDev) {
+        framebuffer_close(fbDev);
+    }
 }
 
 status_t FramebufferNativeWindow::setUpdateRectangle(const Rect& r) 
@@ -216,6 +231,7 @@
             *value = fb->format;
             return NO_ERROR;
     }
+    *value = 0;
     return BAD_VALUE;
 }
 
@@ -223,9 +239,16 @@
 }; // namespace android
 // ----------------------------------------------------------------------------
 
+using namespace android;
 
 EGLNativeWindowType android_createDisplaySurface(void)
 {
-    return new android::FramebufferNativeWindow();
+    FramebufferNativeWindow* w;
+    w = new FramebufferNativeWindow();
+    if (w->getDevice() == NULL) {
+        // get a ref so it can be destroyed when we exit this block
+        sp<FramebufferNativeWindow> ref(w);
+        return NULL;
+    }
+    return (EGLNativeWindowType)w;
 }
-
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 1f9e3af..9afe6a1 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -25,6 +25,8 @@
 import android.content.BroadcastReceiver;
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothClass;
 
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
@@ -219,6 +221,8 @@
     // Forced device usage for communications
     private int mForcedUseForComm;
 
+    private BluetoothDevice mBluetoothDevice = null;
+
     ///////////////////////////////////////////////////////////////////////////
     // Construction
     ///////////////////////////////////////////////////////////////////////////
@@ -243,7 +247,7 @@
         IntentFilter intentFilter =
                 new IntentFilter(Intent.ACTION_HEADSET_PLUG);
         intentFilter.addAction(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
-        intentFilter.addAction(BluetoothIntent.HEADSET_AUDIO_STATE_CHANGED_ACTION);
+        intentFilter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION);
         context.registerReceiver(mReceiver, intentFilter);
     }
 
@@ -756,9 +760,11 @@
     public void setBluetoothScoOn(boolean on){
         if (on) {
             AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_BT_SCO);
+            AudioSystem.setForceUse(AudioSystem.FOR_RECORD, AudioSystem.FORCE_BT_SCO);
             mForcedUseForComm = AudioSystem.FORCE_BT_SCO;
         } else {
             AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_NONE);
+            AudioSystem.setForceUse(AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE);
             mForcedUseForComm = AudioSystem.FORCE_NONE;
         }
     }
@@ -1257,8 +1263,9 @@
                     // Restore call state
                     AudioSystem.setPhoneState(mMode);
 
-                    // Restore forced usage for communcations
+                    // Restore forced usage for communcations and record
                     AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm);
+                    AudioSystem.setForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm);
 
                     // Restore stream volumes
                     int numStreamTypes = AudioSystem.getNumStreamTypes();
@@ -1343,31 +1350,61 @@
                 int state = intent.getIntExtra(BluetoothA2dp.SINK_STATE,
                                                BluetoothA2dp.STATE_DISCONNECTED);
                 String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
-                if (state == BluetoothA2dp.STATE_DISCONNECTED) {
+
+                boolean isConnected = (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) &&
+                                       ((String)mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)).equals(address));
+
+                if (isConnected &&
+                    state != BluetoothA2dp.STATE_CONNECTED && state != BluetoothA2dp.STATE_PLAYING) {
                     AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                             AudioSystem.DEVICE_STATE_UNAVAILABLE,
                             address);
                     mConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
-                } else if (state == BluetoothA2dp.STATE_CONNECTED){
+                } else if (!isConnected &&
+                           (state == BluetoothA2dp.STATE_CONNECTED || state != BluetoothA2dp.STATE_PLAYING)){
                     AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                                                          AudioSystem.DEVICE_STATE_AVAILABLE,
                                                          address);
                     mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP), address);
                 }
-            } else if (action.equals(BluetoothIntent.HEADSET_AUDIO_STATE_CHANGED_ACTION)) {
-                int state = intent.getIntExtra(BluetoothIntent.HEADSET_AUDIO_STATE,
+            } else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) {
+                int state = intent.getIntExtra(BluetoothIntent.HEADSET_STATE,
                                                BluetoothHeadset.STATE_ERROR);
                 String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
-                if (state == BluetoothHeadset.AUDIO_STATE_DISCONNECTED) {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO,
+                int device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
+                if (mBluetoothDevice == null) {
+                    mBluetoothDevice = (BluetoothDevice)mContext.getSystemService(Context.BLUETOOTH_SERVICE);
+                }
+                if (mBluetoothDevice != null) {
+                    int btClass = mBluetoothDevice.getRemoteClass(address);
+                    if (BluetoothClass.Device.Major.getDeviceMajor(btClass) == BluetoothClass.Device.Major.AUDIO_VIDEO) {
+                        switch (BluetoothClass.Device.getDevice(btClass)) {
+                        case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
+                        case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
+                            device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+                            break;
+                        case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
+                            device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+                            break;
+                        default:
+                            break;
+                        }
+                    }
+                }
+
+                boolean isConnected = (mConnectedDevices.containsKey(device) &&
+                                       ((String)mConnectedDevices.get(device)).equals(address));
+
+                if (isConnected && state != BluetoothHeadset.STATE_CONNECTED) {
+                    AudioSystem.setDeviceConnectionState(device,
                                                          AudioSystem.DEVICE_STATE_UNAVAILABLE,
                                                          address);
-                    mConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO);
-                } else if (state == BluetoothHeadset.AUDIO_STATE_CONNECTED) {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO,
+                    mConnectedDevices.remove(device);
+                } else if (!isConnected && state == BluetoothHeadset.STATE_CONNECTED) {
+                    AudioSystem.setDeviceConnectionState(device,
                                                          AudioSystem.DEVICE_STATE_AVAILABLE,
                                                          address);
-                    mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO), address);
+                    mConnectedDevices.put( new Integer(device), address);
                 }
             } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
                 int state = intent.getIntExtra("state", 0);
@@ -1440,6 +1477,4 @@
             }
         }
     }
-
-
 }
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index f74ef3a..84f858c 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -7,49 +7,41 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=               \
-    MediaRecorderClient.cpp \
-    MediaPlayerService.cpp \
+    MediaRecorderClient.cpp     \
+    MediaPlayerService.cpp      \
     MetadataRetrieverClient.cpp \
-    TestPlayerStub.cpp \
-    VorbisPlayer.cpp \
+    StagefrightPlayer.cpp       \
+    TestPlayerStub.cpp          \
+    VorbisPlayer.cpp            \
     MidiFile.cpp
 
 ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
 LOCAL_LDLIBS += -ldl -lpthread
 endif
 
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-	libbinder \
-    libvorbisidec \
-    libsonivox \
-    libopencore_player \
-    libopencore_author \
-    libmedia \
-    libandroid_runtime
+LOCAL_SHARED_LIBRARIES :=     \
+	libcutils             \
+	libutils              \
+	libbinder             \
+	libvorbisidec         \
+	libsonivox            \
+	libopencore_player    \
+	libopencore_author    \
+	libmedia              \
+	libandroid_runtime    \
+	libstagefright        \
+	libstagefright_omx
 
 ifneq ($(TARGET_SIMULATOR),true)
 LOCAL_SHARED_LIBRARIES += libdl
 endif
 
-LOCAL_C_INCLUDES := external/tremor/Tremor \
-	$(call include-path-for, graphics corecg) \
-	$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include
+LOCAL_C_INCLUDES := external/tremor/Tremor                              \
+	$(call include-path-for, graphics corecg)                       \
+	$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
+	$(TOP)/frameworks/base/media/libstagefright/omx
 
 LOCAL_MODULE:= libmediaplayerservice
 
-ifeq ($(BUILD_WITH_STAGEFRIGHT),true)
-    LOCAL_SRC_FILES += StagefrightPlayer.cpp
-
-    LOCAL_SHARED_LIBRARIES += \
-	libstagefright        \
-	libstagefright_omx
-
-    LOCAL_C_INCLUDES += $(TOP)/frameworks/base/media/libstagefright/omx
-
-    LOCAL_CFLAGS += -DBUILD_WITH_STAGEFRIGHT -DUSE_STAGEFRIGHT
-endif
-
 include $(BUILD_SHARED_LIBRARY)
 
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 95d61cd..eeb4e49 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -58,20 +58,9 @@
 #include "VorbisPlayer.h"
 #include <media/PVPlayer.h>
 #include "TestPlayerStub.h"
-
-//#undef USE_STAGEFRIGHT
-
-#if USE_STAGEFRIGHT
 #include "StagefrightPlayer.h"
-#endif
 
-#ifdef BUILD_WITH_STAGEFRIGHT
 #include <OMX.h>
-#else
-#include <media/IOMX.h>
-#endif
-
-
 
 /* desktop Linux needs a little help with gettid() */
 #if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
@@ -199,10 +188,6 @@
     const player_type playertype;
 } extmap;
 extmap FILE_EXTS [] =  {
-#if USE_STAGEFRIGHT
-        {".mp4", STAGEFRIGHT_PLAYER},
-        {".3gp", STAGEFRIGHT_PLAYER},
-#endif
         {".mid", SONIVOX_PLAYER},
         {".midi", SONIVOX_PLAYER},
         {".smf", SONIVOX_PLAYER},
@@ -289,11 +274,7 @@
 }
 
 sp<IOMX> MediaPlayerService::createOMX() {
-#ifdef BUILD_WITH_STAGEFRIGHT
     return new OMX;
-#else
-    return NULL;
-#endif
 }
 
 status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const
@@ -620,6 +601,16 @@
     IPCThreadState::self()->flushCommands();
 }
 
+static player_type getDefaultPlayerType() {
+    char value[PROPERTY_VALUE_MAX];
+    if (property_get("media.stagefright.enable-player", value, NULL)
+        && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
+        return STAGEFRIGHT_PLAYER;
+    }
+
+    return PV_PLAYER;
+}
+
 static player_type getPlayerType(int fd, int64_t offset, int64_t length)
 {
     char buf[20];
@@ -650,12 +641,7 @@
         EAS_Shutdown(easdata);
     }
 
-#if USE_STAGEFRIGHT
-    return STAGEFRIGHT_PLAYER;
-#endif
-
-    // Fall through to PV
-    return PV_PLAYER;
+    return getDefaultPlayerType();
 }
 
 static player_type getPlayerType(const char* url)
@@ -676,12 +662,7 @@
         }
     }
 
-#if USE_STAGEFRIGHT
-    return STAGEFRIGHT_PLAYER;
-#endif
-
-    // Fall through to PV
-    return PV_PLAYER;
+    return getDefaultPlayerType();
 }
 
 static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
@@ -703,17 +684,10 @@
             LOGV(" create VorbisPlayer");
             p = new VorbisPlayer();
             break;
-#if USE_STAGEFRIGHT
         case STAGEFRIGHT_PLAYER:
             LOGV(" create StagefrightPlayer");
             p = new StagefrightPlayer;
             break;
-#else
-        case STAGEFRIGHT_PLAYER:
-            LOG_ALWAYS_FATAL(
-                    "Should not be here, stagefright player not enabled.");
-            break;
-#endif
         case TEST_PLAYER:
             LOGV("Create Test Player stub");
             p = new TestPlayerStub();
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 0a44762..00ba1ac 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -1,5 +1,3 @@
-ifeq ($(BUILD_WITH_STAGEFRIGHT),true)
-
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
@@ -54,4 +52,3 @@
 include $(BUILD_SHARED_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
-endif
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index 2e564e9..ecd3b2e 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -1,5 +1,3 @@
-ifeq ($(BUILD_WITH_STAGEFRIGHT),true)
-
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
@@ -27,5 +25,3 @@
 LOCAL_MODULE:= libstagefright_omx
 
 include $(BUILD_SHARED_LIBRARY)
-
-endif
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
index 3c5bcdf3..867459d 100644
--- a/opengl/libagl/copybit.cpp
+++ b/opengl/libagl/copybit.cpp
@@ -75,6 +75,8 @@
 static bool supportedCopybitsFormat(int format) {
     switch (format) {
     case COPYBIT_FORMAT_RGBA_8888:
+    case COPYBIT_FORMAT_RGBX_8888:
+    case COPYBIT_FORMAT_RGB_888:
     case COPYBIT_FORMAT_RGB_565:
     case COPYBIT_FORMAT_BGRA_8888:
     case COPYBIT_FORMAT_RGBA_5551:
diff --git a/opengl/tests/swapinterval/swapinterval.cpp b/opengl/tests/swapinterval/swapinterval.cpp
index cf908a0..80a6c21 100644
--- a/opengl/tests/swapinterval/swapinterval.cpp
+++ b/opengl/tests/swapinterval/swapinterval.cpp
@@ -1,21 +1,19 @@
 /*
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-#define LOG_TAG "fillrate"
+ **
+ ** Copyright 2006, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License"); 
+ ** you may not use this file except in compliance with the License. 
+ ** You may obtain a copy of the License at 
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0 
+ **
+ ** Unless required by applicable law or agreed to in writing, software 
+ ** distributed under the License is distributed on an "AS IS" BASIS, 
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ ** See the License for the specific language governing permissions and 
+ ** limitations under the License.
+ */
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -33,72 +31,90 @@
 int main(int argc, char** argv)
 {
     EGLint configAttribs[] = {
-         EGL_DEPTH_SIZE, 0,
-         EGL_NONE
-     };
-     
-     EGLint majorVersion;
-     EGLint minorVersion;
-     EGLContext context;
-     EGLConfig config;
-     EGLSurface surface;
-     EGLint w, h;
-     EGLDisplay dpy;
+            EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
+            EGL_NONE
+    };
 
-     dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-     eglInitialize(dpy, &majorVersion, &minorVersion);
-          
-     EGLNativeWindowType window = android_createDisplaySurface();
-     
-     status_t err = EGLUtils::selectConfigForNativeWindow(
-             dpy, configAttribs, window, &config);
-     if (err) {
-         fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n");
-         return 0;
-     }
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EGLContext context;
+    EGLConfig config;
+    EGLint numConfigs=0;
+    EGLSurface surface;
+    EGLint w, h;
+    EGLDisplay dpy;
 
-     surface = eglCreateWindowSurface(dpy, config, window, NULL);
-     context = eglCreateContext(dpy, config, NULL, NULL);
-     eglMakeCurrent(dpy, surface, surface, context);   
-     eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
-     eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
-     
-     printf("w=%d, h=%d\n", w, h);
-     
-     glDisable(GL_DITHER);
-     glEnable(GL_BLEND);
+    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(dpy, 0 ,0) ;//&majorVersion, &minorVersion);
+    eglGetConfigs(dpy, NULL, 0, &numConfigs);
+    printf("# configs = %d\n", numConfigs);
+    
+    EGLNativeWindowType window = android_createDisplaySurface();
 
-     glViewport(0, 0, w, h);
-     glOrthof(0, w, 0, h, 0, 1);
+    status_t err = EGLUtils::selectConfigForNativeWindow(
+            dpy, configAttribs, window, &config);
+    if (err) {
+        fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n");
+        return 0;
+    }
 
-     eglSwapInterval(dpy, 1);
+    EGLint r,g,b,a;
+    eglGetConfigAttrib(dpy, config, EGL_RED_SIZE,   &r);
+    eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g);
+    eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE,  &b);
+    eglGetConfigAttrib(dpy, config, EGL_ALPHA_SIZE, &a);
 
-     glClearColor(1,0,0,0);
-     glClear(GL_COLOR_BUFFER_BIT);
-     eglSwapBuffers(dpy, surface);
+    surface = eglCreateWindowSurface(dpy, config, window, NULL);
+    if (surface == EGL_NO_SURFACE) {
+        EGLint err = eglGetError();
+        fprintf(stderr, "%s, config=%p, format = %d-%d-%d-%d\n",
+                EGLUtils::strerror(err), config, r,g,b,a);
+        return 0;
+    } else {
+        printf("config=%p, format = %d-%d-%d-%d\n", config, r,g,b,a);
+    }
+
+    context = eglCreateContext(dpy, config, NULL, NULL);
+    eglMakeCurrent(dpy, surface, surface, context);   
+    eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+    eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+
+    printf("w=%d, h=%d\n", w, h);
+
+    glDisable(GL_DITHER);
+    glEnable(GL_BLEND);
+
+    glViewport(0, 0, w, h);
+    glOrthof(0, w, 0, h, 0, 1);
+
+    eglSwapInterval(dpy, 1);
+
+    glClearColor(1,0,0,0);
+    glClear(GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(dpy, surface);
 
 
-     int time = 10;
-     printf("screen should flash red/green quickly for %d s...\n", time);
-     
-     int c = 0;
-     nsecs_t start = systemTime();
-     nsecs_t t;
-     do {
-         glClearColor(1,0,0,0);
-         glClear(GL_COLOR_BUFFER_BIT);
-         eglSwapBuffers(dpy, surface);
-         glClearColor(0,1,0,0);
-         glClear(GL_COLOR_BUFFER_BIT);
-         eglSwapBuffers(dpy, surface);
-         t = systemTime() - start;
-         c += 2;
-     } while (int(ns2s(t))<=time);
-     
-     double p =  (double(t) / c) / 1000000000.0;
-     printf("refresh-rate is %f fps (%f ms)\n", 1.0f/p, p*1000.0);
-       
-     eglTerminate(dpy);
-     
-     return 0;
+    int time = 10;
+    printf("screen should flash red/green quickly for %d s...\n", time);
+
+    int c = 0;
+    nsecs_t start = systemTime();
+    nsecs_t t;
+    do {
+        glClearColor(1,0,0,0);
+        glClear(GL_COLOR_BUFFER_BIT);
+        eglSwapBuffers(dpy, surface);
+        glClearColor(0,1,0,0);
+        glClear(GL_COLOR_BUFFER_BIT);
+        eglSwapBuffers(dpy, surface);
+        t = systemTime() - start;
+        c += 2;
+    } while (int(ns2s(t))<=time);
+
+    double p =  (double(t) / c) / 1000000000.0;
+    printf("refresh-rate is %f fps (%f ms)\n", 1.0f/p, p*1000.0);
+
+    eglTerminate(dpy);
+
+    return 0;
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 2b36904..a5bd254 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -83,6 +83,11 @@
     };
 
     private static final String FILE_WIFI_SUPPLICANT = "/data/misc/wifi/wpa_supplicant.conf";
+
+    // the key to store the WIFI data under, should be sorted as last, so restore happens last.
+    // use very late unicode character to quasi-guarantee last sort position.
+    private static final String KEY_WIFI_SUPPLICANT = "\uffeeWIFI";
+
     private static final String FILE_BT_ROOT = "/data/misc/hcid/";
 
     private SettingsHelper mSettingsHelper;
@@ -113,7 +118,7 @@
         stateChecksums[STATE_LOCALE] =
                 writeIfChanged(stateChecksums[STATE_LOCALE], KEY_LOCALE, locale, data);
         stateChecksums[STATE_WIFI] =
-                writeIfChanged(stateChecksums[STATE_WIFI], FILE_WIFI_SUPPLICANT, wifiData, data);
+                writeIfChanged(stateChecksums[STATE_WIFI], KEY_WIFI_SUPPLICANT, wifiData, data);
 
         writeNewChecksums(stateChecksums, newState);
     }
@@ -122,7 +127,7 @@
     public void onRestore(BackupDataInput data, int appVersionCode,
             ParcelFileDescriptor newState) throws IOException {
 
-        enableWifi(false);
+
         enableBluetooth(false);
 
         while (data.readNextHeader()) {
@@ -133,12 +138,16 @@
                 mSettingsHelper.applyAudioSettings();
             } else if (KEY_SECURE.equals(key)) {
                 restoreSettings(data, Settings.Secure.CONTENT_URI);
-            } else if (FILE_WIFI_SUPPLICANT.equals(key)) {
+            } else if (KEY_WIFI_SUPPLICANT.equals(key)) {
+                int retainedWifiState = enableWifi(false);
                 restoreFile(FILE_WIFI_SUPPLICANT, data);
                 FileUtils.setPermissions(FILE_WIFI_SUPPLICANT,
                         FileUtils.S_IRUSR | FileUtils.S_IWUSR |
                         FileUtils.S_IRGRP | FileUtils.S_IWGRP,
                         Process.myUid(), Process.WIFI_UID);
+                // retain the previous WIFI state.
+                enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED ||
+                        retainedWifiState == WifiManager.WIFI_STATE_ENABLING);
             } else if (KEY_SYNC.equals(key)) {
                 mSettingsHelper.setSyncProviders(data);
             } else if (KEY_LOCALE.equals(key)) {
@@ -257,7 +266,7 @@
     }
 
     /**
-     * Given a cursor sorted by key name and a set of keys sorted by name, 
+     * Given a cursor sorted by key name and a set of keys sorted by name,
      * extract the required keys and values and write them to a byte array.
      * @param sortedCursor
      * @param sortedKeys
@@ -373,11 +382,14 @@
         return result;
     }
 
-    private void enableWifi(boolean enable) {
+    private int enableWifi(boolean enable) {
         WifiManager wfm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
         if (wfm != null) {
+            int state = wfm.getWifiState();
             wfm.setWifiEnabled(enable);
+            return state;
         }
+        return WifiManager.WIFI_STATE_UNKNOWN;
     }
 
     private void enableBluetooth(boolean enable) {
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index ed16a37..32ee61b 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -792,11 +792,15 @@
 
         synchronized(mClearDataLock) {
             mClearingData = true;
+            /* This is causing some critical processes to be killed during setup.
+               Temporarily revert this change until we find a better solution.
             try {
                 mActivityManager.clearApplicationUserData(packageName, observer);
             } catch (RemoteException e) {
                 // can't happen because the activity manager is in this process
             }
+            */
+            mPackageManager.clearApplicationUserData(packageName, observer);
 
             // only wait 10 seconds for the clear data to happen
             long timeoutMark = System.currentTimeMillis() + TIMEOUT_INTERVAL;
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 769226e..86ea12b 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -542,6 +542,20 @@
     void unregisterForCdmaOtaStatusChange(Handler h);
 
     /**
+     * Registration point for subscription info ready
+     * @param h handler to notify
+     * @param what what code of message when delivered
+     * @param obj placed in Message.obj
+     */
+    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj);
+
+    /**
+     * Unregister for notifications for subscription info
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForSubscriptionInfoReady(Handler h);
+
+    /**
      * Returns SIM record load state. Use
      * <code>getSimCard().registerForReady()</code> for change notification.
      *
@@ -1366,6 +1380,13 @@
     String getCdmaMin();
 
     /**
+     * Check if subscription data has been assigned to mMin
+     *
+     * return true if MIN info is ready; false otherwise.
+     */
+    boolean isMinInfoReady();
+
+    /**
      *  Retrieves PRL Version for CDMA phones
      */
     String getCdmaPrlVersion();
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index fbda221..6e2b3f3 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -698,6 +698,12 @@
         return null;
     }
 
+    public boolean isMinInfoReady() {
+        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+        Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+        return false;
+    }
+
     public String getCdmaPrlVersion(){
         //  This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
@@ -724,6 +730,16 @@
         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
     }
 
+    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
+        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+        Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+    }
+
+    public void unregisterForSubscriptionInfoReady(Handler h) {
+        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+        Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+    }
+
     public  boolean isOtaSpNumber(String dialStr) {
         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 30d56da..f2568c1 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -315,6 +315,14 @@
          mActivePhone.unregisterForCdmaOtaStatusChange(h);
     }
 
+    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
+        mActivePhone.registerForSubscriptionInfoReady(h, what, obj);
+    }
+
+    public void unregisterForSubscriptionInfoReady(Handler h) {
+        mActivePhone.unregisterForSubscriptionInfoReady(h);
+    }
+
     public boolean getIccRecordsLoaded() {
         return mActivePhone.getIccRecordsLoaded();
     }
@@ -419,6 +427,10 @@
         return mActivePhone.getCdmaMin();
     }
 
+    public boolean isMinInfoReady() {
+        return mActivePhone.isMinInfoReady();
+    }
+
     public String getCdmaPrlVersion() {
         return mActivePhone.getCdmaPrlVersion();
     }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 7b3ff5e..e0fbd81 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -441,6 +441,10 @@
         return mSST.getCdmaMin();
     }
 
+    public boolean isMinInfoReady() {
+        return mSST.isMinInfoReady();
+    }
+
     public void getCallWaiting(Message onComplete) {
         mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
     }
@@ -556,6 +560,14 @@
         mCM.unregisterForCdmaOtaProvision(h);
     }
 
+    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
+        mSST.registerForSubscriptionInfoReady(h, what, obj);
+    }
+
+    public void unregisterForSubscriptionInfoReady(Handler h) {
+        mSST.unregisterForSubscriptionInfoReady(h);
+    }
+
     public void setOnEcbModeExitResponse(Handler h, int what, Object obj) {
         mECMExitRespRegistrant = new Registrant (h, what, obj);
     }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 53f0274..753b5e7 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -93,6 +93,7 @@
     private int mRegistrationState = -1;
     private RegistrantList cdmaDataConnectionAttachedRegistrants = new RegistrantList();
     private RegistrantList cdmaDataConnectionDetachedRegistrants = new RegistrantList();
+    private RegistrantList cdmaForSubscriptionInfoReadyRegistrants = new RegistrantList();
 
     // Sometimes we get the NITZ time before we know what country we are in.
     // Keep the time zone information from the NITZ string so we can fix
@@ -125,6 +126,7 @@
     private int mHomeNetworkId[] = null;
     private String mMin;
     private String mPrlVersion;
+    private boolean mIsMinInfoReady = false;
 
     private boolean isEriTextLoaded = false;
     private boolean isSubscriptionFromRuim = false;
@@ -264,6 +266,25 @@
         cdmaDataConnectionDetachedRegistrants.remove(h);
     }
 
+    /**
+     * Registration point for subscription info ready
+     * @param h handler to notify
+     * @param what what code of message when delivered
+     * @param obj placed in Message.obj
+     */
+    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
+        Registrant r = new Registrant(h, what, obj);
+        cdmaForSubscriptionInfoReadyRegistrants.add(r);
+
+        if (isMinInfoReady()) {
+            r.notifyRegistrant();
+        }
+    }
+
+    public void unregisterForSubscriptionInfoReady(Handler h) {
+        cdmaForSubscriptionInfoReadyRegistrants.remove(h);
+    }
+
     //***** Called from CDMAPhone
     public void
     getLacAndCid(Message onComplete) {
@@ -426,6 +447,13 @@
                     mMin = cdmaSubscription[3];
                     mPrlVersion = cdmaSubscription[4];
                     Log.d(LOG_TAG,"GET_CDMA_SUBSCRIPTION MDN=" + mMdn);
+                    //Notify apps subscription info is ready
+                    if (cdmaForSubscriptionInfoReadyRegistrants != null) {
+                        cdmaForSubscriptionInfoReadyRegistrants.notifyRegistrants();
+                    }
+                    if (!mIsMinInfoReady) {
+                        mIsMinInfoReady = true;
+                    }
                 } else {
                     Log.w(LOG_TAG,"error parsing cdmaSubscription params num="
                             + cdmaSubscription.length);
@@ -1545,4 +1573,13 @@
             return null;
         }
     }
+
+    /**
+     * Check if subscription data has been assigned to mMin
+     *
+     * return true if MIN info is ready; false otherwise.
+     */
+    public boolean isMinInfoReady() {
+        return mIsMinInfoReady;
+    }
 }