Merge change 22661 into eclair

* changes:
  SettingsProvider: Fix botched merge from donut to eclair.
diff --git a/api/current.xml b/api/current.xml
index 2d7ee31..1406588 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -60507,6 +60507,21 @@
  visibility="public"
 >
 </method>
+<method name="setGammaForText"
+ return="void"
+ abstract="false"
+ native="true"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="blackGamma" type="float">
+</parameter>
+<parameter name="whiteGamma" type="float">
+</parameter>
+</method>
 <field name="BOLD"
  type="int"
  transient="false"
@@ -118649,6 +118664,19 @@
  synchronized="false"
  static="false"
  final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+<parameter name="instrumentation" type="android.app.Instrumentation">
+</parameter>
+</method>
+<method name="setInstrumentation"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
@@ -118898,6 +118926,19 @@
  synchronized="false"
  static="false"
  final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+<parameter name="instrumentation" type="android.app.Instrumentation">
+</parameter>
+</method>
+<method name="injectInstrumentation"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
@@ -264057,7 +264098,7 @@
 </parameter>
 <parameter name="buffer" type="java.lang.StringBuffer">
 </parameter>
-<parameter name="field" type="java.text.FieldPosition">
+<parameter name="fieldPos" type="java.text.FieldPosition">
 </parameter>
 </method>
 <method name="get2DigitYearStart"
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 140c814..5ed8941 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -23,6 +23,8 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.pm.RegisteredServicesCache;
+import android.content.pm.PackageInfo;
+import android.content.pm.ApplicationInfo;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
 import android.database.sqlite.SQLiteDatabase;
@@ -44,6 +46,7 @@
 import android.app.PendingIntent;
 import android.app.NotificationManager;
 import android.app.Notification;
+import android.app.Activity;
 import android.Manifest;
 
 import java.io.FileDescriptor;
@@ -118,8 +121,7 @@
 
     private static final String[] ACCOUNT_NAME_TYPE_PROJECTION =
             new String[]{ACCOUNTS_ID, ACCOUNTS_NAME, ACCOUNTS_TYPE};
-    private static final Intent ACCOUNTS_CHANGED_INTENT =
-            new Intent(Constants.LOGIN_ACCOUNTS_CHANGED_ACTION);
+    private static final Intent ACCOUNTS_CHANGED_INTENT;
 
     private static final String COUNT_OF_MATCHING_GRANTS = ""
             + "SELECT COUNT(*) FROM " + TABLE_GRANTS + ", " + TABLE_ACCOUNTS
@@ -143,6 +145,12 @@
     private static final boolean isDebuggableMonkeyBuild =
             SystemProperties.getBoolean("ro.monkey", false)
                     && SystemProperties.getBoolean("ro.debuggable", false);
+
+    static {
+        ACCOUNTS_CHANGED_INTENT = new Intent(Constants.LOGIN_ACCOUNTS_CHANGED_ACTION);
+        ACCOUNTS_CHANGED_INTENT.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+    }
+
     /**
      * This should only be called by system code. One should only call this after the service
      * has started.
@@ -1474,6 +1482,22 @@
         }
     }
 
+    private boolean inSystemImage(int callerUid) {
+        String[] packages = mContext.getPackageManager().getPackagesForUid(callerUid);
+        for (String name : packages) {
+            try {
+                PackageInfo packageInfo =
+                        mContext.getPackageManager().getPackageInfo(name, 0 /* flags */);
+                if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                    return true;
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                return false;
+            }
+        }
+        return false;
+    }
+
     private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) {
         final boolean fromAuthenticator = hasAuthenticatorUid(account.type, callerUid);
         final boolean hasExplicitGrants = hasExplicitlyGrantedPermission(account, authTokenType);
@@ -1483,7 +1507,7 @@
                     + ": is authenticator? " + fromAuthenticator
                     + ", has explicit permission? " + hasExplicitGrants);
         }
-        return fromAuthenticator || hasExplicitGrants;
+        return fromAuthenticator || hasExplicitGrants || inSystemImage(callerUid);
     }
 
     private boolean hasAuthenticatorUid(String accountType, int callingUid) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 496ab76..9dedca6 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1696,7 +1696,6 @@
     public static final String ACTION_REBOOT =
             "android.intent.action.REBOOT";
 
-
     /**
      * Broadcast Action: a remote intent is to be broadcasted.
      *
@@ -1711,6 +1710,18 @@
     public static final String ACTION_REMOTE_INTENT =
             "android.intent.action.REMOTE_INTENT";
 
+    /**
+     * Broadcast Action: hook for permforming cleanup after a system update.
+     *
+     * The broadcast is sent when the system is booting, before the
+     * BOOT_COMPLETED broadcast.  It is only sent to receivers in the system
+     * image.  A receiver for this should do its work and then disable itself
+     * so that it does not get run again at the next boot.
+     * @hide
+     */
+    public static final String ACTION_PRE_BOOT_COMPLETED =
+            "android.intent.action.PRE_BOOT_COMPLETED";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Standard intent categories (see addCategory()).
@@ -2251,6 +2262,13 @@
      * @hide
      */
     public static final int FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT = 0x20000000;
+    /**
+     * Set when this broadcast is for a boot upgrade, a special mode that
+     * allows the broadcast to be sent before the system is ready and launches
+     * the app process with no providers running in it.
+     * @hide
+     */
+    public static final int FLAG_RECEIVER_BOOT_UPGRADE = 0x10000000;
 
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java
index db25cfa..46cce52 100644
--- a/core/java/android/preference/VolumePreference.java
+++ b/core/java/android/preference/VolumePreference.java
@@ -16,15 +16,17 @@
 
 package android.preference;
 
+import android.app.Dialog;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.database.ContentObserver;
+import android.media.AudioManager;
 import android.media.Ringtone;
 import android.media.RingtoneManager;
-import android.media.AudioManager;
 import android.net.Uri;
 import android.os.Handler;
-import android.preference.PreferenceManager;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.provider.Settings;
 import android.provider.Settings.System;
 import android.util.AttributeSet;
@@ -42,7 +44,7 @@
     private static final String TAG = "VolumePreference";
     
     private int mStreamType;
-    
+
     /** May be null if the dialog isn't visible. */
     private SeekBarVolumizer mSeekBarVolumizer;
     
@@ -54,7 +56,7 @@
         mStreamType = a.getInt(android.R.styleable.VolumePreference_streamType, 0);
         a.recycle();        
     }
-    
+
     public void setStreamType(int streamType) {
         mStreamType = streamType;
     }
@@ -65,7 +67,7 @@
     
         final SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar);
         mSeekBarVolumizer = new SeekBarVolumizer(getContext(), seekBar, mStreamType);
-        
+
         getPreferenceManager().registerOnActivityStopListener(this);
 
         // grab focus and key events so that pressing the volume buttons in the
@@ -100,7 +102,7 @@
         if (!positiveResult && mSeekBarVolumizer != null) {
             mSeekBarVolumizer.revertVolume();
         }
-        
+
         cleanup();
     }
 
@@ -113,19 +115,96 @@
      */
     private void cleanup() {
        getPreferenceManager().unregisterOnActivityStopListener(this);
-       
+
        if (mSeekBarVolumizer != null) {
+           Dialog dialog = getDialog();
+           if (dialog != null && dialog.isShowing()) {
+               // Stopped while dialog was showing, revert changes
+               mSeekBarVolumizer.revertVolume();
+           }
            mSeekBarVolumizer.stop();
            mSeekBarVolumizer = null;
        }
+
     }
-   
+
     protected void onSampleStarting(SeekBarVolumizer volumizer) {
         if (mSeekBarVolumizer != null && volumizer != mSeekBarVolumizer) {
             mSeekBarVolumizer.stopSample();
         }
     }
-    
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        final Parcelable superState = super.onSaveInstanceState();
+        if (isPersistent()) {
+            // No need to save instance state since it's persistent
+            return superState;
+        }
+
+        final SavedState myState = new SavedState(superState);
+        if (mSeekBarVolumizer != null) {
+            mSeekBarVolumizer.onSaveInstanceState(myState.getVolumeStore());
+        }
+        return myState;
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        if (state == null || !state.getClass().equals(SavedState.class)) {
+            // Didn't save state for us in onSaveInstanceState
+            super.onRestoreInstanceState(state);
+            return;
+        }
+
+        SavedState myState = (SavedState) state;
+        super.onRestoreInstanceState(myState.getSuperState());
+        if (mSeekBarVolumizer != null) {
+            mSeekBarVolumizer.onRestoreInstanceState(myState.getVolumeStore());
+        }
+    }
+
+    public static class VolumeStore {
+        public int volume = -1;
+        public int originalVolume = -1;
+    }
+
+    private static class SavedState extends BaseSavedState {
+        VolumeStore mVolumeStore = new VolumeStore();
+
+        public SavedState(Parcel source) {
+            super(source);
+            mVolumeStore.volume = source.readInt();
+            mVolumeStore.originalVolume = source.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeInt(mVolumeStore.volume);
+            dest.writeInt(mVolumeStore.originalVolume);
+        }
+
+        VolumeStore getVolumeStore() {
+            return mVolumeStore;
+        }
+
+        public SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+
     /**
      * Turns a {@link SeekBar} into a volume control.
      */
@@ -139,7 +218,7 @@
         private int mOriginalStreamVolume; 
         private Ringtone mRingtone;
     
-        private int mLastProgress;
+        private int mLastProgress = -1;
         private SeekBar mSeekBar;
         
         private ContentObserver mVolumeObserver = new ContentObserver(mHandler) {
@@ -153,7 +232,7 @@
                 }
             }
         };
-    
+
         public SeekBarVolumizer(Context context, SeekBar seekBar, int streamType) {
             mContext = context;
             mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
@@ -207,7 +286,7 @@
             postSetVolume(progress);
         }
 
-        private void postSetVolume(int progress) {
+        void postSetVolume(int progress) {
             // Do the volume changing separately to give responsive UI
             mLastProgress = progress;
             mHandler.removeCallbacks(this);
@@ -249,5 +328,20 @@
             }
             postSetVolume(mSeekBar.getProgress());
         }
+
+        public void onSaveInstanceState(VolumeStore volumeStore) {
+            if (mLastProgress >= 0) {
+                volumeStore.volume = mLastProgress;
+                volumeStore.originalVolume = mOriginalStreamVolume;
+            }
+        }
+
+        public void onRestoreInstanceState(VolumeStore volumeStore) {
+            if (volumeStore.volume != -1) {
+                mOriginalStreamVolume = volumeStore.originalVolume;
+                mLastProgress = volumeStore.volume;
+                postSetVolume(mLastProgress);
+            }
+        }
     }
 }
diff --git a/core/java/android/test/InstrumentationTestCase.java b/core/java/android/test/InstrumentationTestCase.java
index 2145d7c..22d95d1 100644
--- a/core/java/android/test/InstrumentationTestCase.java
+++ b/core/java/android/test/InstrumentationTestCase.java
@@ -43,11 +43,25 @@
      * 
      * @param instrumentation the instrumentation to use with this instance
      */
-    public void injectInsrumentation(Instrumentation instrumentation) {
+    public void injectInstrumentation(Instrumentation instrumentation) {
         mInstrumentation = instrumentation;
     }
 
     /**
+     * Injects instrumentation into this test case. This method is
+     * called by the test runner during test setup.
+     *
+     * @param instrumentation the instrumentation to use with this instance
+     *
+     * @deprecated Incorrect spelling,
+     * use {@link #injectInstrumentation(android.app.Instrumentation) instead.
+     */
+    @Deprecated
+    public void injectInsrumentation(Instrumentation instrumentation) {
+        injectInstrumentation(instrumentation);
+    }
+
+    /**
      * Inheritors can access the instrumentation using this.
      * @return instrumentation
      */
diff --git a/core/java/android/test/InstrumentationTestSuite.java b/core/java/android/test/InstrumentationTestSuite.java
index 2ab949e..7a78ffb 100644
--- a/core/java/android/test/InstrumentationTestSuite.java
+++ b/core/java/android/test/InstrumentationTestSuite.java
@@ -65,7 +65,7 @@
     public void runTest(Test test, TestResult result) {
 
         if (test instanceof InstrumentationTestCase) {
-            ((InstrumentationTestCase) test).injectInsrumentation(mInstrumentation);
+            ((InstrumentationTestCase) test).injectInstrumentation(mInstrumentation);
         }
 
         // run the test as usual
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index 21dde63..238ece1 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -141,6 +141,25 @@
     return SkTypeface::CreateFromFile(str.c_str());
 }
 
+#define MIN_GAMMA   (0.1f)
+#define MAX_GAMMA   (10.0f)
+static float pinGamma(float gamma) {
+    if (gamma < MIN_GAMMA) {
+        gamma = MIN_GAMMA;
+    } else if (gamma > MAX_GAMMA) {
+        gamma = MAX_GAMMA;
+    }
+    return gamma;
+}
+
+extern void skia_set_text_gamma(float, float);
+
+static void Typeface_setGammaForText(JNIEnv* env, jobject, jfloat blackGamma,
+                                     jfloat whiteGamma) {
+    // Comment this out for release builds. This is only used during development
+    skia_set_text_gamma(pinGamma(blackGamma), pinGamma(whiteGamma));
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 static JNINativeMethod gTypefaceMethods[] = {
@@ -151,7 +170,8 @@
     { "nativeCreateFromAsset",    "(Landroid/content/res/AssetManager;Ljava/lang/String;)I",
                                            (void*)Typeface_createFromAsset },
     { "nativeCreateFromFile",     "(Ljava/lang/String;)I",
-                                           (void*)Typeface_createFromFile }
+                                           (void*)Typeface_createFromFile },
+    { "setGammaForText", "(FF)V", (void*)Typeface_setGammaForText },
 };
 
 int register_android_graphics_Typeface(JNIEnv* env);
diff --git a/core/jni/android_server_BluetoothA2dpService.cpp b/core/jni/android_server_BluetoothA2dpService.cpp
index 14da1fd..a185d8d 100644
--- a/core/jni/android_server_BluetoothA2dpService.cpp
+++ b/core/jni/android_server_BluetoothA2dpService.cpp
@@ -211,10 +211,6 @@
                             method_onSinkPropertyChanged,
                             env->NewStringUTF(c_path),
                             str_array);
-        for (int i = 0; i < env->GetArrayLength(str_array); i++) {
-            env->DeleteLocalRef(env->GetObjectArrayElement(str_array, i));
-        }
-        env->DeleteLocalRef(str_array);
         result = DBUS_HANDLER_RESULT_HANDLED;
         return result;
     } else {
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 527bf07..1bfabd7 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -57,6 +57,8 @@
 
 typedef event_loop_native_data_t native_data_t;
 
+#define EVENT_LOOP_REFS 10
+
 static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
     return (native_data_t *)(env->GetIntField(object,
                                                  field_mNativeData));
@@ -679,6 +681,7 @@
     native_data_t *nat;
     JNIEnv *env;
     DBusError err;
+    DBusHandlerResult ret;
 
     dbus_error_init(&err);
 
@@ -694,6 +697,7 @@
         dbus_message_get_interface(msg), dbus_message_get_member(msg),
         dbus_message_get_path(msg));
 
+    env->PushLocalFrame(EVENT_LOOP_REFS);
     if (dbus_message_is_signal(msg,
                                "org.bluez.Adapter",
                                "DeviceFound")) {
@@ -711,10 +715,9 @@
                                 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;
+        goto success;
     } else if (dbus_message_is_signal(msg,
                                      "org.bluez.Adapter",
                                      "DeviceDisappeared")) {
@@ -726,7 +729,7 @@
             env->CallVoidMethod(nat->me, method_onDeviceDisappeared,
                                 env->NewStringUTF(c_address));
         } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-        return DBUS_HANDLER_RESULT_HANDLED;
+        goto success;
     } else if (dbus_message_is_signal(msg,
                                      "org.bluez.Adapter",
                                      "DeviceCreated")) {
@@ -739,7 +742,7 @@
                                 method_onDeviceCreated,
                                 env->NewStringUTF(c_object_path));
         } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-        return DBUS_HANDLER_RESULT_HANDLED;
+        goto success;
     } else if (dbus_message_is_signal(msg,
                                      "org.bluez.Adapter",
                                      "DeviceRemoved")) {
@@ -752,8 +755,7 @@
                                method_onDeviceRemoved,
                                env->NewStringUTF(c_object_path));
         } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-
-        return DBUS_HANDLER_RESULT_HANDLED;
+        goto success;
     } else if (dbus_message_is_signal(msg,
                                       "org.bluez.Adapter",
                                       "PropertyChanged")) {
@@ -775,9 +777,8 @@
             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;
+        goto success;
     } else if (dbus_message_is_signal(msg,
                                       "org.bluez.Device",
                                       "PropertyChanged")) {
@@ -788,12 +789,17 @@
                             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;
-
+        goto success;
     }
-    return a2dp_event_filter(msg, env);
+
+    ret = a2dp_event_filter(msg, env);
+    env->PopLocalFrame(NULL);
+    return ret;
+
+success:
+    env->PopLocalFrame(NULL);
+    return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 // Called by dbus during WaitForAndDispatchEventNative()
@@ -811,6 +817,8 @@
     if (nat == NULL) return DBUS_HANDLER_RESULT_HANDLED;
 
     nat->vm->GetEnv((void**)&env, nat->envVer);
+    env->PushLocalFrame(EVENT_LOOP_REFS);
+
     if (dbus_message_is_method_call(msg,
             "org.bluez.Agent", "Cancel")) {
 
@@ -820,11 +828,11 @@
         DBusMessage *reply = dbus_message_new_method_return(msg);
         if (!reply) {
             LOGE("%s: Cannot create message reply\n", __FUNCTION__);
-            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            goto failure;
         }
         dbus_connection_send(nat->conn, reply, NULL);
         dbus_message_unref(reply);
-        return DBUS_HANDLER_RESULT_HANDLED;
+        goto success;
 
     } else if (dbus_message_is_method_call(msg,
             "org.bluez.Agent", "Authorize")) {
@@ -835,7 +843,7 @@
                                    DBUS_TYPE_STRING, &uuid,
                                    DBUS_TYPE_INVALID)) {
             LOGE("%s: Invalid arguments for Authorize() method", __FUNCTION__);
-            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            goto failure;
         }
 
         LOGV("... object_path = %s", object_path);
@@ -850,7 +858,7 @@
             DBusMessage *reply = dbus_message_new_method_return(msg);
             if (!reply) {
                 LOGE("%s: Cannot create message reply\n", __FUNCTION__);
-                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+                goto failure;
             }
             dbus_connection_send(nat->conn, reply, NULL);
             dbus_message_unref(reply);
@@ -859,12 +867,12 @@
                     "org.bluez.Error.Rejected", "Authorization rejected");
             if (!reply) {
                 LOGE("%s: Cannot create message reply\n", __FUNCTION__);
-                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+                goto failure;
             }
             dbus_connection_send(nat->conn, reply, NULL);
             dbus_message_unref(reply);
         }
-        return DBUS_HANDLER_RESULT_HANDLED;
+        goto success;
     } else if (dbus_message_is_method_call(msg,
             "org.bluez.Agent", "RequestPinCode")) {
         char *object_path;
@@ -872,14 +880,14 @@
                                    DBUS_TYPE_OBJECT_PATH, &object_path,
                                    DBUS_TYPE_INVALID)) {
             LOGE("%s: Invalid arguments for RequestPinCode() method", __FUNCTION__);
-            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            goto failure;
         }
 
         dbus_message_ref(msg);  // increment refcount because we pass to java
         env->CallVoidMethod(nat->me, method_onRequestPinCode,
                                        env->NewStringUTF(object_path),
                                        int(msg));
-        return DBUS_HANDLER_RESULT_HANDLED;
+        goto success;
     } else if (dbus_message_is_method_call(msg,
             "org.bluez.Agent", "RequestPasskey")) {
         char *object_path;
@@ -887,13 +895,14 @@
                                    DBUS_TYPE_OBJECT_PATH, &object_path,
                                    DBUS_TYPE_INVALID)) {
             LOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
-            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            goto failure;
         }
 
         dbus_message_ref(msg);  // increment refcount because we pass to java
         env->CallVoidMethod(nat->me, method_onRequestPasskey,
                                        env->NewStringUTF(object_path),
                                        int(msg));
+        goto success;
     } else if (dbus_message_is_method_call(msg,
             "org.bluez.Agent", "RequestConfirmation")) {
         char *object_path;
@@ -903,7 +912,7 @@
                                    DBUS_TYPE_UINT32, &passkey,
                                    DBUS_TYPE_INVALID)) {
             LOGE("%s: Invalid arguments for RequestConfirmation() method", __FUNCTION__);
-            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            goto failure;
         }
 
         dbus_message_ref(msg);  // increment refcount because we pass to java
@@ -911,23 +920,30 @@
                                        env->NewStringUTF(object_path),
                                        passkey,
                                        int(msg));
-        return DBUS_HANDLER_RESULT_HANDLED;
+        goto success;
     } else if (dbus_message_is_method_call(msg,
                   "org.bluez.Agent", "Release")) {
         // reply
         DBusMessage *reply = dbus_message_new_method_return(msg);
         if (!reply) {
             LOGE("%s: Cannot create message reply\n", __FUNCTION__);
-            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            goto failure;
         }
         dbus_connection_send(nat->conn, reply, NULL);
         dbus_message_unref(reply);
-        return DBUS_HANDLER_RESULT_HANDLED;
+        goto success;
     } else {
         LOGV("%s:%s is ignored", dbus_message_get_interface(msg), dbus_message_get_member(msg));
     }
 
+failure:
+    env->PopLocalFrame(NULL);
     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+success:
+    env->PopLocalFrame(NULL);
+    return DBUS_HANDLER_RESULT_HANDLED;
+
 }
 #endif
 
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index 326052b..d1901b4 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -46,6 +46,7 @@
 namespace android {
 
 #define BLUETOOTH_CLASS_ERROR 0xFF000000
+#define PROPERTIES_NREFS 10
 
 #ifdef HAVE_BLUETOOTH
 // We initialize these variables when we load class
@@ -576,11 +577,16 @@
                 LOGE("DBus reply is NULL in function %s", __FUNCTION__);
             return NULL;
         }
+        env->PushLocalFrame(PROPERTIES_NREFS);
+
         DBusMessageIter iter;
         jobjectArray str_array = NULL;
         if (dbus_message_iter_init(reply, &iter))
            str_array =  parse_remote_device_properties(env, &iter);
         dbus_message_unref(reply);
+
+        env->PopLocalFrame(NULL);
+
         return str_array;
     }
 #endif
@@ -607,11 +613,15 @@
                 LOGE("DBus reply is NULL in function %s", __FUNCTION__);
             return NULL;
         }
+        env->PushLocalFrame(PROPERTIES_NREFS);
+
         DBusMessageIter iter;
         jobjectArray str_array = NULL;
         if (dbus_message_iter_init(reply, &iter))
             str_array = parse_adapter_properties(env, &iter);
         dbus_message_unref(reply);
+
+        env->PopLocalFrame(NULL);
         return str_array;
     }
 #endif
diff --git a/core/res/res/drawable/stat_sys_signal_0_cdma.png b/core/res/res/drawable/stat_sys_signal_0_cdma.png
deleted file mode 100644
index 0ef7d53..0000000
--- a/core/res/res/drawable/stat_sys_signal_0_cdma.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_1_cdma.png b/core/res/res/drawable/stat_sys_signal_1_cdma.png
deleted file mode 100644
index f4839d4..0000000
--- a/core/res/res/drawable/stat_sys_signal_1_cdma.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_2_cdma.png b/core/res/res/drawable/stat_sys_signal_2_cdma.png
deleted file mode 100644
index e25a99c..0000000
--- a/core/res/res/drawable/stat_sys_signal_2_cdma.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_3_cdma.png b/core/res/res/drawable/stat_sys_signal_3_cdma.png
deleted file mode 100644
index d828d99..0000000
--- a/core/res/res/drawable/stat_sys_signal_3_cdma.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_4_cdma.png b/core/res/res/drawable/stat_sys_signal_4_cdma.png
deleted file mode 100644
index 53a31ea..0000000
--- a/core/res/res/drawable/stat_sys_signal_4_cdma.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_cdma_0.png b/core/res/res/drawable/stat_sys_signal_cdma_0.png
deleted file mode 100755
index 0ef7d53..0000000
--- a/core/res/res/drawable/stat_sys_signal_cdma_0.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_cdma_1.png b/core/res/res/drawable/stat_sys_signal_cdma_1.png
deleted file mode 100755
index f4839d4..0000000
--- a/core/res/res/drawable/stat_sys_signal_cdma_1.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_cdma_2.png b/core/res/res/drawable/stat_sys_signal_cdma_2.png
deleted file mode 100755
index e25a99c..0000000
--- a/core/res/res/drawable/stat_sys_signal_cdma_2.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_cdma_3.png b/core/res/res/drawable/stat_sys_signal_cdma_3.png
deleted file mode 100755
index d828d99..0000000
--- a/core/res/res/drawable/stat_sys_signal_cdma_3.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_cdma_4.png b/core/res/res/drawable/stat_sys_signal_cdma_4.png
deleted file mode 100755
index 53a31ea..0000000
--- a/core/res/res/drawable/stat_sys_signal_cdma_4.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_evdo_0.png b/core/res/res/drawable/stat_sys_signal_evdo_0.png
deleted file mode 100755
index 1b8aec7..0000000
--- a/core/res/res/drawable/stat_sys_signal_evdo_0.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_evdo_1.png b/core/res/res/drawable/stat_sys_signal_evdo_1.png
deleted file mode 100755
index 7ce01fd..0000000
--- a/core/res/res/drawable/stat_sys_signal_evdo_1.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_evdo_2.png b/core/res/res/drawable/stat_sys_signal_evdo_2.png
deleted file mode 100755
index 890cd59..0000000
--- a/core/res/res/drawable/stat_sys_signal_evdo_2.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_evdo_3.png b/core/res/res/drawable/stat_sys_signal_evdo_3.png
deleted file mode 100755
index 712c640..0000000
--- a/core/res/res/drawable/stat_sys_signal_evdo_3.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_signal_evdo_4.png b/core/res/res/drawable/stat_sys_signal_evdo_4.png
deleted file mode 100755
index f0537dd..0000000
--- a/core/res/res/drawable/stat_sys_signal_evdo_4.png
+++ /dev/null
Binary files differ
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index e40e84a..9bcab72 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -172,4 +172,14 @@
     private static native int  nativeGetStyle(int native_instance);
     private static native int  nativeCreateFromAsset(AssetManager mgr, String path);
     private static native int nativeCreateFromFile(String path);
+
+    /**
+     * Set the global gamma coefficients for black and white text. This call is
+     * usually a no-op in shipping products, and only exists for testing during
+     * development.
+     *
+     * @param blackGamma gamma coefficient for black text
+     * @param whiteGamma gamma coefficient for white text
+     */
+    public static native void setGammaForText(float blackGamma, float whiteGamma);
 }
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index a4be171..792b98d 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -141,15 +141,12 @@
 
     // ----------------------------------------------------------------------
 
-    public RenderScript createRenderScript() {
-        Log.v(RenderScript.LOG_TAG, "createRenderScript 1");
+    public RenderScript createRenderScript(boolean useDepth) {
         Surface sur = null;
         while ((sur == null) || (mSurfaceHolder == null)) {
             sur = getHolder().getSurface();
         }
-        Log.v(RenderScript.LOG_TAG, "createRenderScript 2");
-        RenderScript rs = new RenderScript(sur);
-        Log.v(RenderScript.LOG_TAG, "createRenderScript 3 rs");
+        RenderScript rs = new RenderScript(sur, useDepth);
         return rs;
     }
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 1bdabe7..8489003 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -60,7 +60,7 @@
 
     native int  nDeviceCreate();
     native void nDeviceDestroy(int dev);
-    native int  nContextCreate(int dev, Surface sur, int ver);
+    native int  nContextCreate(int dev, Surface sur, int ver, boolean useDepth);
     native void nContextDestroy(int con);
 
     //void rsContextBindSampler (uint32_t slot, RsSampler sampler);
@@ -194,10 +194,10 @@
     ///////////////////////////////////////////////////////////////////////////////////
     //
 
-    public RenderScript(Surface sur) {
+    public RenderScript(Surface sur, boolean useDepth) {
         mSurface = sur;
         mDev = nDeviceCreate();
-        mContext = nContextCreate(mDev, mSurface, 0);
+        mContext = nContextCreate(mDev, mSurface, 0, useDepth);
 
         // TODO: This should be protected by a lock
         if(!mElementsInitialized) {
@@ -206,6 +206,13 @@
         }
     }
 
+    public void destroy() {
+        nContextDestroy(mContext);
+        mContext = 0;
+
+        nDeviceDestroy(mDev);
+        mDev = 0;
+    }
 
     //////////////////////////////////////////////////////////////////////////////////
     // Triangle Mesh
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index fede0e50..2393f74 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -126,7 +126,7 @@
 }
 
 static jint
-nContextCreate(JNIEnv *_env, jobject _this, jint dev, jobject wnd, jint ver)
+nContextCreate(JNIEnv *_env, jobject _this, jint dev, jobject wnd, jint ver, jboolean useDepth)
 {
     LOG_API("nContextCreate");
 
@@ -142,7 +142,7 @@
     if (window == NULL)
         goto not_valid_surface;
 
-    return (jint)rsContextCreate((RsDevice)dev, window, ver);
+    return (jint)rsContextCreate((RsDevice)dev, window, ver, useDepth);
 }
 
 static void
@@ -1206,7 +1206,7 @@
 {"_nInit",                         "()V",                                  (void*)_nInit },
 {"nDeviceCreate",                  "()I",                                  (void*)nDeviceCreate },
 {"nDeviceDestroy",                 "(I)V",                                 (void*)nDeviceDestroy },
-{"nContextCreate",                 "(ILandroid/view/Surface;I)I",          (void*)nContextCreate },
+{"nContextCreate",                 "(ILandroid/view/Surface;IZ)I",         (void*)nContextCreate },
 {"nContextDestroy",                "(I)V",                                 (void*)nContextDestroy },
 {"nAssignName",                    "(I[B)V",                               (void*)nAssignName },
 {"nObjDestroy",                    "(I)V",                                 (void*)nObjDestroy },
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 0b94118..e4f6a4e 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -82,6 +82,7 @@
         kWantsNALFragments                   = 2,
         kRequiresLoadedToIdleAfterAllocation = 4,
         kRequiresAllocateBufferOnInputPorts  = 8,
+        kRequiresFlushCompleteEmulation      = 16,
     };
 
     struct BufferInfo {
@@ -165,7 +166,13 @@
     void drainInputBuffers();
     void fillOutputBuffers();
 
-    void flushPortAsync(OMX_U32 portIndex);
+    // Returns true iff a flush was initiated and a completion event is
+    // upcoming, false otherwise (A flush was not necessary as we own all
+    // the buffers on that port).
+    // This method will ONLY ever return false for a component with quirk
+    // "kRequiresFlushCompleteEmulation".
+    bool flushPortAsync(OMX_U32 portIndex);
+
     void disablePortAsync(OMX_U32 portIndex);
     void enablePortAsync(OMX_U32 portIndex);
 
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 2f60c9f..1e24cd2 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -49,7 +49,7 @@
 RsDevice rsDeviceCreate();
 void rsDeviceDestroy(RsDevice);
 
-RsContext rsContextCreate(RsDevice, void *, uint32_t version);
+RsContext rsContextCreate(RsDevice, void *, uint32_t version, bool useDepth);
 void rsContextDestroy(RsContext);
 void rsObjDestroyOOB(RsContext, void *);
 
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 fa2caa7..7468d2b 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
@@ -36,7 +36,7 @@
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
         super.surfaceChanged(holder, format, w, h);
 
-        RenderScript RS = createRenderScript();
+        RenderScript RS = createRenderScript(false);
         mRender = new FallRS(w, h);
         mRender.init(RS, getResources());
     }
diff --git a/libs/rs/java/Film/src/com/android/film/FilmView.java b/libs/rs/java/Film/src/com/android/film/FilmView.java
index 73b7414..1c5b2bc 100644
--- a/libs/rs/java/Film/src/com/android/film/FilmView.java
+++ b/libs/rs/java/Film/src/com/android/film/FilmView.java
@@ -52,7 +52,7 @@
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
         super.surfaceChanged(holder, format, w, h);
 
-        mRS = createRenderScript();
+        mRS = createRenderScript(true);
         mRender = new FilmRS();
         mRender.init(mRS, getResources(), w, h);
     }
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
index 2768e2c..7826161 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
@@ -52,7 +52,7 @@
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
         super.surfaceChanged(holder, format, w, h);
 
-        mRS = createRenderScript();
+        mRS = createRenderScript(false);
         mRender = new FountainRS();
         mRender.init(mRS, getResources(), w, h);
     }
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java
index 3e1c54d..7524a0e 100644
--- a/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java
+++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java
@@ -54,7 +54,7 @@
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
         super.surfaceChanged(holder, format, w, h);
 
-        mRS = createRenderScript();
+        mRS = createRenderScript(false);
         mRender = new RolloRS();
         mRender.init(mRS, getResources(), w, h);
     }
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 413caab..3ebfdce 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -18,6 +18,7 @@
 #include "rsContext.h"
 #include "rsThreadIO.h"
 #include <ui/FramebufferNativeWindow.h>
+#include <ui/EGLUtils.h>
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
@@ -29,41 +30,64 @@
 
 void Context::initEGL()
 {
-    mNumConfigs = -1;
+    mEGL.mNumConfigs = -1;
+    EGLint configAttribs[128];
+    EGLint *configAttribsPtr = configAttribs;
 
-    EGLint s_configAttribs[] = {
-         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-#if 1
-         EGL_RED_SIZE,       8,
-         EGL_GREEN_SIZE,     8,
-         EGL_BLUE_SIZE,      8,
-         EGL_ALPHA_SIZE,     8,
-#else
-         EGL_RED_SIZE,       5,
-         EGL_GREEN_SIZE,     6,
-         EGL_BLUE_SIZE,      5,
-#endif
-         EGL_DEPTH_SIZE,     16,
-         EGL_NONE
-     };
+    memset(configAttribs, 0, sizeof(configAttribs));
 
-     mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-     eglInitialize(mDisplay, &mMajorVersion, &mMinorVersion);
-     eglChooseConfig(mDisplay, s_configAttribs, &mConfig, 1, &mNumConfigs);
+    configAttribsPtr[0] = EGL_SURFACE_TYPE;
+    configAttribsPtr[1] = EGL_WINDOW_BIT;
+    configAttribsPtr += 2;
 
-     if (mWndSurface) {
-         mSurface = eglCreateWindowSurface(mDisplay, mConfig, mWndSurface,
-                 NULL);
-     } else {
-         mSurface = eglCreateWindowSurface(mDisplay, mConfig,
-                 android_createDisplaySurface(),
-                 NULL);
-     }
+    if (mUseDepth) {
+        configAttribsPtr[0] = EGL_DEPTH_SIZE;
+        configAttribsPtr[1] = 16;
+        configAttribsPtr += 2;
+    }
+    configAttribsPtr[0] = EGL_NONE;
+    rsAssert(configAttribsPtr < (configAttribs + (sizeof(configAttribs) / sizeof(EGLint))));
 
-     mContext = eglCreateContext(mDisplay, mConfig, NULL, NULL);
-     eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
-     eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth);
-     eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight);
+    mEGL.mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(mEGL.mDisplay, &mEGL.mMajorVersion, &mEGL.mMinorVersion);
+
+    status_t err = EGLUtils::selectConfigForNativeWindow(mEGL.mDisplay, configAttribs, mWndSurface, &mEGL.mConfig);
+    if (err) {
+     LOGE("couldn't find an EGLConfig matching the screen format\n");
+    }
+    //eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs);
+
+    if (mWndSurface) {
+        mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL);
+    } else {
+        mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig,
+             android_createDisplaySurface(),
+             NULL);
+    }
+
+    mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, NULL, NULL);
+    eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext);
+    eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
+    eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight);
+
+
+    mGL.mVersion = glGetString(GL_VERSION);
+    mGL.mVendor = glGetString(GL_VENDOR);
+    mGL.mRenderer = glGetString(GL_RENDERER);
+    mGL.mExtensions = glGetString(GL_EXTENSIONS);
+
+    LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
+    LOGV("GL Version %s", mGL.mVersion);
+    LOGV("GL Vendor %s", mGL.mVendor);
+    LOGV("GL Renderer %s", mGL.mRenderer);
+    LOGV("GL Extensions %s", mGL.mExtensions);
+
+    if (memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) {
+        LOGE("Error, OpenGL ES Lite not supported");
+    }
+    sscanf((const char *)mGL.mVersion + 13, "%i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion);
+
+
 }
 
 bool Context::runScript(Script *s, uint32_t launchID)
@@ -90,19 +114,22 @@
 
     //glColor4f(1,1,1,1);
     //glEnable(GL_LIGHT0);
-    glViewport(0, 0, mWidth, mHeight);
-
-    glDepthMask(GL_TRUE);
+    glViewport(0, 0, mEGL.mWidth, mEGL.mHeight);
+#if 1
     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 
     glClearColor(mRootScript->mEnviroment.mClearColor[0],
                  mRootScript->mEnviroment.mClearColor[1],
                  mRootScript->mEnviroment.mClearColor[2],
                  mRootScript->mEnviroment.mClearColor[3]);
-    glClearDepthf(mRootScript->mEnviroment.mClearDepth);
-    glClear(GL_COLOR_BUFFER_BIT);
-    glClear(GL_DEPTH_BUFFER_BIT);
-
+    if (mUseDepth) {
+        glDepthMask(GL_TRUE);
+        glClearDepthf(mRootScript->mEnviroment.mClearDepth);
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    } else {
+        glClear(GL_COLOR_BUFFER_BIT);
+    }
+#endif
 #if RS_LOG_TIMES
     timerSet(RS_TIMER_SCRIPT);
 #endif
@@ -156,13 +183,13 @@
 void Context::setupCheck()
 {
     if (mFragmentStore.get()) {
-        mFragmentStore->setupGL(&mStateFragmentStore);
+        mFragmentStore->setupGL(this, &mStateFragmentStore);
     }
     if (mFragment.get()) {
-        mFragment->setupGL(&mStateFragment);
+        mFragment->setupGL(this, &mStateFragment);
     }
     if (mVertex.get()) {
-        mVertex->setupGL(&mStateVertex);
+        mVertex->setupGL(this, &mStateVertex);
     }
 
 }
@@ -186,11 +213,11 @@
          LOGE("pthread_setspecific %i", status);
      }
 
-     rsc->mStateVertex.init(rsc, rsc->mWidth, rsc->mHeight);
+     rsc->mStateVertex.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
      rsc->setVertex(NULL);
-     rsc->mStateFragment.init(rsc, rsc->mWidth, rsc->mHeight);
+     rsc->mStateFragment.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
      rsc->setFragment(NULL);
-     rsc->mStateFragmentStore.init(rsc, rsc->mWidth, rsc->mHeight);
+     rsc->mStateFragmentStore.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
      rsc->setFragmentStore(NULL);
 
      rsc->mRunning = true;
@@ -204,7 +231,7 @@
 #if RS_LOG_TIMES
              rsc->timerSet(RS_TIMER_CLEAR_SWAP);
 #endif
-             eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
+             eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
 #if RS_LOG_TIMES
              rsc->timerSet(RS_TIMER_INTERNAL);
              rsc->timerPrint();
@@ -216,20 +243,23 @@
          }
      }
 
+     LOGV("RS Thread exiting");
      glClearColor(0,0,0,0);
      glClear(GL_COLOR_BUFFER_BIT);
-     eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
-     eglTerminate(rsc->mDisplay);
+     eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
+     eglTerminate(rsc->mEGL.mDisplay);
      rsc->objDestroyOOBRun();
+     LOGV("RS Thread exited");
      return NULL;
 }
 
-Context::Context(Device *dev, Surface *sur)
+Context::Context(Device *dev, Surface *sur, bool useDepth)
 {
     dev->addContext(this);
     mDev = dev;
     mRunning = false;
     mExit = false;
+    mUseDepth = useDepth;
 
     int status;
     pthread_attr_t threadAttr;
@@ -270,9 +300,11 @@
 
 Context::~Context()
 {
+    LOGV("Context::~Context");
     mExit = true;
     void *res;
 
+    mIO.shutdown();
     int status = pthread_join(mThreadId, &res);
     objDestroyOOBRun();
 
@@ -284,17 +316,6 @@
     objDestroyOOBDestroy();
 }
 
-void Context::swapBuffers()
-{
-    eglSwapBuffers(mDisplay, mSurface);
-}
-
-void rsContextSwap(RsContext vrsc)
-{
-    Context *rsc = static_cast<Context *>(vrsc);
-    rsc->swapBuffers();
-}
-
 void Context::setRootScript(Script *s)
 {
     mRootScript.set(s);
@@ -520,10 +541,10 @@
 }
 
 
-RsContext rsContextCreate(RsDevice vdev, void *sur, uint32_t version)
+RsContext rsContextCreate(RsDevice vdev, void *sur, uint32_t version, bool useDepth)
 {
     Device * dev = static_cast<Device *>(vdev);
-    Context *rsc = new Context(dev, (Surface *)sur);
+    Context *rsc = new Context(dev, (Surface *)sur, useDepth);
     return rsc;
 }
 
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index ca67e40..c58a88c 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -49,7 +49,7 @@
 class Context
 {
 public:
-    Context(Device *, Surface *);
+    Context(Device *, Surface *, bool useDepth);
     ~Context();
 
     static pthread_key_t gThreadTLSKey;
@@ -111,8 +111,8 @@
         mFloatDefines.add(String8(name), value);
     }
 
-    uint32_t getWidth() const {return mWidth;}
-    uint32_t getHeight() const {return mHeight;}
+    uint32_t getWidth() const {return mEGL.mWidth;}
+    uint32_t getHeight() const {return mEGL.mHeight;}
 
 
     ThreadIO mIO;
@@ -132,21 +132,38 @@
     void timerSet(Timers);
     void timerPrint();
 
+    bool checkVersion1_1() const {return (mGL.mMajorVersion > 1) || (mGL.mMinorVersion >= 1); }
+    bool checkVersion2_0() const {return mGL.mMajorVersion >= 2; }
+
 protected:
     Device *mDev;
 
-    EGLint mNumConfigs;
-    EGLint mMajorVersion;
-    EGLint mMinorVersion;
-    EGLConfig mConfig;
-    EGLContext mContext;
-    EGLSurface mSurface;
-    EGLint mWidth;
-    EGLint mHeight;
-    EGLDisplay mDisplay;
+    struct {
+        EGLint mNumConfigs;
+        EGLint mMajorVersion;
+        EGLint mMinorVersion;
+        EGLConfig mConfig;
+        EGLContext mContext;
+        EGLSurface mSurface;
+        EGLint mWidth;
+        EGLint mHeight;
+        EGLDisplay mDisplay;
+    } mEGL;
+
+    struct {
+        const uint8_t * mVendor;
+        const uint8_t * mRenderer;
+        const uint8_t * mVersion;
+        const uint8_t * mExtensions;
+
+        uint32_t mMajorVersion;
+        uint32_t mMinorVersion;
+
+    } mGL;
 
     bool mRunning;
     bool mExit;
+    bool mUseDepth;
 
     pthread_t mThreadId;
 
diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp
index c3fee54..0c403895 100644
--- a/libs/rs/rsLocklessFifo.cpp
+++ b/libs/rs/rsLocklessFifo.cpp
@@ -25,6 +25,16 @@
 
 LocklessCommandFifo::~LocklessCommandFifo()
 {
+    if (!mInShutdown) {
+        shutdown();
+    }
+    free(mBuffer);
+}
+
+void LocklessCommandFifo::shutdown()
+{
+    mInShutdown = true;
+    mSignalToWorker.set();
 }
 
 bool LocklessCommandFifo::init(uint32_t sizeInBytes)
@@ -42,6 +52,7 @@
         return false;
     }
 
+    mInShutdown = false;
     mSize = sizeInBytes;
     mPut = mBuffer;
     mGet = mBuffer;
@@ -50,7 +61,7 @@
     return true;
 }
 
-uint32_t LocklessCommandFifo::getFreeSpace() const 
+uint32_t LocklessCommandFifo::getFreeSpace() const
 {
     int32_t freeSpace = 0;
     //dumpState("getFreeSpace");
@@ -115,7 +126,7 @@
 {
     while(1) {
         //dumpState("get");
-        while(isEmpty()) {
+        while(isEmpty() && !mInShutdown) {
             mSignalToControl.set();
             mSignalToWorker.wait();
         }
@@ -126,7 +137,7 @@
             // non-zero command is valid
             return mGet+4;
         }
-    
+
         // zero command means reset to beginning.
         mGet = mBuffer;
     }
@@ -161,7 +172,7 @@
     while(getFreeSpace() < bytes) {
         sleep(1);
     }
-    
+
 }
 
 void LocklessCommandFifo::dumpState(const char *s) const
diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h
index abeddf7..d0a4356 100644
--- a/libs/rs/rsLocklessFifo.h
+++ b/libs/rs/rsLocklessFifo.h
@@ -25,13 +25,14 @@
 
 // A simple FIFO to be used as a producer / consumer between two
 // threads.  One is writer and one is reader.  The common cases
-// will not require locking.  It is not threadsafe for multiple 
+// will not require locking.  It is not threadsafe for multiple
 // readers or writers by design.
 
-class LocklessCommandFifo 
+class LocklessCommandFifo
 {
 public:
     bool init(uint32_t size);
+    void shutdown();
 
     LocklessCommandFifo();
     ~LocklessCommandFifo();
@@ -59,6 +60,7 @@
     uint8_t * mBuffer;
     uint8_t * mEnd;
     uint8_t mSize;
+    bool mInShutdown;
 
     Signal mSignalToWorker;
     Signal mSignalToControl;
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index 6a5b7d8..07bbc1e 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -43,6 +43,11 @@
     mRefCount --;
     //LOGV("ObjectBase %p dec ref %i", this, mRefCount);
     if (!mRefCount) {
+        if (mName) {
+            LOGV("Deleting RS object %p, name %s", this, mName);
+        } else {
+            LOGV("Deleting RS object %p, no name", this);
+        }
         delete this;
     }
 }
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index 6606daa..18eacfb 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -47,9 +47,3 @@
     }
 }
 
-void Program::setupGL()
-{
-
-}
-
-
diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h
index 251072f..bb3d9ac 100644
--- a/libs/rs/rsProgram.h
+++ b/libs/rs/rsProgram.h
@@ -32,11 +32,7 @@
     Program(Element *in, Element *out);
     virtual ~Program();
 
-
     void bindAllocation(Allocation *);
-
-    virtual void setupGL();
-
     void checkUpdatedAllocation(const Allocation *);
 
 protected:
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index 4ef6835..654974f 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -40,7 +40,7 @@
 {
 }
 
-void ProgramFragment::setupGL(ProgramFragmentState *state)
+void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
 {
     if ((state->mLast.get() == this) && !mDirty) {
         return;
@@ -55,7 +55,9 @@
         }
 
         glEnable(GL_TEXTURE_2D);
-        //glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
+        if (rsc->checkVersion1_1()) {
+            glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
+        }
         glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
 
         switch(mEnvModes[ct]) {
diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h
index bd45342..51117eb 100644
--- a/libs/rs/rsProgramFragment.h
+++ b/libs/rs/rsProgramFragment.h
@@ -35,7 +35,7 @@
     ProgramFragment(Element *in, Element *out, bool pointSpriteEnable);
     virtual ~ProgramFragment();
 
-    virtual void setupGL(ProgramFragmentState *);
+    virtual void setupGL(const Context *, ProgramFragmentState *);
 
 
 
diff --git a/libs/rs/rsProgramFragmentStore.cpp b/libs/rs/rsProgramFragmentStore.cpp
index 99eed16..36ec615 100644
--- a/libs/rs/rsProgramFragmentStore.cpp
+++ b/libs/rs/rsProgramFragmentStore.cpp
@@ -48,7 +48,7 @@
 {
 }
 
-void ProgramFragmentStore::setupGL(ProgramFragmentStoreState *state)
+void ProgramFragmentStore::setupGL(const Context *rsc, ProgramFragmentStoreState *state)
 {
     if (state->mLast.get() == this) {
         return;
diff --git a/libs/rs/rsProgramFragmentStore.h b/libs/rs/rsProgramFragmentStore.h
index 0de5c3a..e646e03 100644
--- a/libs/rs/rsProgramFragmentStore.h
+++ b/libs/rs/rsProgramFragmentStore.h
@@ -31,7 +31,7 @@
     ProgramFragmentStore(Element *in, Element *out);
     virtual ~ProgramFragmentStore();
 
-    virtual void setupGL(ProgramFragmentStoreState *);
+    virtual void setupGL(const Context *, ProgramFragmentStoreState *);
 
     void setDepthFunc(RsDepthFunc);
     void setDepthMask(bool);
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 6ef5456..dc57d34 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -44,7 +44,7 @@
     LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[3], f[7], f[11], f[15]);
 }
 
-void ProgramVertex::setupGL(ProgramVertexState *state)
+void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state)
 {
     if ((state->mLast.get() == this) && !mDirty) {
         return;
diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h
index c9ce7aa..523c3ed 100644
--- a/libs/rs/rsProgramVertex.h
+++ b/libs/rs/rsProgramVertex.h
@@ -33,7 +33,7 @@
     ProgramVertex(Element *in, Element *out);
     virtual ~ProgramVertex();
 
-    virtual void setupGL(ProgramVertexState *state);
+    virtual void setupGL(const Context *rsc, ProgramVertexState *state);
 
 
     void setTextureMatrixEnable(bool e) {mTextureMatrixEnable = e;}
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 4a1dbbb..db4bb81 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -30,6 +30,11 @@
 {
 }
 
+void ThreadIO::shutdown()
+{
+    mToCore.shutdown();
+}
+
 bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand)
 {
     bool ret = false;
diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h
index 4aab1b4..1f6a0c2 100644
--- a/libs/rs/rsThreadIO.h
+++ b/libs/rs/rsThreadIO.h
@@ -31,6 +31,8 @@
     ThreadIO();
     ~ThreadIO();
 
+    void shutdown();
+
     // Plays back commands from the client.
     // Returns true if any commands were processed.
     bool playCoreCommands(Context *con, bool waitForCommand);
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index ec9f6d3..fec6cfb 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -193,6 +193,7 @@
     }
     if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
         quirks |= kNeedsFlushBeforeDisable;
+        quirks |= kRequiresFlushCompleteEmulation;
     }
     if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
         quirks |= kRequiresLoadedToIdleAfterAllocation;
@@ -1163,21 +1164,38 @@
     setState(RECONFIGURING);
 
     if (mQuirks & kNeedsFlushBeforeDisable) {
-        flushPortAsync(portIndex);
+        if (!flushPortAsync(portIndex)) {
+            onCmdComplete(OMX_CommandFlush, portIndex);
+        }
     } else {
         disablePortAsync(portIndex);
     }
 }
 
-void OMXCodec::flushPortAsync(OMX_U32 portIndex) {
+bool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
     CHECK(mState == EXECUTING || mState == RECONFIGURING);
 
+    LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
+         portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
+         mPortBuffers[portIndex].size());
+
     CHECK_EQ(mPortStatus[portIndex], ENABLED);
     mPortStatus[portIndex] = SHUTTING_DOWN;
 
+    if ((mQuirks & kRequiresFlushCompleteEmulation)
+        && countBuffersWeOwn(mPortBuffers[portIndex])
+                == mPortBuffers[portIndex].size()) {
+        // No flush is necessary and this component fails to send a
+        // flush-complete event in this case.
+
+        return false;
+    }
+
     status_t err =
         mOMX->send_command(mNode, OMX_CommandFlush, portIndex);
     CHECK_EQ(err, OK);
+
+    return true;
 }
 
 void OMXCodec::disablePortAsync(OMX_U32 portIndex) {
@@ -1323,6 +1341,12 @@
 void OMXCodec::fillOutputBuffer(BufferInfo *info) {
     CHECK_EQ(info->mOwnedByComponent, false);
 
+    if (mNoMoreOutputData) {
+        LOGV("There is no more output data available, not "
+             "calling fillOutputBuffer");
+        return;
+    }
+
     LOGV("Calling fill_buffer on buffer %p", info->mBuffer);
     mOMX->fill_buffer(mNode, info->mBuffer);
 
@@ -1648,8 +1672,16 @@
 
         CHECK_EQ(mState, EXECUTING);
 
-        flushPortAsync(kPortIndexInput);
-        flushPortAsync(kPortIndexOutput);
+        bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
+        bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
+
+        if (emulateInputFlushCompletion) {
+            onCmdComplete(OMX_CommandFlush, kPortIndexInput);
+        }
+
+        if (emulateOutputFlushCompletion) {
+            onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
+        }
     }
 
     while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
index dcb8c43..ea42f53 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
@@ -435,13 +435,6 @@
     @LargeTest
     public void testLocalMp3PrepareAsyncCallback() throws Exception {
         boolean onPrepareSuccess = 
-            CodecTest.prepareAsyncCallback(MediaNames.MP3CBR, false);
-        assertTrue("LocalMp3prepareAsyncCallback", onPrepareSuccess);
-    }
-
-    @LargeTest
-    public void testLocalH263AMRPrepareAsyncCallback() throws Exception {
-        boolean onPrepareSuccess =
             CodecTest.prepareAsyncCallback(MediaNames.VIDEO_H263_AMR, false);
         assertTrue("LocalMp3prepareAsyncCallback", onPrepareSuccess);
     }
diff --git a/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsProvider.java b/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsProvider.java
index 120b4a3..2647752 100644
--- a/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsProvider.java
+++ b/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsProvider.java
@@ -127,7 +127,9 @@
     protected void onAccountsChanged(Account[] accountsArray) {
         super.onAccountsChanged(accountsArray);
         for (Account account : accountsArray) {
-            ContentResolver.setSyncAutomatically(account, "subscribedfeeds", true);
+            if (account.type.equals("com.google.GAIA")) {
+                ContentResolver.setSyncAutomatically(account, "subscribedfeeds", true);
+            }
         }
     }
 
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index a4b0685..23eb7c1 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -755,6 +755,8 @@
     String mTopData;
     boolean mSystemReady = false;
     boolean mBooting = false;
+    boolean mWaitingUpdate = false;
+    boolean mDidUpdate = false;
 
     Context mContext;
 
@@ -972,6 +974,8 @@
                         res.set(0);
                     }
                 }
+                
+                ensureBootCompleted();
             } break;
             case SHOW_NOT_RESPONDING_MSG: {
                 synchronized (ActivityManagerService.this) {
@@ -992,13 +996,13 @@
                     proc.anrDialog = d;
                 }
                 
-                ensureScreenEnabled();
+                ensureBootCompleted();
             } break;
             case SHOW_FACTORY_ERROR_MSG: {
                 Dialog d = new FactoryErrorDialog(
                     mContext, msg.getData().getCharSequence("msg"));
                 d.show();
-                enableScreenAfterBoot();
+                ensureBootCompleted();
             } break;
             case UPDATE_CONFIGURATION_MSG: {
                 final ContentResolver resolver = mContext.getContentResolver();
@@ -1843,12 +1847,12 @@
         }
 
         startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
-                "activity", r.intent.getComponent());
+                "activity", r.intent.getComponent(), false);
     }
 
     private final ProcessRecord startProcessLocked(String processName,
             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
-            String hostingType, ComponentName hostingName) {
+            String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
         ProcessRecord app = getProcessRecordLocked(processName, info.uid);
         // We don't have to do anything more if:
         // (1) There is an existing application record; and
@@ -1901,7 +1905,8 @@
         // If the system is not ready yet, then hold off on starting this
         // process until it is.
         if (!mSystemReady
-                && (info.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
+                && !isAllowedWhileBooting(info)
+                && !allowWhileBooting) {
             if (!mProcessesOnHold.contains(app)) {
                 mProcessesOnHold.add(app);
             }
@@ -1912,6 +1917,10 @@
         return (app.pid != 0) ? app : null;
     }
 
+    boolean isAllowedWhileBooting(ApplicationInfo ai) {
+        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
+    }
+    
     private final void startProcessLocked(ProcessRecord app,
             String hostingType, String hostingNameStr) {
         if (app.pid > 0 && app.pid != MY_PID) {
@@ -5085,8 +5094,13 @@
 
         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
 
-        List providers = generateApplicationProvidersLocked(app);
+        boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info);
+        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
 
+        if (!normalMode) {
+            Log.i(TAG, "Launching preboot mode app: " + app);
+        }
+        
         if (localLOGV) Log.v(
             TAG, "New app record " + app
             + " thread=" + thread.asBinder() + " pid=" + pid);
@@ -5102,12 +5116,14 @@
                     mWaitForDebugger = mOrigWaitForDebugger;
                 }
             }
+            
             // If the app is being launched for restore or full backup, set it up specially
             boolean isRestrictedBackupMode = false;
             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
             }
+            
             ensurePackageDexOpt(app.instrumentationInfo != null
                     ? app.instrumentationInfo.packageName
                     : app.info.packageName);
@@ -5118,7 +5134,8 @@
                     ? app.instrumentationInfo : app.info, providers,
                     app.instrumentationClass, app.instrumentationProfileFile,
                     app.instrumentationArguments, app.instrumentationWatcher, testMode, 
-                    isRestrictedBackupMode, mConfiguration, getCommonServicesLocked());
+                    isRestrictedBackupMode || !normalMode,
+                    mConfiguration, getCommonServicesLocked());
             updateLRUListLocked(app, false);
             app.lastRequestedGc = SystemClock.uptimeMillis();
         } catch (Exception e) {
@@ -5284,6 +5301,8 @@
     }
 
     void enableScreenAfterBoot() {
+        EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN,
+                SystemClock.uptimeMillis());
         mWindowManager.enableScreenAfterBoot();
     }
 
@@ -5394,26 +5413,7 @@
         }
 
         if (booting) {
-            // Ensure that any processes we had put on hold are now started
-            // up.
-            final int NP = mProcessesOnHold.size();
-            if (NP > 0) {
-                ArrayList<ProcessRecord> procs =
-                    new ArrayList<ProcessRecord>(mProcessesOnHold);
-                for (int ip=0; ip<NP; ip++) {
-                    this.startProcessLocked(procs.get(ip), "on-hold", null);
-                }
-            }
-            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
-                // Tell anyone interested that we are done booting!
-                synchronized (this) {
-                    broadcastIntentLocked(null, null,
-                            new Intent(Intent.ACTION_BOOT_COMPLETED, null),
-                            null, null, 0, null, null,
-                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
-                            false, false, MY_PID, Process.SYSTEM_UID);
-                }
-            }
+            finishBooting();
         }
 
         trimApplications();
@@ -5421,22 +5421,48 @@
         //mWindowManager.dump();
 
         if (enableScreen) {
-            EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN,
-                SystemClock.uptimeMillis());
             enableScreenAfterBoot();
         }
     }
 
-    final void ensureScreenEnabled() {
+    final void finishBooting() {
+        // Ensure that any processes we had put on hold are now started
+        // up.
+        final int NP = mProcessesOnHold.size();
+        if (NP > 0) {
+            ArrayList<ProcessRecord> procs =
+                new ArrayList<ProcessRecord>(mProcessesOnHold);
+            for (int ip=0; ip<NP; ip++) {
+                this.startProcessLocked(procs.get(ip), "on-hold", null);
+            }
+        }
+        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
+            // Tell anyone interested that we are done booting!
+            synchronized (this) {
+                broadcastIntentLocked(null, null,
+                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
+                        null, null, 0, null, null,
+                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
+                        false, false, MY_PID, Process.SYSTEM_UID);
+            }
+        }
+    }
+    
+    final void ensureBootCompleted() {
+        boolean booting;
         boolean enableScreen;
         synchronized (this) {
+            booting = mBooting;
+            mBooting = false;
             enableScreen = !mBooted;
             mBooted = true;
         }
+        
+        if (booting) {
+            finishBooting();
+        }
 
         if (enableScreen) {
-            EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN,
-                SystemClock.uptimeMillis());
             enableScreenAfterBoot();
         }
     }
@@ -5588,6 +5614,13 @@
             throw new IllegalArgumentException("File descriptors passed in Intent");
         }
 
+        if (type == INTENT_SENDER_BROADCAST) {
+            if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
+                throw new IllegalArgumentException(
+                        "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
+            }
+        }
+        
         synchronized(this) {
             int callingUid = Binder.getCallingUid();
             try {
@@ -7398,7 +7431,7 @@
                     ProcessRecord proc = startProcessLocked(cpi.processName,
                             cpr.appInfo, false, 0, "content provider",
                             new ComponentName(cpi.applicationInfo.packageName,
-                                    cpi.name));
+                                    cpi.name), false);
                     if (proc == null) {
                         Log.w(TAG, "Unable to launch app "
                                 + cpi.applicationInfo.packageName + "/"
@@ -8125,17 +8158,93 @@
             if (mSystemReady) {
                 return;
             }
+            
+            // Check to see if there are any update receivers to run.
+            if (!mDidUpdate) {
+                if (mWaitingUpdate) {
+                    return;
+                }
+                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
+                List<ResolveInfo> ris = null;
+                try {
+                    ris = ActivityThread.getPackageManager().queryIntentReceivers(
+                                intent, null, 0);
+                } catch (RemoteException e) {
+                }
+                if (ris != null) {
+                    for (int i=ris.size()-1; i>=0; i--) {
+                        if ((ris.get(i).activityInfo.applicationInfo.flags
+                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
+                            ris.remove(i);
+                        }
+                    }
+                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
+                    for (int i=0; i<ris.size(); i++) {
+                        ActivityInfo ai = ris.get(i).activityInfo;
+                        intent.setComponent(new ComponentName(ai.packageName, ai.name));
+                        IIntentReceiver finisher = null;
+                        if (i == 0) {
+                            finisher = new IIntentReceiver.Stub() {
+                                public void performReceive(Intent intent, int resultCode,
+                                        String data, Bundle extras, boolean ordered)
+                                        throws RemoteException {
+                                    synchronized (ActivityManagerService.this) {
+                                        mDidUpdate = true;
+                                    }
+                                    systemReady();
+                                }
+                            };
+                        }
+                        Log.i(TAG, "Sending system update to: " + intent.getComponent());
+                        broadcastIntentLocked(null, null, intent, null, finisher,
+                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
+                        if (i == 0) {
+                            mWaitingUpdate = true;
+                        }
+                    }
+                }
+                if (mWaitingUpdate) {
+                    return;
+                }
+                mDidUpdate = true;
+            }
+            
             mSystemReady = true;
             if (!mStartRunning) {
                 return;
             }
         }
 
+        ArrayList<ProcessRecord> procsToKill = null;
+        synchronized(mPidsSelfLocked) {
+            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
+                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
+                if (!isAllowedWhileBooting(proc.info)){
+                    if (procsToKill == null) {
+                        procsToKill = new ArrayList<ProcessRecord>();
+                    }
+                    procsToKill.add(proc);
+                }
+            }
+        }
+        
+        if (procsToKill != null) {
+            synchronized(this) {
+                for (int i=procsToKill.size()-1; i>=0; i--) {
+                    ProcessRecord proc = procsToKill.get(i);
+                    Log.i(TAG, "Removing system update proc: " + proc);
+                    removeProcessLocked(proc, true);
+                }
+            }
+        }
+        
         if (Config.LOGD) Log.d(TAG, "Start running!");
         EventLog.writeEvent(LOG_BOOT_PROGRESS_AMS_READY,
             SystemClock.uptimeMillis());
 
         synchronized(this) {
+            // Make sure we have no pre-ready processes sitting around.
+            
             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
                 ResolveInfo ri = mContext.getPackageManager()
                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
@@ -8193,6 +8302,9 @@
                 }
             }
 
+            // Start up initial activity.
+            mBooting = true;
+            
             try {
                 if (ActivityThread.getPackageManager().hasSystemUidErrors()) {
                     Message msg = Message.obtain();
@@ -8202,8 +8314,6 @@
             } catch (RemoteException e) {
             }
 
-            // Start up initial activity.
-            mBooting = true;
             resumeTopActivityLocked(null);
         }
     }
@@ -10128,7 +10238,7 @@
             // Not running -- get it started, and enqueue this service record
             // to be executed when the app comes up.
             if (startProcessLocked(appName, r.appInfo, true, intentFlags,
-                    "service", r.name) == null) {
+                    "service", r.name, false) == null) {
                 Log.w(TAG, "Unable to launch app "
                         + r.appInfo.packageName + "/"
                         + r.appInfo.uid + " for service "
@@ -10930,7 +11040,7 @@
             ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
             // startProcessLocked() returns existing proc's record if it's already running
             ProcessRecord proc = startProcessLocked(app.processName, app,
-                    false, 0, "backup", hostingName);
+                    false, 0, "backup", hostingName, false);
             if (proc == null) {
                 Log.e(TAG, "Unable to start backup agent process " + r);
                 return false;
@@ -11467,10 +11577,11 @@
         }
 
         synchronized(this) {
+            int flags = intent.getFlags();
+            
             if (!mSystemReady) {
                 // if the caller really truly claims to know what they're doing, go
                 // ahead and allow the broadcast without launching any receivers
-                int flags = intent.getFlags();
                 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
                     intent = new Intent(intent);
                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
@@ -11481,6 +11592,11 @@
                 }
             }
             
+            if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
+                throw new IllegalArgumentException(
+                        "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
+            }
+            
             final ProcessRecord callerApp = getRecordForAppLocked(caller);
             final int callingPid = Binder.getCallingPid();
             final int callingUid = Binder.getCallingUid();
@@ -12075,12 +12191,13 @@
                 // restart the application.
             }
 
-            // Not running -- get it started, and enqueue this history record
-            // to be executed when the app comes up.
+            // Not running -- get it started, to be executed when the app comes up.
             if ((r.curApp=startProcessLocked(targetProcess,
                     info.activityInfo.applicationInfo, true,
                     r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
-                    "broadcast", r.curComponent)) == null) {
+                    "broadcast", r.curComponent,
+                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
+                            == null) {
                 // Ah, this recipient is unavailable.  Finish it if necessary,
                 // and mark the broadcast record as ready for the next.
                 Log.w(TAG, "Unable to launch app "
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index c6b085d..65b2ddb 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -105,11 +105,9 @@
     // phone
     private TelephonyManager mPhone;
     private IBinder mPhoneIcon;
-    private IBinder mPhoneEvdoIcon;
 
     //***** Signal strength icons
     private IconData mPhoneData;
-    private IconData mPhoneEvdoData;
     //GSM/UMTS
     private static final int[] sSignalImages = new int[] {
         com.android.internal.R.drawable.stat_sys_signal_0,
@@ -125,14 +123,6 @@
         com.android.internal.R.drawable.stat_sys_r_signal_3,
         com.android.internal.R.drawable.stat_sys_r_signal_4
     };
-    //CDMA
-    private static final int[] sSignalImages_cdma = new int[] {
-        com.android.internal.R.drawable.stat_sys_signal_cdma_0,
-        com.android.internal.R.drawable.stat_sys_signal_cdma_1,
-        com.android.internal.R.drawable.stat_sys_signal_cdma_2,
-        com.android.internal.R.drawable.stat_sys_signal_cdma_3,
-        com.android.internal.R.drawable.stat_sys_signal_cdma_4
-    };
     private static final int[] sRoamingIndicatorImages_cdma = new int[] {
         com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //Standard Roaming Indicator
         // 1 is Standard Roaming Indicator OFF
@@ -232,14 +222,6 @@
 
         // 128-255 Reserved
     };
-    // EVDO
-    private static final int[] sSignalImages_evdo = new int[] {
-        com.android.internal.R.drawable.stat_sys_signal_evdo_0,
-        com.android.internal.R.drawable.stat_sys_signal_evdo_1,
-        com.android.internal.R.drawable.stat_sys_signal_evdo_2,
-        com.android.internal.R.drawable.stat_sys_signal_evdo_3,
-        com.android.internal.R.drawable.stat_sys_signal_evdo_4
-    };
 
     //***** Data connection icons
     private int[] mDataIconList = sDataNetType_g;
@@ -438,12 +420,6 @@
                 null, com.android.internal.R.drawable.stat_sys_signal_null, 0, 0);
         mPhoneIcon = service.addIcon(mPhoneData, null);
 
-        // phone_evdo_signal
-        mPhoneEvdoData = IconData.makeIcon("phone_evdo_signal",
-                null, com.android.internal.R.drawable.stat_sys_signal_evdo_0, 0, 0);
-        mPhoneEvdoIcon = service.addIcon(mPhoneEvdoData, null);
-        service.setIconVisibility(mPhoneEvdoIcon, false);
-
         // register for phone state notifications.
         ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE))
                 .listen(mPhoneStateListener,
@@ -499,7 +475,7 @@
         mGpsFixIconData = IconData.makeIcon("gps",
                 null, com.android.internal.R.drawable.stat_sys_gps_on, 0, 0);
         mGpsIcon = service.addIcon(mGpsEnabledIconData, null);
-        service.setIconVisibility(mGpsIcon, false);           
+        service.setIconVisibility(mGpsIcon, false);
 
         // Alarm clock
         mAlarmClockIconData = IconData.makeIcon(
@@ -522,7 +498,7 @@
         mVolumeIcon = service.addIcon(mVolumeData, null);
         service.setIconVisibility(mVolumeIcon, false);
         updateVolume();
-        
+
         IntentFilter filter = new IntentFilter();
 
         // Register for Intent broadcasts for...
@@ -642,7 +618,7 @@
         }
     }
 
-    private void showBatteryView() {    
+    private void showBatteryView() {
         closeLastBatteryView();
         if (mLowBatteryDialog != null) {
             mLowBatteryDialog.dismiss();
@@ -723,7 +699,7 @@
                 b.setView(v);
                 b.setIcon(android.R.drawable.ic_dialog_alert);
                 b.setPositiveButton(android.R.string.ok, null);
-                
+
                 final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
                 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                         | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
@@ -811,6 +787,10 @@
         @Override
         public void onCallStateChanged(int state, String incomingNumber) {
             updateCallState(state);
+            // In cdma, if a voice call is made, RSSI should switch to 1x.
+            if (isCdma()) {
+                updateSignalStrength();
+            }
         }
 
         @Override
@@ -839,7 +819,7 @@
             final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
             if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
                 mSimState = IccCard.State.PIN_REQUIRED;
-            } 
+            }
             else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
                 mSimState = IccCard.State.PUK_REQUIRED;
             }
@@ -856,6 +836,14 @@
         return ((mPhone != null) && (mPhone.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA));
     }
 
+    private boolean isEvdo() {
+        return ( (mServiceState != null)
+                 && ((mServiceState.getRadioTechnology()
+                        == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
+                     || (mServiceState.getRadioTechnology()
+                        == ServiceState.RADIO_TECHNOLOGY_EVDO_A)));
+    }
+
     private boolean hasService() {
         if (mServiceState != null) {
             switch (mServiceState.getState()) {
@@ -872,9 +860,7 @@
 
     private final void updateSignalStrength() {
         int iconLevel = -1;
-        int evdoIconLevel = -1;
         int[] iconList;
-        int[] evdoIconList;
 
         if (!hasService()) {
             //Log.d(TAG, "updateSignalStrength: no service");
@@ -885,7 +871,6 @@
                 mPhoneData.iconId = com.android.internal.R.drawable.stat_sys_signal_null;
             }
             mService.updateIcon(mPhoneIcon, mPhoneData, null);
-            mService.setIconVisibility(mPhoneEvdoIcon,false);
             return;
         }
 
@@ -908,64 +893,67 @@
                 iconList = sSignalImages;
             }
         } else {
-            iconList = this.sSignalImages_cdma;
+            iconList = this.sSignalImages;
 
-            int cdmaDbm = mSignalStrength.getCdmaDbm();
-            int cdmaEcio = mSignalStrength.getCdmaEcio();
-            int levelDbm = 0;
-            int levelEcio = 0;
-
-            if (cdmaDbm >= -75) levelDbm = 4;
-            else if (cdmaDbm >= -85) levelDbm = 3;
-            else if (cdmaDbm >= -95) levelDbm = 2;
-            else if (cdmaDbm >= -100) levelDbm = 1;
-            else levelDbm = 0;
-
-            // Ec/Io are in dB*10
-            if (cdmaEcio >= -90) levelEcio = 4;
-            else if (cdmaEcio >= -110) levelEcio = 3;
-            else if (cdmaEcio >= -130) levelEcio = 2;
-            else if (cdmaEcio >= -150) levelEcio = 1;
-            else levelEcio = 0;
-
-            iconLevel = (levelDbm < levelEcio) ? levelDbm : levelEcio;
+            // If 3G(EV) and 1x network are available than 3G should be
+            // displayed, displayed RSSI should be from the EV side.
+            // If a voice call is made then RSSI should switch to 1x.
+            if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
+                iconLevel = getEvdoLevel();
+                if (false) {
+                    Log.d(TAG, "use Evdo level=" + iconLevel + " to replace Cdma Level=" + getCdmaLevel());
+                }
+            } else {
+                iconLevel = getCdmaLevel();
+            }
         }
-
-        if ((mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
-                  || (mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_A)) {
-            // Use Evdo icon
-            evdoIconList = this.sSignalImages_evdo;
-
-            int evdoDbm = mSignalStrength.getEvdoDbm();
-            int evdoSnr = mSignalStrength.getEvdoSnr();
-            int levelEvdoDbm = 0;
-            int levelEvdoSnr = 0;
-
-            if (evdoDbm >= -65) levelEvdoDbm = 4;
-            else if (evdoDbm >= -75) levelEvdoDbm = 3;
-            else if (evdoDbm >= -90) levelEvdoDbm = 2;
-            else if (evdoDbm >= -105) levelEvdoDbm = 1;
-            else levelEvdoDbm = 0;
-
-            if (evdoSnr > 7) levelEvdoSnr = 4;
-            else if (evdoSnr > 5) levelEvdoSnr = 3;
-            else if (evdoSnr > 3) levelEvdoSnr = 2;
-            else if (evdoSnr > 1) levelEvdoSnr = 1;
-            else levelEvdoSnr = 0;
-
-            evdoIconLevel = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
-
-            mPhoneEvdoData.iconId = evdoIconList[evdoIconLevel];
-            mService.updateIcon(mPhoneEvdoIcon, mPhoneEvdoData, null);
-            mService.setIconVisibility(mPhoneEvdoIcon,true);
-        } else {
-            mService.setIconVisibility(mPhoneEvdoIcon,false);
-        }
-
         mPhoneData.iconId = iconList[iconLevel];
         mService.updateIcon(mPhoneIcon, mPhoneData, null);
     }
 
+    private int getCdmaLevel() {
+        final int cdmaDbm = mSignalStrength.getCdmaDbm();
+        final int cdmaEcio = mSignalStrength.getCdmaEcio();
+        int levelDbm = 0;
+        int levelEcio = 0;
+
+        if (cdmaDbm >= -75) levelDbm = 4;
+        else if (cdmaDbm >= -85) levelDbm = 3;
+        else if (cdmaDbm >= -95) levelDbm = 2;
+        else if (cdmaDbm >= -100) levelDbm = 1;
+        else levelDbm = 0;
+
+        // Ec/Io are in dB*10
+        if (cdmaEcio >= -90) levelEcio = 4;
+        else if (cdmaEcio >= -110) levelEcio = 3;
+        else if (cdmaEcio >= -130) levelEcio = 2;
+        else if (cdmaEcio >= -150) levelEcio = 1;
+        else levelEcio = 0;
+
+        return (levelDbm < levelEcio) ? levelDbm : levelEcio;
+    }
+
+    private int getEvdoLevel() {
+        int evdoDbm = mSignalStrength.getEvdoDbm();
+        int evdoSnr = mSignalStrength.getEvdoSnr();
+        int levelEvdoDbm = 0;
+        int levelEvdoSnr = 0;
+
+        if (evdoDbm >= -65) levelEvdoDbm = 4;
+        else if (evdoDbm >= -75) levelEvdoDbm = 3;
+        else if (evdoDbm >= -90) levelEvdoDbm = 2;
+        else if (evdoDbm >= -105) levelEvdoDbm = 1;
+        else levelEvdoDbm = 0;
+
+        if (evdoSnr > 7) levelEvdoSnr = 4;
+        else if (evdoSnr > 5) levelEvdoSnr = 3;
+        else if (evdoSnr > 3) levelEvdoSnr = 2;
+        else if (evdoSnr > 1) levelEvdoSnr = 1;
+        else levelEvdoSnr = 0;
+
+        return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
+    }
+
     private final void updateDataNetType() {
         int net = mPhone.getNetworkType();
 
diff --git a/test-runner/android/test/AndroidTestRunner.java b/test-runner/android/test/AndroidTestRunner.java
index 0d4e1e9..358b7e9 100644
--- a/test-runner/android/test/AndroidTestRunner.java
+++ b/test-runner/android/test/AndroidTestRunner.java
@@ -180,14 +180,23 @@
     private void setInstrumentationIfInstrumentationTestCase(
             Test test, Instrumentation instrumentation) {
         if (InstrumentationTestCase.class.isAssignableFrom(test.getClass())) {
-            ((InstrumentationTestCase) test).injectInsrumentation(instrumentation);
+            ((InstrumentationTestCase) test).injectInstrumentation(instrumentation);
         }
     }
 
-    public void setInstrumentaiton(Instrumentation instrumentation) {
+    public void setInstrumentation(Instrumentation instrumentation) {
         mInstrumentation = instrumentation;
     }
 
+    /**
+     * @deprecated Incorrect spelling,
+     * use {@link #setInstrumentation(android.app.Instrumentation)} instead.
+     */
+    @Deprecated
+    public void setInstrumentaiton(Instrumentation instrumentation) {
+        setInstrumentation(instrumentation);
+    }
+
     @Override
     protected Class loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
         return mContext.getClassLoader().loadClass(suiteClassName);
diff --git a/test-runner/android/test/InstrumentationTestRunner.java b/test-runner/android/test/InstrumentationTestRunner.java
index 6658fb0..23f0ed4 100644
--- a/test-runner/android/test/InstrumentationTestRunner.java
+++ b/test-runner/android/test/InstrumentationTestRunner.java
@@ -329,7 +329,7 @@
 
         mTestRunner = getAndroidTestRunner();
         mTestRunner.setContext(getTargetContext());
-        mTestRunner.setInstrumentaiton(this);
+        mTestRunner.setInstrumentation(this);
         mTestRunner.setSkipExecution(logOnly);
         mTestRunner.setTest(testSuiteBuilder.build());
         mTestCount = mTestRunner.getTestCases().size();