Merge change 27177 into eclair

* changes:
  Add auto-brightness mode to the list of backed-up settings
diff --git a/api/current.xml b/api/current.xml
index 54cff8d..b430e2c 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -41626,6 +41626,19 @@
 <parameter name="appInfo" type="android.content.pm.ApplicationInfo">
 </parameter>
 </method>
+<method name="hasSystemFeature"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</method>
 <method name="isSafeMode"
  return="boolean"
  abstract="true"
@@ -131377,6 +131390,19 @@
 <parameter name="appInfo" type="android.content.pm.ApplicationInfo">
 </parameter>
 </method>
+<method name="hasSystemFeature"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</method>
 <method name="isSafeMode"
  return="boolean"
  abstract="false"
@@ -196869,7 +196895,7 @@
  abstract="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <constructor name="AllocationLimitError"
@@ -197075,7 +197101,7 @@
  abstract="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <constructor name="PotentialDeadlockError"
@@ -197102,7 +197128,7 @@
  abstract="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <constructor name="StaleDexCacheError"
@@ -197129,7 +197155,7 @@
  abstract="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <constructor name="TemporaryDirectory"
@@ -197172,7 +197198,7 @@
  abstract="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <constructor name="TouchDex"
@@ -197215,7 +197241,7 @@
  abstract="false"
  static="false"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <method name="dumpHprofData"
@@ -197719,7 +197745,7 @@
  abstract="false"
  static="false"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <method name="gcSoftReferences"
@@ -197820,7 +197846,7 @@
  abstract="false"
  static="false"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <constructor name="VMStack"
@@ -197887,7 +197913,7 @@
  abstract="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <method name="fork"
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index b877098..79eb310b 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -18,6 +18,7 @@
 
 import android.content.ComponentName;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDeleteObserver;
 import android.content.pm.IPackageInstallObserver;
 import android.content.pm.IPackageManager;
@@ -137,6 +138,7 @@
      * pm list [package | packages]
      * pm list permission-groups
      * pm list permissions
+     * pm list features
      * pm list instrumentation
      */
     private void runList() {
@@ -152,6 +154,8 @@
             runListPermissionGroups();
         } else if ("permissions".equals(type)) {
             runListPermissions();
+        } else if ("features".equals(type)) {
+            runListFeatures();
         } else if ("instrumentation".equals(type)) {
             runListInstrumentation();
         } else {
@@ -205,6 +209,44 @@
     }
 
     /**
+     * Lists all of the features supported by the current device.
+     *
+     * pm list features
+     */
+    private void runListFeatures() {
+        try {
+            List<FeatureInfo> list = new ArrayList<FeatureInfo>();
+            FeatureInfo[] rawList = mPm.getSystemAvailableFeatures();
+            for (int i=0; i<rawList.length; i++) {
+                list.add(rawList[i]);
+            }
+                    
+
+            // Sort by name
+            Collections.sort(list, new Comparator<FeatureInfo>() {
+                public int compare(FeatureInfo o1, FeatureInfo o2) {
+                    if (o1.name == o2.name) return 0;
+                    if (o1.name == null) return -1;
+                    if (o2.name == null) return 1;
+                    return o1.name.compareTo(o2.name);
+                }
+            });
+
+            int count = (list != null) ? list.size() : 0;
+            for (int p = 0; p < count; p++) {
+                FeatureInfo fi = list.get(p);
+                System.out.print("feature:");
+                if (fi.name != null) System.out.println(fi.name);
+                else System.out.println("reqGlEsVersion=0x"
+                        + Integer.toHexString(fi.reqGlEsVersion));
+            }
+        } catch (RemoteException e) {
+            System.err.println(e.toString());
+            System.err.println(PM_NOT_RUNNING_ERR);
+        }
+    }
+
+    /**
      * Lists all of the installed instrumentation, or all for a given package
      *
      * pm list instrumentation [package] [-f]
@@ -778,6 +820,7 @@
         System.err.println("       pm list permission-groups");
         System.err.println("       pm list permissions [-g] [-f] [-d] [-u] [GROUP]");
         System.err.println("       pm list instrumentation [-f] [TARGET-PACKAGE]");
+        System.err.println("       pm list features");
         System.err.println("       pm path PACKAGE");
         System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] PATH");
         System.err.println("       pm uninstall [-k] PACKAGE");
@@ -802,6 +845,8 @@
         System.err.println("or only those that target a specified package.  Options:");
         System.err.println("  -f: see their associated file.");
         System.err.println("");
+        System.err.println("The list features command prints all features of the system.");
+        System.err.println("");
         System.err.println("The path command prints the path to the .apk of a package.");
         System.err.println("");
         System.err.println("The install command installs a package to the system.  Options:");
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 2bb8480..9095ec9 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3020,9 +3020,9 @@
      * or {@link #finish} to specify an explicit transition animation to
      * perform next.
      * @param enterAnim A resource ID of the animation resource to use for
-     * the incoming activity.
+     * the incoming activity.  Use 0 for no animation.
      * @param exitAnim A resource ID of the animation resource to use for
-     * the outgoing activity.
+     * the outgoing activity.  Use 0 for no animation.
      */
     public void overridePendingTransition(int enterAnim, int exitAnim) {
         try {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 65d6eb9..76a133b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2951,8 +2951,8 @@
 
             // The window is now visible if it has been added, we are not
             // simply finishing, and we are not starting another activity.
-            if (!r.activity.mFinished && r.activity.mDecor != null
-                    && !r.hideForNow) {
+            if (!r.activity.mFinished && !a.mStartedActivity
+                    && r.activity.mDecor != null && !r.hideForNow) {
                 if (r.newConfig != null) {
                     performConfigurationChanged(r.activity, r.newConfig);
                     r.newConfig = null;
@@ -2966,9 +2966,11 @@
                     l.softInputMode = (l.softInputMode
                             & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                             | forwardBit;
-                    ViewManager wm = a.getWindowManager();
-                    View decor = r.window.getDecorView();
-                    wm.updateViewLayout(decor, l);
+                    if (r.activity.mVisibleFromClient) {
+                        ViewManager wm = a.getWindowManager();
+                        View decor = r.window.getDecorView();
+                        wm.updateViewLayout(decor, l);
+                    }
                 }
                 r.activity.mVisibleFromServer = true;
                 mNumVisibleActivities++;
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index 8896015..0582e34 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -1686,6 +1686,15 @@
         }
         
         @Override
+        public boolean hasSystemFeature(String name) {
+            try {
+                return mPM.hasSystemFeature(name);
+            } catch (RemoteException e) {
+                throw new RuntimeException("Package manager has died", e);
+            }
+        }
+        
+        @Override
         public int checkPermission(String permName, String pkgName) {
             try {
                 return mPM.checkPermission(permName, pkgName);
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 1c61324d..6181a07 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -2092,6 +2092,7 @@
             clickIntent.setClassName("com.android.providers.subscribedfeeds",
                     "com.android.settings.SyncActivityTooManyDeletes");
             clickIntent.putExtra("account", account);
+            clickIntent.putExtra("authority", authority);
             clickIntent.putExtra("provider", authorityName.toString());
             clickIntent.putExtra("numDeletes", numDeletes);
 
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c322951..fc6538f 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -283,6 +283,8 @@
      */
     FeatureInfo[] getSystemAvailableFeatures();
 
+    boolean hasSystemFeature(String name);
+    
     void enterSafeMode();
     boolean isSafeMode();
     void systemReady();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 825eb85..cd48dcb 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -995,11 +995,19 @@
      * 
      * @return An array of FeatureInfo classes describing the features
      * that are available on the system, or null if there are none(!!).
-     * 
      */
     public abstract FeatureInfo[] getSystemAvailableFeatures();
 
     /**
+     * Check whether the given feature name is one of the available
+     * features as returned by {@link #getSystemAvailableFeatures()}.
+     * 
+     * @return Returns true if the devices supports the feature, else
+     * false.
+     */
+    public abstract boolean hasSystemFeature(String name);
+
+    /**
      * Determine the best action to perform for a given Intent.  This is how
      * {@link Intent#resolveActivity} finds an activity if a class has not
      * been explicitly specified.
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index d8db4c1..709766b 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -157,7 +157,8 @@
                             // if we're not enabled but the APN Type is supported by this connection
                             // we should record the interface name if one's provided.  If the user
                             // turns on this network we will need the interfacename but won't get
-                            // a fresh connected message - TODO fix this..
+                            // a fresh connected message - TODO fix this when we get per-APN
+                            // notifications
                             if (state == Phone.DataState.CONNECTED) {
                                 if (DBG) Log.d(TAG, "replacing old mInterfaceName (" +
                                         mInterfaceName + ") with " +
@@ -186,10 +187,13 @@
                                 if (mInterfaceName != null) {
                                     NetworkUtils.resetConnections(mInterfaceName);
                                 }
-                                if (DBG) Log.d(TAG, "clearing mInterfaceName for "+ mApnType +
-                                        " as it DISCONNECTED");
-                                mInterfaceName = null;
-                                mDefaultGatewayAddr = 0;
+                                // can't do this here - ConnectivityService needs it to clear stuff
+                                // it's ok though - just leave it to be refreshed next time
+                                // we connect.
+                                //if (DBG) Log.d(TAG, "clearing mInterfaceName for "+ mApnType +
+                                //        " as it DISCONNECTED");
+                                //mInterfaceName = null;
+                                //mDefaultGatewayAddr = 0;
                                 break;
                             case CONNECTING:
                                 setDetailedState(DetailedState.CONNECTING, reason, apnName);
@@ -310,6 +314,11 @@
      */
     @Override
     public boolean teardown() {
+        // since we won't get a notification currently (TODO - per APN notifications)
+        // we won't get a disconnect message until all APN's on the current connection's
+        // APN list are disabled.  That means privateRoutes for DNS and such will remain on -
+        // not a problem since that's all shared with whatever other APN is still on, but
+        // ugly.
         setTeardownRequested(true);
         return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED);
     }
@@ -321,6 +330,7 @@
         setTeardownRequested(false);
         switch (setEnableApn(mApnType, true)) {
             case Phone.APN_ALREADY_ACTIVE:
+                // TODO - remove this when we get per-apn notifications
                 mEnabled = true;
                 // need to set self to CONNECTING so the below message is handled.
                 mMobileDataState = Phone.DataState.CONNECTING;
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 54529ae..d3e4ea5 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -124,11 +124,12 @@
 
     public void addPrivateDnsRoutes() {
         if (DBG) Log.d(TAG, "addPrivateDnsRoutes for " + this +
-                "(" + mInterfaceName + ")");
+                "(" + mInterfaceName + ") - mPrivateDnsRouteSet = "+mPrivateDnsRouteSet);
         if (mInterfaceName != null && !mPrivateDnsRouteSet) {
             for (String addrString : getNameServers()) {
                 int addr = NetworkUtils.lookupHost(addrString);
-                if (addr != -1) {
+                if (addr != -1 && addr != 0) {
+                    if (DBG) Log.d(TAG, "  adding "+addrString+" ("+addr+")");
                     NetworkUtils.addHostRoute(mInterfaceName, addr);
                 }
             }
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index b4778fe..b9f78a1 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -146,6 +146,9 @@
          * <li> The {@link android.app.Activity} class will now execute back
          * key presses on the key up instead of key down, to be able to detect
          * canceled presses from virtual keys.
+         * <li> The {@link android.widget.TabWidget} class will use a new color scheme
+         * for tabs. In the new scheme, the foreground tab has a medium gray background
+         * the background tabs have a dark gray background.
          * </ul>
          */
         public static final int ECLAIR = CUR_DEVELOPMENT;
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index e32d3ad..cd03869 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -434,29 +434,6 @@
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact";
 
         /**
-         * An optional query parameter added to {@link Groups#CONTENT_URI} or
-         * {@link Settings#CONTENT_URI} signaling that any update of
-         * {@link Contacts#STARRED} should not be triggered based on
-         * {@link Groups#GROUP_VISIBLE} or {@link Settings#UNGROUPED_VISIBLE}
-         * during the current update. Callers should follow-up with a separate
-         * update using {@link #FORCE_STARRED_UPDATE} to ensure that
-         * {@link Contacts#STARRED} remains consistent.
-         *
-         * @hide
-         */
-        public static final String DELAY_STARRED_UPDATE = "delay_update";
-
-        /**
-         * An optional query parameter added to {@link Groups#CONTENT_URI} or
-         * {@link Settings#CONTENT_URI} signaling that a full update of
-         * {@link Contacts#STARRED} should be triggered. This is usually only
-         * needed after using {@link #DELAY_STARRED_UPDATE}.
-         *
-         * @hide
-         */
-        public static final String FORCE_STARRED_UPDATE = "force_update";
-
-        /**
          * A sub-directory of a single contact that contains all of the constituent raw contact
          * {@link Data} rows.
          */
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index b2f0c60..ca907af 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -1104,13 +1104,13 @@
         final int NS = mNumSamples;
         final int NI = NP*NS;
         final int ND = NI * NUM_SAMPLE_DATA;
-        if (data.length <= ND) {
+        if (data.length < (ND+(NP*NUM_SAMPLE_DATA))) {
             final int NEW_ND = ND + (NP * (BASE_AVAIL_SAMPLES * NUM_SAMPLE_DATA));
             float[] newData = new float[NEW_ND];
             System.arraycopy(data, 0, newData, 0, ND);
             mDataSamples = data = newData;
         }
-        if (times.length <= NS) {
+        if (times.length < (NS+1)) {
             final int NEW_NS = NS + BASE_AVAIL_SAMPLES;
             long[] newHistoryTimes = new long[NEW_NS];
             System.arraycopy(times, 0, newHistoryTimes, 0, NS);
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index ee3b91e..31920e7 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -28,11 +29,12 @@
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.Window;
-import com.android.internal.R;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import com.android.internal.R;
+
 /**
  * Container for a tabbed window view. This object holds two children: a set of tab labels that the
  * user clicks to select a specific tab, and a FrameLayout object that displays the contents of that
@@ -497,17 +499,22 @@
         }
 
         public View createIndicatorView() {
+            final Context context = getContext();
             LayoutInflater inflater =
-                    (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+                    (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
             View tabIndicator = inflater.inflate(R.layout.tab_indicator,
                     mTabWidget, // tab widget is the parent
                     false); // no inflate params
-            // TODO: Move this to xml when bug 2068024 is resolved.
-            tabIndicator.getBackground().setDither(true);
 
             final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
             tv.setText(mLabel);
 
+            if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
+                // Donut apps get old color scheme
+                tabIndicator.setBackgroundResource(R.drawable.tab_indicator_v4);
+                tv.setTextColor(context.getResources().getColorStateList(R.color.tab_indicator_text_v4));
+            }
+            
             return tabIndicator;
         }
     }
@@ -526,13 +533,12 @@
         }
 
         public View createIndicatorView() {
+            final Context context = getContext();
             LayoutInflater inflater =
-                    (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+                    (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
             View tabIndicator = inflater.inflate(R.layout.tab_indicator,
                     mTabWidget, // tab widget is the parent
                     false); // no inflate params
-            // TODO: Move this to xml when bug 2068024 is resolved.
-            tabIndicator.getBackground().setDither(true);
 
             final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
             tv.setText(mLabel);
@@ -540,6 +546,12 @@
             final ImageView iconView = (ImageView) tabIndicator.findViewById(R.id.icon);
             iconView.setImageDrawable(mIcon);
 
+            if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
+                // Donut apps get old color scheme
+                tabIndicator.setBackgroundResource(R.drawable.tab_indicator_v4);
+                tv.setTextColor(context.getResources().getColorStateList(R.color.tab_indicator_text_v4));
+            }
+            
             return tabIndicator;
         }
     }
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 889f37f..2ba6268 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -16,11 +16,15 @@
 
 package android.widget;
 
+import com.android.internal.R;
+
 import android.content.Context;
+import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.View;
@@ -94,10 +98,24 @@
         setOrientation(LinearLayout.HORIZONTAL);
         mGroupFlags |= FLAG_USE_CHILD_DRAWING_ORDER;
 
-        mBottomLeftStrip = mContext.getResources().getDrawable(
-                com.android.internal.R.drawable.tab_bottom_left);
-        mBottomRightStrip = mContext.getResources().getDrawable(
-                com.android.internal.R.drawable.tab_bottom_right);
+        final Context context = mContext;
+        final Resources resources = context.getResources();
+        
+        if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
+            // Donut apps get old color scheme
+            mBottomLeftStrip = resources.getDrawable(
+                    com.android.internal.R.drawable.tab_bottom_left_v4);
+            mBottomRightStrip = resources.getDrawable(
+                    com.android.internal.R.drawable.tab_bottom_right_v4); 
+        } else {
+            // Use modern color scheme for Eclair and beyond
+            mBottomLeftStrip = resources.getDrawable(
+                    com.android.internal.R.drawable.tab_bottom_left);
+            mBottomRightStrip = resources.getDrawable(
+                    com.android.internal.R.drawable.tab_bottom_right); 
+        }
+
+
         // Deal with focus, as we don't want the focus to go by default
         // to a tab other than the current tab
         setFocusable(true);
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index d758291..86ee3dbc7 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -16,13 +16,14 @@
 
 package com.android.internal.widget;
 
+import com.android.internal.R;
+
 import android.Manifest;
 import android.content.AsyncQueryHandler;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
-import android.content.Intent;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -31,13 +32,13 @@
 import android.os.SystemClock;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.Intents;
 import android.provider.ContactsContract.PhoneLookup;
 import android.provider.ContactsContract.Presence;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Photo;
-import android.provider.SocialContract.Activities;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -47,8 +48,6 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import com.android.internal.R;
-
 /**
  * Header used across system for displaying a title bar with contact info. You
  * can bind specific values on the header, or use helper methods like
@@ -57,8 +56,7 @@
  * The parent must request the {@link Manifest.permission#READ_CONTACTS}
  * permission to access contact data.
  */
-public class ContactHeaderWidget extends FrameLayout implements View.OnClickListener,
-        View.OnLongClickListener {
+public class ContactHeaderWidget extends FrameLayout implements View.OnClickListener {
 
     private static final String TAG = "ContactHeaderWidget";
 
@@ -69,6 +67,7 @@
     private FasttrackBadgeWidget mPhotoView;
     private ImageView mPresenceView;
     private TextView mStatusView;
+    private TextView mStatusDateView;
     private int mNoPhotoResource;
     private QueryHandler mQueryHandler;
 
@@ -82,37 +81,36 @@
      * Interface for callbacks invoked when the user interacts with a header.
      */
     public interface ContactHeaderListener {
-        public void onPhotoLongClick(View view);
-        public void onDisplayNameLongClick(View view);
+        public void onPhotoClick(View view);
+        public void onDisplayNameClick(View view);
     }
 
     private ContactHeaderListener mListener;
 
-    //Projection used for the summary info in the header.
-    protected static final String[] HEADER_PROJECTION = new String[] {
-        Contacts.DISPLAY_NAME,
-        Contacts.STARRED,
-        Contacts.PHOTO_ID,
-        Contacts.PRESENCE_STATUS,
-        Contacts._ID,
-        Contacts.LOOKUP_KEY,
-    };
-    protected static final int HEADER_DISPLAY_NAME_COLUMN_INDEX = 0;
-    //TODO: We need to figure out how we're going to get the phonetic name.
-    //static final int HEADER_PHONETIC_NAME_COLUMN_INDEX
-    protected static final int HEADER_STARRED_COLUMN_INDEX = 1;
-    protected static final int HEADER_PHOTO_ID_COLUMN_INDEX = 2;
-    protected static final int HEADER_PRESENCE_STATUS_COLUMN_INDEX = 3;
-    protected static final int HEADER_CONTACT_ID_COLUMN_INDEX = 4;
-    protected static final int HEADER_LOOKUP_KEY_COLUMN_INDEX = 5;
 
-    //Projection used for finding the most recent social status.
-    protected static final String[] SOCIAL_PROJECTION = new String[] {
-        Activities.TITLE,
-        Activities.PUBLISHED,
-    };
-    protected static final int SOCIAL_TITLE_COLUMN_INDEX = 0;
-    protected static final int SOCIAL_PUBLISHED_COLUMN_INDEX = 1;
+    private interface ContactQuery {
+        //Projection used for the summary info in the header.
+        String[] COLUMNS = new String[] {
+            Contacts._ID,
+            Contacts.LOOKUP_KEY,
+            Contacts.PHOTO_ID,
+            Contacts.DISPLAY_NAME,
+            Contacts.STARRED,
+            Contacts.PRESENCE_STATUS,
+            Contacts.PRESENCE_CUSTOM_STATUS,
+            Contacts.PRESENCE_CUSTOM_STATUS_TIMESTAMP,
+        };
+        int _ID = 0;
+        int LOOKUP_KEY = 1;
+        int PHOTO_ID = 2;
+        int DISPLAY_NAME = 3;
+        //TODO: We need to figure out how we're going to get the phonetic name.
+        //static final int HEADER_PHONETIC_NAME_COLUMN_INDEX
+        int STARRED = 4;
+        int PRESENCE_STATUS = 5;
+        int PRESENCE_CUSTOM_STATUS = 6;
+        int PRESENCE_CUSTOM_STATUS_TIMESTAMP = 7;
+    }
 
     //Projection used for looking up contact id from phone number
     protected static final String[] PHONE_LOOKUP_PROJECTION = new String[] {
@@ -136,10 +134,8 @@
     protected static final int CONTACT_LOOKUP_ID_COLUMN_INDEX = 0;
 
     private static final int TOKEN_CONTACT_INFO = 0;
-    private static final int TOKEN_SOCIAL = 1;
-    private static final int TOKEN_PHONE_LOOKUP = 2;
-    private static final int TOKEN_EMAIL_LOOKUP = 3;
-    private static final int TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY = 4;
+    private static final int TOKEN_PHONE_LOOKUP = 1;
+    private static final int TOKEN_EMAIL_LOOKUP = 2;
 
     public ContactHeaderWidget(Context context) {
         this(context, null);
@@ -159,7 +155,6 @@
         inflater.inflate(R.layout.contact_header, this);
 
         mDisplayNameView = (TextView) findViewById(R.id.name);
-        mDisplayNameView.setOnLongClickListener(this);
         mAggregateBadge = findViewById(R.id.aggregate_badge);
         mAggregateBadge.setVisibility(View.GONE);
 
@@ -169,11 +164,11 @@
         mStarredView.setOnClickListener(this);
 
         mPhotoView = (FasttrackBadgeWidget) findViewById(R.id.photo);
-        mPhotoView.setOnLongClickListener(this);
 
         mPresenceView = (ImageView) findViewById(R.id.presence);
 
         mStatusView = (TextView)findViewById(R.id.status);
+        mStatusDateView = (TextView)findViewById(R.id.status_date);
 
         // Set the photo with a random "no contact" image
         long now = SystemClock.elapsedRealtime();
@@ -192,6 +187,11 @@
         mQueryHandler = new QueryHandler(mContentResolver);
     }
 
+    public void enableClickListeners() {
+        mDisplayNameView.setOnClickListener(this);
+        mPhotoView.setOnClickListener(this);
+    }
+
     /**
      * Set the given {@link ContactHeaderListener} to handle header events.
      */
@@ -199,28 +199,15 @@
         mListener = listener;
     }
 
-    /** {@inheritDoc} */
-    public boolean onLongClick(View v) {
-        switch (v.getId()) {
-            case R.id.photo:
-                performPhotoLongClick();
-                return true;
-            case R.id.name:
-                performDisplayNameLongClick();
-                return true;
-        }
-        return false;
-    }
-
-    private void performPhotoLongClick() {
+    private void performPhotoClick() {
         if (mListener != null) {
-            mListener.onPhotoLongClick(mPhotoView);
+            mListener.onPhotoClick(mPhotoView);
         }
     }
 
-    private void performDisplayNameLongClick() {
+    private void performDisplayNameClick() {
         if (mListener != null) {
-            mListener.onDisplayNameLongClick(mDisplayNameView);
+            mListener.onDisplayNameClick(mDisplayNameView);
         }
     }
 
@@ -239,11 +226,6 @@
                         invalidate();
                         break;
                     }
-                    case TOKEN_SOCIAL: {
-                        bindSocial(cursor);
-                        invalidate();
-                        break;
-                    }
                     case TOKEN_PHONE_LOOKUP: {
                         if (cursor != null && cursor.moveToFirst()) {
                             long contactId = cursor.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX);
@@ -270,13 +252,6 @@
                         }
                         break;
                     }
-                    case TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY: {
-                        if (cursor != null && cursor.moveToFirst()) {
-                            long contactId = cursor.getLong(CONTACT_LOOKUP_ID_COLUMN_INDEX);
-                            startSocialQuery(ContentUris.withAppendedId(
-                                    Activities.CONTENT_CONTACT_STATUS_URI, contactId));
-                        }
-                    }
                 }
             } finally {
                 if (cursor != null) {
@@ -355,7 +330,12 @@
      * Manually set the social snippet text to display in the header.
      */
     public void setSocialSnippet(CharSequence snippet) {
-        mStatusView.setText(snippet);
+        if (snippet == null) {
+            mStatusView.setVisibility(View.GONE);
+        } else {
+            mStatusView.setText(snippet);
+            mStatusView.setVisibility(View.VISIBLE);
+        }
     }
 
     /**
@@ -375,11 +355,6 @@
      */
     public void bindFromContactLookupUri(Uri contactLookupUri) {
         mContactUri = contactLookupUri;
-
-        // Query for the contactId so we can do the social query.
-        mQueryHandler.startQuery(TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY, null, contactLookupUri,
-                CONTACT_LOOKUP_PROJECTION, null, null, null);
-
         startContactQuery(contactLookupUri);
     }
 
@@ -394,8 +369,6 @@
         long contactId = ContentUris.parseId(contactUri);
 
         startContactQuery(contactUri);
-        startSocialQuery(ContentUris.withAppendedId(
-                Activities.CONTENT_CONTACT_STATUS_URI, contactId));
     }
 
     /**
@@ -426,13 +399,8 @@
                 PHONE_LOOKUP_PROJECTION, null, null, null);
     }
 
-    private void startSocialQuery(Uri contactSocial) {
-        mQueryHandler.startQuery(TOKEN_SOCIAL, null, contactSocial, SOCIAL_PROJECTION, null, null,
-                null);
-    }
-
     private void startContactQuery(Uri contactUri) {
-        mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, contactUri, HEADER_PROJECTION,
+        mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, contactUri, ContactQuery.COLUMNS,
                 null, null, null);
     }
 
@@ -443,17 +411,17 @@
         if (c == null || !c.moveToFirst()) return;
 
         // TODO: Bring back phonetic name
-        final String displayName = c.getString(HEADER_DISPLAY_NAME_COLUMN_INDEX);
-        final long contactId = c.getLong(HEADER_CONTACT_ID_COLUMN_INDEX);
-        final String lookupKey = c.getString(HEADER_LOOKUP_KEY_COLUMN_INDEX);
+        final String displayName = c.getString(ContactQuery.DISPLAY_NAME);
+        final long contactId = c.getLong(ContactQuery._ID);
+        final String lookupKey = c.getString(ContactQuery.LOOKUP_KEY);
         final String phoneticName = null;
         this.setDisplayName(displayName, null);
 
-        final boolean starred = c.getInt(HEADER_STARRED_COLUMN_INDEX) != 0;
+        final boolean starred = c.getInt(ContactQuery.STARRED) != 0;
         mStarredView.setChecked(starred);
 
         //Set the photo
-        Bitmap photoBitmap = loadContactPhoto(c.getLong(HEADER_PHOTO_ID_COLUMN_INDEX), null);
+        Bitmap photoBitmap = loadContactPhoto(c.getLong(ContactQuery.PHOTO_ID), null);
         if (photoBitmap == null) {
             photoBitmap = loadPlaceholderPhoto(null);
         }
@@ -461,43 +429,62 @@
         mPhotoView.assignContactUri(Contacts.getLookupUri(contactId, lookupKey));
 
         //Set the presence status
-        int presence = c.getInt(HEADER_PRESENCE_STATUS_COLUMN_INDEX);
-        mPresenceView.setImageResource(Presence.getPresenceIconResourceId(presence));
-    }
+        if (!c.isNull(ContactQuery.PRESENCE_STATUS)) {
+            int presence = c.getInt(ContactQuery.PRESENCE_STATUS);
+            mPresenceView.setImageResource(Presence.getPresenceIconResourceId(presence));
+            mPresenceView.setVisibility(View.VISIBLE);
+        } else {
+            mPresenceView.setVisibility(View.GONE);
+        }
 
-    /**
-     * Bind the social data provided by the given {@link Cursor}.
-     */
-    protected void bindSocial(Cursor c) {
-        if (c == null || !c.moveToFirst()) return;
-        final String status = c.getString(SOCIAL_TITLE_COLUMN_INDEX);
-        this.setSocialSnippet(status);
+        //Set the status update
+        String status = c.getString(ContactQuery.PRESENCE_CUSTOM_STATUS);
+        if (!TextUtils.isEmpty(status)) {
+            mStatusView.setText(status);
+            mStatusView.setVisibility(View.VISIBLE);
+
+            if (!c.isNull(ContactQuery.PRESENCE_CUSTOM_STATUS_TIMESTAMP)) {
+                long date = c.getLong(ContactQuery.PRESENCE_CUSTOM_STATUS_TIMESTAMP);
+
+                // Set the date/time field by mixing relative and absolute
+                // times.
+                int flags = DateUtils.FORMAT_ABBREV_RELATIVE;
+
+                mStatusDateView.setText(DateUtils.getRelativeTimeSpanString(date, System
+                        .currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, flags));
+                mStatusDateView.setVisibility(View.VISIBLE);
+            } else {
+                mStatusDateView.setVisibility(View.GONE);
+            }
+        } else {
+            mStatusView.setVisibility(View.GONE);
+            mStatusDateView.setVisibility(View.GONE);
+        }
+
+        // TODO add support for status update source, e.g. "via Google Talk"
     }
 
     public void onClick(View view) {
-        // Make sure there is a contact
-        if (mContactUri == null) {
-            return;
+        switch (view.getId()) {
+            case R.id.star: {
+                // Toggle "starred" state
+                // Make sure there is a contact
+                if (mContactUri != null) {
+                    final ContentValues values = new ContentValues(1);
+                    values.put(Contacts.STARRED, mStarredView.isChecked());
+                    mContentResolver.update(mContactUri, values, null, null);
+                }
+                break;
+            }
+            case R.id.photo: {
+                performPhotoClick();
+                break;
+            }
+            case R.id.name: {
+                performDisplayNameClick();
+                break;
+            }
         }
-
-        if (view.getId() == R.id.star) {
-            // Toggle "starred" state
-            final ContentValues values = new ContentValues(1);
-            values.put(Contacts.STARRED, mStarredView.isChecked());
-            mContentResolver.update(mContactUri, values, null, null);
-        }
-    }
-
-    private Rect getTargetRect(View anchor) {
-        final int[] location = new int[2];
-        anchor.getLocationOnScreen(location);
-
-        final Rect rect = new Rect();
-        rect.left = location[0];
-        rect.top = location[1];
-        rect.right = rect.left + anchor.getWidth();
-        rect.bottom = rect.top + anchor.getHeight();
-        return rect;
     }
 
     private Bitmap loadContactPhoto(long photoId, BitmapFactory.Options options) {
diff --git a/core/res/res/color/tab_indicator_text_v4.xml b/core/res/res/color/tab_indicator_text_v4.xml
new file mode 100644
index 0000000..4f4e394
--- /dev/null
+++ b/core/res/res/color/tab_indicator_text_v4.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:color="#808080"/>
+    <item android:color="#FFFFFF"/> <!-- not selected -->
+</selector>
diff --git a/core/res/res/drawable-hdpi/tab_selected_bar_left_v4.9.png b/core/res/res/drawable-hdpi/tab_selected_bar_left_v4.9.png
new file mode 100644
index 0000000..109bbcd
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_selected_bar_left_v4.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_selected_bar_right_v4.9.png b/core/res/res/drawable-hdpi/tab_selected_bar_right_v4.9.png
new file mode 100644
index 0000000..109bbcd
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_selected_bar_right_v4.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_selected_v4.9.png b/core/res/res/drawable-hdpi/tab_selected_v4.9.png
new file mode 100644
index 0000000..2981ea5
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_selected_v4.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_unselected_v4.9.png b/core/res/res/drawable-hdpi/tab_unselected_v4.9.png
new file mode 100644
index 0000000..7a13b8a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_unselected_v4.9.png
Binary files differ
diff --git a/core/res/res/drawable/tab_bottom_left_v4.xml b/core/res/res/drawable/tab_bottom_left_v4.xml
new file mode 100644
index 0000000..0aee288
--- /dev/null
+++ b/core/res/res/drawable/tab_bottom_left_v4.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/tab_press_bar_left"/>
+    <item android:state_focused="false" android:drawable="@drawable/tab_selected_bar_left_v4"/>
+    <item android:state_focused="true" android:drawable="@drawable/tab_focus_bar_left"/>
+</selector>
diff --git a/core/res/res/drawable/tab_bottom_right_v4.xml b/core/res/res/drawable/tab_bottom_right_v4.xml
new file mode 100644
index 0000000..64227dd
--- /dev/null
+++ b/core/res/res/drawable/tab_bottom_right_v4.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/tab_press_bar_right"/>
+    <item android:state_focused="false" android:state_pressed="false" android:drawable="@drawable/tab_selected_bar_right_v4"/>
+    <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/tab_focus_bar_right"/>
+</selector>
diff --git a/core/res/res/drawable/tab_indicator_v4.xml b/core/res/res/drawable/tab_indicator_v4.xml
new file mode 100644
index 0000000..b1e3c9c
--- /dev/null
+++ b/core/res/res/drawable/tab_indicator_v4.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- Non focused states -->
+    <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected_v4" />
+    <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_v4" />
+
+    <!-- Focused states -->
+    <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_focus" />
+    <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_focus" />
+
+    <!-- Pressed -->
+    <item android:state_pressed="true" android:drawable="@drawable/tab_press" />
+</selector>
diff --git a/core/res/res/layout-ja/contact_header_name.xml b/core/res/res/layout-ja/contact_header_name.xml
index 9dceeb6..faf1b87 100644
--- a/core/res/res/layout-ja/contact_header_name.xml
+++ b/core/res/res/layout-ja/contact_header_name.xml
@@ -4,9 +4,9 @@
      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.
@@ -20,11 +20,11 @@
     android:orientation="vertical"
     android:layout_width="0dip"
     android:layout_weight="1"
-    android:layout_height="wrap_content">
+    android:layout_height="fill_parent">
 
     <TextView android:id="@+id/name"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
         android:singleLine="true"
         android:ellipsize="end"
         android:textAppearance="?android:attr/textAppearanceMedium"
diff --git a/core/res/res/layout/contact_header.xml b/core/res/res/layout/contact_header.xml
index d19bb04..2dbc311 100644
--- a/core/res/res/layout/contact_header.xml
+++ b/core/res/res/layout/contact_header.xml
@@ -4,9 +4,9 @@
      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.
@@ -17,26 +17,25 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/banner"
     android:layout_width="fill_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="fill_parent"
     android:orientation="horizontal"
     android:background="@drawable/title_bar_medium"
-    android:paddingRight="5dip"
-    android:gravity="center_vertical">
-    
+    android:paddingRight="5dip">
+
     <android.widget.FasttrackBadgeWidget android:id="@+id/photo"
         android:layout_alignParentLeft="true"
-        android:layout_centerVertical="true"
+        android:layout_gravity="center_vertical"
         android:layout_marginRight="10dip"
         android:layout_marginLeft="10dip"
         style="@*android:style/Widget.FasttrackBadgeWidget.WindowSmall" />
     />
-    
+
     <LinearLayout
         android:layout_width="0dip"
         android:layout_height="wrap_content"
         android:layout_weight="1"
-        android:layout_marginTop="5dip"
-        android:orientation="vertical">
+        android:orientation="vertical"
+        android:layout_gravity="center_vertical" >
 
         <LinearLayout
             android:layout_width="fill_parent"
@@ -59,25 +58,36 @@
 
         <TextView android:id="@+id/status"
             android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:maxLines="1"
+            android:ellipsize="end"
+            android:layout_marginTop="-4dip"
+        />
+
+        <TextView android:id="@+id/status_date"
+            android:layout_width="fill_parent"
             android:layout_height="0dip"
             android:layout_weight="1"
             android:textAppearance="?android:attr/textAppearanceSmall"
-            android:maxLines="2"
-            android:ellipsize="end"/>
-                
+            android:textSize="12sp"
+            android:layout_marginTop="-2dip"
+        />
     </LinearLayout>
 
     <ImageView
         android:id="@+id/presence"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
         android:paddingLeft="3dip"
         android:paddingRight="6dip"/>
-        
+
     <CheckBox
         android:id="@+id/star"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
         android:visibility="gone"
         style="?android:attr/starStyle" />
 
diff --git a/core/res/res/layout/contact_header_name.xml b/core/res/res/layout/contact_header_name.xml
index 9a56fb4..a763c22 100644
--- a/core/res/res/layout/contact_header_name.xml
+++ b/core/res/res/layout/contact_header_name.xml
@@ -4,9 +4,9 @@
      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.
@@ -23,4 +23,5 @@
     android:textStyle="bold"
     android:singleLine="true"
     android:ellipsize="end"
+    android:layout_gravity="center_vertical"
     />
diff --git a/data/etc/android.hardware.touchscreen.multitouch.xml b/data/etc/android.hardware.touchscreen.multitouch.xml
new file mode 100644
index 0000000..3d2399a
--- /dev/null
+++ b/data/etc/android.hardware.touchscreen.multitouch.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<!-- This is the standard set of features for a touchscreen that supports
+     multitouch. -->
+<permissions>
+    <feature name="android.hardware.touchscreen.multitouch" />
+</permissions>
diff --git a/data/etc/required_hardware.xml b/data/etc/required_hardware.xml
index 896a148..05e7f8a 100644
--- a/data/etc/required_hardware.xml
+++ b/data/etc/required_hardware.xml
@@ -22,4 +22,5 @@
     <feature name="android.hardware.sensor.accelerometer" />
     <feature name="android.hardware.bluetooth" />
     <feature name="android.hardware.wifi" />
+    <feature name="android.hardware.touchscreen" />
 </permissions>
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
index acf6899..3158192 100644
--- a/docs/html/guide/appendix/api-levels.jd
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -7,17 +7,18 @@
   <h2>In this document</h2>
 <ol>
   <li><a href="intro">What is API Level?</a></li>
-  <li><a href="#uses">Uses of API Level</a></li>
+  <li><a href="#uses">Uses of API Level in Android</a></li>
   <li><a href="#considerations">Development Considerations</a>
     <ol>
       <li><a href="#fc">Application forward compatibility</a></li>
       <li><a href="#bc">Application backward compatibility</a></li>
-      <li><a href="#platform">Selecting a platform version for compiling</a></li>
+      <li><a href="#platform">Selecting a platform version and API Level</a></li>
       <li><a href="#apilevel">Declaring a minimum API Level</a></li>
       <li><a href="#testing">Testing against higher API Levels</a></li>
     </ol>
   </li>
-  <li><a href="#filtering">Filtering the documentation</a></li>
+  <li><a href="#provisional">Using a Provisional API Level</a></li>
+  <li><a href="#filtering">Filtering the Reference Documentation by API Level</a></li>
 </ol>
 
   <h2>See also</h2>
@@ -285,6 +286,27 @@
 a list of platform versions and their API Levels. </p>
 
 
+<h2 id="provisional">Using a Provisional API Level</h2>
+
+<p>During an "Early Look" SDK release, the APIs may not be final, so the API Level integer
+will not be specified. You must instead use a provisional API Level in your application
+manifest in order to build applications against the Early Look platform. In this case,
+the provisional API Level is not an integer, but a string matching the codename of the
+unreleased platform version (for example, "Eclair"). The provisional API Level will be specified
+in the Early Look SDK release notes and is case-sensitive.</p>
+
+<p>The use of a provisional API Level is designed to protect developers 
+and device users from inadvertently publishing or installing applications based on the 
+Early Look framework API, which may not run properly on actual devices running the final
+system image.</p>
+
+<p>The provisional API Level will only be valid while using the Early Look SDK to run
+applications in the emulator. An application using the provisional API Level can never be 
+installed on an Android device. When the final SDK is released, you must replace any
+instances of the provisional API Level in your application manifest with the final 
+API Level integer.</p>
+
+
 <h2 id="filtering">Filtering the Reference Documentation by API Level</h2>
 
 <p>Reference documentation pages on the Android Developers site offer a "Filter
diff --git a/libs/rs/java/Fountain/res/raw/fountain.c b/libs/rs/java/Fountain/res/raw/fountain.c
index 57e10cf..86f0f99 100644
--- a/libs/rs/java/Fountain/res/raw/fountain.c
+++ b/libs/rs/java/Fountain/res/raw/fountain.c
@@ -31,10 +31,11 @@
             np->b = b;
             np->a = 0xf0;
             newPart++;
+            np++;
             if (newPart >= count) {
                 newPart = 0;
+                np = &p[newPart];
             }
-            np++;
         }
     }
 
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 116afd0..cda005e 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
@@ -42,7 +42,6 @@
 
     public FountainView(Context context) {
         super(context);
-
         //setFocusable(true);
     }
 
@@ -59,11 +58,7 @@
 
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
         super.surfaceChanged(holder, format, w, h);
-
-        Log.e("rs", "surfaceChanged");
         destroyRS();
-
-
         mRS = createRenderScript(false, true);
         mRender = new FountainRS();
         mRender.init(mRS, getResources(), w, h);
@@ -71,15 +66,7 @@
 
     public void surfaceDestroyed(SurfaceHolder holder) {
         // Surface will be destroyed when we return
-        Log.v("rs", "surfaceDestroyed");
         destroyRS();
-
-        try {
-            java.lang.Thread.sleep(5000);
-        } catch(InterruptedException e) {
-
-        }
-        Runtime.getRuntime().exit(0);
     }
 
 
diff --git a/libs/rs/rsAdapter.cpp b/libs/rs/rsAdapter.cpp
index 9a3bbb1..0d31fac 100644
--- a/libs/rs/rsAdapter.cpp
+++ b/libs/rs/rsAdapter.cpp
@@ -23,11 +23,15 @@
 
 Adapter1D::Adapter1D(Context *rsc) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     reset();
 }
 
 Adapter1D::Adapter1D(Context *rsc, Allocation *a) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     reset();
     setAllocation(a);
 }
@@ -127,11 +131,15 @@
 
 Adapter2D::Adapter2D(Context *rsc) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     reset();
 }
 
 Adapter2D::Adapter2D(Context *rsc, Allocation *a) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     reset();
     setAllocation(a);
 }
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 96e128b..8ee6e5a 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -24,6 +24,8 @@
 
 Allocation::Allocation(Context *rsc, const Type *type) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mPtr = NULL;
 
     mCpuWrite = false;
diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp
index 67184ff..42e2e4f 100644
--- a/libs/rs/rsComponent.cpp
+++ b/libs/rs/rsComponent.cpp
@@ -23,6 +23,8 @@
 
 Component::Component(Context *rsc) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mType = FLOAT;
     mKind = USER;
     mIsNormalized = false;
@@ -33,6 +35,8 @@
     DataKind dk, DataType dt,
     bool isNormalized, uint32_t bits, const char * name) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mType = dt;
     mKind = dk;
     mIsNormalized = isNormalized;
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 653d427..70add92 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -269,11 +269,16 @@
      }
 
      LOGV("RS Thread exiting");
+     rsc->mRaster.clear();
+     rsc->mFragment.clear();
+     rsc->mVertex.clear();
+     rsc->mFragmentStore.clear();
+     rsc->mRootScript.clear();
+     rsc->mStateRaster.deinit(rsc);
+     rsc->mStateVertex.deinit(rsc);
+     rsc->mStateFragment.deinit(rsc);
+     rsc->mStateFragmentStore.deinit(rsc);
      ObjectBase::zeroAllUserRef(rsc);
-     rsc->mRaster.set(NULL);
-     rsc->mFragment.set(NULL);
-     rsc->mVertex.set(NULL);
-     rsc->mFragmentStore.set(NULL);
 
      glClearColor(0,0,0,0);
      glClear(GL_COLOR_BUFFER_BIT);
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index e7ae247..a00fb52 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -24,12 +24,16 @@
 
 Element::Element(Context *rsc) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mComponents = NULL;
     mComponentCount = 0;
 }
 
 Element::Element(Context *rsc, uint32_t count) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mComponents = new ObjectBaseRef<Component> [count];
     mComponentCount = count;
 }
diff --git a/libs/rs/rsLight.cpp b/libs/rs/rsLight.cpp
index e9b8ef9..6f2cf3e 100644
--- a/libs/rs/rsLight.cpp
+++ b/libs/rs/rsLight.cpp
@@ -24,6 +24,8 @@
 
 Light::Light(Context *rsc, bool isLocal, bool isMono) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mIsLocal = isLocal;
     mIsMono = isMono;
 
diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp
index 73aef62..d595b4e 100644
--- a/libs/rs/rsMesh.cpp
+++ b/libs/rs/rsMesh.cpp
@@ -24,6 +24,8 @@
 
 Mesh::Mesh(Context *rsc) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mVerticies = NULL;
     mVerticiesCount = 0;
     mPrimitives = NULL;
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index 83fa482..720e8fc 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -28,6 +28,8 @@
     mRSC = NULL;
     mNext = NULL;
     mPrev = NULL;
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     setContext(rsc);
 }
 
@@ -39,6 +41,17 @@
     remove();
 }
 
+void ObjectBase::dumpObj(const char *op) const
+{
+    if (mName) {
+        LOGV("%s RSobj %p, name %s, refs %i,%i  from %s,%i links %p,%p,%p",
+             op, this, mName, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
+    } else {
+        LOGV("%s RSobj %p, no-name, refs %i,%i  from %s,%i links %p,%p,%p",
+             op, this, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
+    }
+}
+
 void ObjectBase::setContext(Context *rsc)
 {
     if (mRSC) {
@@ -66,11 +79,7 @@
 {
     if (!(mSysRefCount | mUserRefCount)) {
         if (mRSC && mRSC->props.mLogObjects) {
-            if (mName) {
-                LOGV("Deleting RS object %p, name %s", this, mName);
-            } else {
-                LOGV("Deleting RS object %p, no name", this);
-            }
+            dumpObj("checkDelete");
         }
         delete this;
         return true;
@@ -82,14 +91,14 @@
 {
     rsAssert(mUserRefCount > 0);
     mUserRefCount --;
-    //LOGV("ObjectBase %p dec ref %i", this, mRefCount);
+    //dumpObj("decUserRef");
     return checkDelete();
 }
 
 bool ObjectBase::zeroUserRef() const
 {
     mUserRefCount = 0;
-    //LOGV("ObjectBase %p dec ref %i", this, mRefCount);
+    //dumpObj("zeroUserRef");
     return checkDelete();
 }
 
@@ -97,7 +106,7 @@
 {
     rsAssert(mSysRefCount > 0);
     mSysRefCount --;
-    //LOGV("ObjectBase %p dec ref %i", this, mRefCount);
+    //dumpObj("decSysRef");
     return checkDelete();
 }
 
@@ -174,5 +183,14 @@
             //LOGE("o next %p", o);
         }
     }
+
+    if (rsc->props.mLogObjects) {
+        LOGV("Objects remaining.");
+        o = rsc->mObjHead;
+        while (o) {
+            o->dumpObj("  ");
+            o = o->mNext;
+        }
+    }
 }
 
diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h
index be400ca..ea5e37cc 100644
--- a/libs/rs/rsObjectBase.h
+++ b/libs/rs/rsObjectBase.h
@@ -50,6 +50,12 @@
 
     static void zeroAllUserRef(Context *rsc);
 
+    void dumpObj(const char *op) const;
+
+protected:
+    const char *mAllocFile;
+    uint32_t mAllocLine;
+
 private:
     void add() const;
     void remove() const;
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index 051483f..5f2a609 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -23,10 +23,11 @@
 
 Program::Program(Context *rsc, Element *in, Element *out) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
+
     mElementIn.set(in);
     mElementOut.set(out);
-
-
 }
 
 Program::~Program()
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index 5f685ff..708a0e0 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -27,6 +27,8 @@
 ProgramFragment::ProgramFragment(Context *rsc, Element *in, Element *out, bool pointSpriteEnable) :
     Program(rsc, in, out)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
         mEnvModes[ct] = RS_TEX_ENV_MODE_REPLACE;
         mTextureDimensions[ct] = 2;
@@ -190,6 +192,12 @@
     mDefault.set(pf);
 }
 
+void ProgramFragmentState::deinit(Context *rsc)
+{
+    mDefault.clear();
+    mLast.clear();
+}
+
 
 namespace android {
 namespace renderscript {
diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h
index d783c0d..e26c6e8 100644
--- a/libs/rs/rsProgramFragment.h
+++ b/libs/rs/rsProgramFragment.h
@@ -75,6 +75,7 @@
 
     ProgramFragment *mPF;
     void init(Context *rsc, int32_t w, int32_t h);
+    void deinit(Context *rsc);
 
     ObjectBaseRef<Type> mTextureTypes[ProgramFragment::MAX_TEXTURE];
     ObjectBaseRef<ProgramFragment> mDefault;
diff --git a/libs/rs/rsProgramFragmentStore.cpp b/libs/rs/rsProgramFragmentStore.cpp
index 39802c7..de33d9c 100644
--- a/libs/rs/rsProgramFragmentStore.cpp
+++ b/libs/rs/rsProgramFragmentStore.cpp
@@ -27,6 +27,8 @@
 ProgramFragmentStore::ProgramFragmentStore(Context *rsc, Element *in, Element *out) :
     Program(rsc, in, out)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mDitherEnable = true;
     mBlendEnable = false;
     mColorRWriteEnable = true;
@@ -217,6 +219,12 @@
     mDefault.set(pfs);
 }
 
+void ProgramFragmentStoreState::deinit(Context *rsc)
+{
+    mDefault.clear();
+    mLast.clear();
+}
+
 
 namespace android {
 namespace renderscript {
diff --git a/libs/rs/rsProgramFragmentStore.h b/libs/rs/rsProgramFragmentStore.h
index b71e35f..a344387 100644
--- a/libs/rs/rsProgramFragmentStore.h
+++ b/libs/rs/rsProgramFragmentStore.h
@@ -65,6 +65,7 @@
     ProgramFragmentStoreState();
     ~ProgramFragmentStoreState();
     void init(Context *rsc, int32_t w, int32_t h);
+    void deinit(Context *rsc);
 
     ObjectBaseRef<ProgramFragmentStore> mDefault;
     ObjectBaseRef<ProgramFragmentStore> mLast;
diff --git a/libs/rs/rsProgramRaster.cpp b/libs/rs/rsProgramRaster.cpp
index 2a9c4ab..fcf6824 100644
--- a/libs/rs/rsProgramRaster.cpp
+++ b/libs/rs/rsProgramRaster.cpp
@@ -32,6 +32,8 @@
                              bool pointSprite) :
     Program(rsc, in, out)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mPointSmooth = pointSmooth;
     mLineSmooth = lineSmooth;
     mPointSprite = pointSprite;
@@ -100,6 +102,12 @@
     mDefault.set(pr);
 }
 
+void ProgramRasterState::deinit(Context *rsc)
+{
+    mDefault.clear();
+    mLast.clear();
+}
+
 
 namespace android {
 namespace renderscript {
diff --git a/libs/rs/rsProgramRaster.h b/libs/rs/rsProgramRaster.h
index da68f67..a6d5ba8 100644
--- a/libs/rs/rsProgramRaster.h
+++ b/libs/rs/rsProgramRaster.h
@@ -58,6 +58,7 @@
     ProgramRasterState();
     ~ProgramRasterState();
     void init(Context *rsc, int32_t w, int32_t h);
+    void deinit(Context *rsc);
 
     ObjectBaseRef<ProgramRaster> mDefault;
     ObjectBaseRef<ProgramRaster> mLast;
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 9eb32ff..9bfa602 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -27,6 +27,8 @@
 ProgramVertex::ProgramVertex(Context *rsc, Element *in, Element *out) :
     Program(rsc, in, out)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mTextureMatrixEnable = false;
     mLightCount = 0;
 }
@@ -139,10 +141,10 @@
 
     rsi_TypeBegin(rsc, e);
     rsi_TypeAdd(rsc, RS_DIMENSION_X, 48);
-    mAllocType = rsi_TypeCreate(rsc);
+    mAllocType.set((Type *)rsi_TypeCreate(rsc));
 
     ProgramVertex *pv = new ProgramVertex(rsc, NULL, NULL);
-    Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType);
+    Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType.get());
     mDefaultAlloc.set(alloc);
     mDefault.set(pv);
 
@@ -156,6 +158,16 @@
     alloc->subData(RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4);
 }
 
+void ProgramVertexState::deinit(Context *rsc)
+{
+    mDefaultAlloc.clear();
+    mDefault.clear();
+    mAllocType.clear();
+    mLast.clear();
+    delete mPV;
+    mPV = NULL;
+}
+
 
 namespace android {
 namespace renderscript {
diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h
index b3a8b8d..e198f23 100644
--- a/libs/rs/rsProgramVertex.h
+++ b/libs/rs/rsProgramVertex.h
@@ -59,12 +59,13 @@
     ~ProgramVertexState();
 
     void init(Context *rsc, int32_t w, int32_t h);
+    void deinit(Context *rsc);
 
     ObjectBaseRef<ProgramVertex> mDefault;
     ObjectBaseRef<ProgramVertex> mLast;
     ObjectBaseRef<Allocation> mDefaultAlloc;
 
-    RsType mAllocType;
+    ObjectBaseRef<Type> mAllocType;
 
     ProgramVertex *mPV;
 
diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp
index 99091a9..b793750 100644
--- a/libs/rs/rsSampler.cpp
+++ b/libs/rs/rsSampler.cpp
@@ -27,6 +27,8 @@
 
 Sampler::Sampler(Context *rsc) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     // Should not get called.
     rsAssert(0);
 }
@@ -38,6 +40,8 @@
                  RsSamplerValue wrapT,
                  RsSamplerValue wrapR) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mMagFilter = magFilter;
     mMinFilter = minFilter;
     mWrapS = wrapS;
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index f9526fe0..cb1436b 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -21,6 +21,8 @@
 
 Script::Script(Context *rsc) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     memset(&mEnviroment, 0, sizeof(mEnviroment));
     mEnviroment.mClearColor[0] = 0;
     mEnviroment.mClearColor[1] = 0;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index fb8180f..e63ed24 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -35,6 +35,8 @@
 
 ScriptC::ScriptC(Context *rsc) : Script(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mAccScript = NULL;
     memset(&mProgram, 0, sizeof(mProgram));
 }
diff --git a/libs/rs/rsSimpleMesh.cpp b/libs/rs/rsSimpleMesh.cpp
index fe06e0c..b082fd7 100644
--- a/libs/rs/rsSimpleMesh.cpp
+++ b/libs/rs/rsSimpleMesh.cpp
@@ -24,10 +24,14 @@
 
 SimpleMesh::SimpleMesh(Context *rsc) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
 }
 
 SimpleMesh::~SimpleMesh()
 {
+    delete[] mVertexTypes;
+    delete[] mVertexBuffers;
 }
 
 void SimpleMesh::render() const
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 010e49b..5ce9ca2 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -22,6 +22,8 @@
 
 Type::Type(Context *rsc) : ObjectBase(rsc)
 {
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
     mLODs = 0;
     mLODCount = 0;
     memset(&mGL, 0, sizeof(mGL));
@@ -372,6 +374,7 @@
     st->setDimLOD(stc->mLOD);
     st->setDimFaces(stc->mFaces);
     st->compute();
+    stc->mElement.clear();
 
     return st;
 }
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 087e50d..116f1c7 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -139,12 +139,6 @@
     uint32_t mLOD;
     bool mFaces;
     ObjectBaseRef<const Element> mElement;
-
-    ObjectBaseRef<const Type> mIndexType;
-    ObjectBaseRef<const Type> mPrimitiveType;
-    ObjectBaseRef<const Type> *mVertexTypes;
-
-
 };
 
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
index 53afb1d..717f7ba 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
@@ -58,19 +58,21 @@
     public static void createVideoProfileTable() {
         // push all the property into one big table
         String encoderType = getVideoCodecProperty();
-        String encoder[] = encoderType.split(",");
-        for (int i = 0; i < encoder.length; i++) {
-            for (int j = 0; j < VIDEO_ENCODER_PROPERTY.length; j++) {
-                String propertyName = MEDIA_ENC_VID + encoder[i] + VIDEO_ENCODER_PROPERTY[j];
-                String prop = SystemProperties.get(propertyName);
-                //push to the table
-                String propRange[] = prop.split(",");
-                OUTPUT_FORMAT_TABLE.put((encoder[i] + VIDEO_ENCODER_PROPERTY[j] + "_low"),
-                        Integer.parseInt(propRange[0]));
-                OUTPUT_FORMAT_TABLE.put((encoder[i] + VIDEO_ENCODER_PROPERTY[j] + "_high"),
-                        Integer.parseInt(propRange[1]));
-            }
+        if (encoderType.length() != 0) {
+            String encoder[] = encoderType.split(",");
+            for (int i = 0; i < encoder.length; i++) {
+                for (int j = 0; j < VIDEO_ENCODER_PROPERTY.length; j++) {
+                    String propertyName = MEDIA_ENC_VID + encoder[i] + VIDEO_ENCODER_PROPERTY[j];
+                    String prop = SystemProperties.get(propertyName);
+                    // push to the table
+                    String propRange[] = prop.split(",");
+                    OUTPUT_FORMAT_TABLE.put((encoder[i] + VIDEO_ENCODER_PROPERTY[j] + "_low"),
+                            Integer.parseInt(propRange[0]));
+                    OUTPUT_FORMAT_TABLE.put((encoder[i] + VIDEO_ENCODER_PROPERTY[j] + "_high"),
+                            Integer.parseInt(propRange[1]));
+                }
 
+            }
         }
     }
 
@@ -78,18 +80,19 @@
         // push all the property into one big table
         String audioType = getAudioCodecProperty();
         String encoder[] = audioType.split(",");
-        for (int i = 0; i < encoder.length; i++) {
-            for (int j = 0; j < AUDIO_ENCODER_PROPERTY.length; j++) {
-                String propertyName = MEDIA_AUD_VID + encoder[i] + AUDIO_ENCODER_PROPERTY[j];
-                String prop = SystemProperties.get(propertyName);
-                //push to the table
-                String propRange[] = prop.split(",");
-                OUTPUT_FORMAT_TABLE.put((encoder[i] + AUDIO_ENCODER_PROPERTY[j] + "_low"),
-                        Integer.parseInt(propRange[0]));
-                OUTPUT_FORMAT_TABLE.put((encoder[i] + AUDIO_ENCODER_PROPERTY[j] + "_high"),
-                        Integer.parseInt(propRange[1]));
+        if (audioType.length() != 0) {
+            for (int i = 0; i < encoder.length; i++) {
+                for (int j = 0; j < AUDIO_ENCODER_PROPERTY.length; j++) {
+                    String propertyName = MEDIA_AUD_VID + encoder[i] + AUDIO_ENCODER_PROPERTY[j];
+                    String prop = SystemProperties.get(propertyName);
+                    // push to the table
+                    String propRange[] = prop.split(",");
+                    OUTPUT_FORMAT_TABLE.put((encoder[i] + AUDIO_ENCODER_PROPERTY[j] + "_low"),
+                            Integer.parseInt(propRange[0]));
+                    OUTPUT_FORMAT_TABLE.put((encoder[i] + AUDIO_ENCODER_PROPERTY[j] + "_high"),
+                            Integer.parseInt(propRange[1]));
+                }
             }
-
         }
     }
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
index 690eff6..fdc5970 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
@@ -434,15 +434,15 @@
         boolean recordSuccess = false;
         String deviceType = MediaProfileReader.getDeviceType();
         Log.v(TAG, "deviceType = " + deviceType);
-        if (deviceType.compareTo("voles") == 0) {
-            // Test cases are device specified
-            MediaProfileReader.createVideoProfileTable();
-            MediaProfileReader.createAudioProfileTable();
-            MediaProfileReader.createEncoderTable();
-            String encoderType = MediaProfileReader.getVideoCodecProperty();
-            String encoder[] = encoderType.split(",");
-            String audioType = MediaProfileReader.getAudioCodecProperty();
+        // Test cases are device specified
+        MediaProfileReader.createVideoProfileTable();
+        MediaProfileReader.createAudioProfileTable();
+        MediaProfileReader.createEncoderTable();
+        String encoderType = MediaProfileReader.getVideoCodecProperty();
+        String audioType = MediaProfileReader.getAudioCodecProperty();
+        if ((encoderType.length() != 0) || (audioType.length() != 0)) {
             String audio[] = audioType.split(",");
+            String encoder[] = encoderType.split(",");
             for (int k = 0; k < 2; k++) {
                 for (int i = 0; i < encoder.length; i++) {
                     for (int j = 0; j < audio.length; j++) {
@@ -451,18 +451,18 @@
                         } else {
                             recordSuccess = recordVideoWithPara(encoder[i], audio[j], "low");
                         }
-                        if (!recordSuccess){
+                        if (!recordSuccess) {
                             Log.v(TAG, "testDeviceSpecificCodec failed");
                             Log.v(TAG, "Encoder = " + encoder[i] + "Audio Encoder = " + audio[j]);
                             noOfFailure++;
                         }
-                       //assertTrue((encoder[i] + audio[j]), recordSuccess);
+                        // assertTrue((encoder[i] + audio[j]), recordSuccess);
                     }
                 }
             }
-        }
-        if (noOfFailure != 0){
-            assertTrue("testDeviceSpecificCodec", false);
+            if (noOfFailure != 0) {
+                assertTrue("testDeviceSpecificCodec", false);
+            }
         }
     }
 }
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 3662a4f..695d061 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -829,6 +829,9 @@
             * OpenGL context is a somewhat heavy object.
             */
             mEglContext = mEGLContextFactory.createContext(mEgl, mEglDisplay, mEglConfig);
+            if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) {
+                throw new RuntimeException("createContext failed");
+            }
 
             mEglSurface = null;
         }
@@ -842,7 +845,7 @@
              *  The window size has changed, so we need to create a new
              *  surface.
              */
-            if (mEglSurface != null) {
+            if (mEglSurface != null && mEglSurface != EGL10.EGL_NO_SURFACE) {
 
                 /*
                  * Unbind and destroy the old EGL surface, if
@@ -859,12 +862,17 @@
             mEglSurface = mEGLWindowSurfaceFactory.createWindowSurface(mEgl,
                     mEglDisplay, mEglConfig, holder);
 
+            if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
+                throw new RuntimeException("createWindowSurface failed");
+            }
+
             /*
              * Before we can issue GL commands, we need to make sure
              * the context is current and bound to a surface.
              */
-            mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-                    mEglContext);
+            if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+                throw new RuntimeException("eglMakeCurrent failed.");
+            }
 
             GL gl = mEglContext.getGL();
             if (mGLWrapper != null) {
@@ -902,7 +910,7 @@
         }
 
         public void destroySurface() {
-            if (mEglSurface != null) {
+            if (mEglSurface != null && mEglSurface != EGL10.EGL_NO_SURFACE) {
                 mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
                         EGL10.EGL_NO_SURFACE,
                         EGL10.EGL_NO_CONTEXT);
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 9578452..d6c7114 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -32,6 +32,10 @@
 LOCAL_CFLAGS += -DADRENO130=1
 endif
 
+ifeq ($(TARGET_BOARD_PLATFORM),qsd8k)
+LOCAL_CFLAGS += -DADRENO130=1
+endif
+
 include $(BUILD_SHARED_LIBRARY)
 installed_libEGL := $(LOCAL_INSTALLED_MODULE)
 
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index ba9a717..9345de5 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -44,17 +44,6 @@
     fprintf(stderr, "GL %s = %s\n", name, v);
 }
 
-static const char* eglErrorToString[] = {
-        "EGL_SUCCESS", // 0x3000 12288
-        "EGL_NOT_INITIALIZED",
-        "EGL_BAD_ACCESS", // 0x3002 12290
-        "EGL_BAD_ALLOC", "EGL_BAD_ATTRIBUTE",
-        "EGL_BAD_CONFIG",
-        "EGL_BAD_CONTEXT", // 0x3006 12294
-        "EGL_BAD_CURRENT_SURFACE", "EGL_BAD_DISPLAY", "EGL_BAD_MATCH",
-        "EGL_BAD_NATIVE_PIXMAP", "EGL_BAD_NATIVE_WINDOW", "EGL_BAD_PARAMETER", // 0x300c 12300
-        "EGL_BAD_SURFACE" };
-
 static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
     if (returnVal != EGL_TRUE) {
         fprintf(stderr, "%s() returned %d\n", op, returnVal);
@@ -62,11 +51,7 @@
 
     for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
             = eglGetError()) {
-        const char* errorString = "unknown";
-        if (error >= EGL_SUCCESS && error <= EGL_BAD_SURFACE) {
-            errorString = eglErrorToString[error - EGL_SUCCESS];
-        }
-        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, errorString,
+        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
                 error);
     }
 }
@@ -190,22 +175,33 @@
     checkGlError("glDrawArrays");
 }
 
+#if 0
+
+void PrintEGLConfig(EGLDisplay dpy, EGLConfig config) {
+	int attrib[] = {EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE, EGL_ALPHA_SIZE,
+			EGL_DEPTH_SIZE, EGL_SURFACE_TYPE, EGL_RENDERABLE_TYPE
+	};
+	for(size_t i = 0; i < sizeof(attrib)/sizeof(attrib[0]); i++) {
+        int value = 0;
+        int a = attrib[i];
+        if (eglGetConfigAttrib(dpy, config, a, &value)) {
+            printf(" 0x%04x: %d", a, value);
+        }
+	}
+	printf("\n");
+}
+
+#endif
+
 int main(int argc, char** argv) {
     EGLBoolean returnValue;
-    EGLConfig configs[2];
-    EGLint config_count;
+    EGLConfig myConfig = {0};
 
     EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
-    EGLint s_configAttribs[] = { EGL_BUFFER_SIZE, EGL_DONT_CARE, EGL_RED_SIZE,
-            5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 8,
-            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE };
-
-    EGLint s_configAttribs2[] =
-    {
-            EGL_DEPTH_SIZE,     16,
-            EGL_NONE
-    };
-
+    EGLint s_configAttribs[] = {
+            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT|EGL_WINDOW_BIT,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+            EGL_NONE };
     EGLint majorVersion;
     EGLint minorVersion;
     EGLContext context;
@@ -214,9 +210,6 @@
 
     EGLDisplay dpy;
 
-    EGLNativeWindowType window = 0;
-    window = android_createDisplaySurface();
-
     checkEglError("<init>");
     dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     checkEglError("eglGetDisplay");
@@ -233,43 +226,31 @@
         return 0;
     }
 
-    returnValue = eglGetConfigs(dpy, configs, 2, &config_count);
-    checkEglError("eglGetConfigs", returnValue);
-    fprintf(stderr, "Config count: %d\n", config_count);
-    for (int i = 0; i < config_count; i++) {
-        fprintf(stderr, "%d: 0x%08x\n", i, (unsigned int) configs[i]);
+    EGLNativeWindowType window = android_createDisplaySurface();

+    returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig);
+    if (returnValue) {
+    	printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue);
+    	return 0;
     }
 
-#if 0
-    EGLConfig config;
-    EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
-    checkEglError("EGLUtils::selectConfigForNativeWindow");
-#else
-    int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs2, configs, 2,
-            &config_count);
-    checkEglError("eglChooseConfig", chooseConfigResult);
-    if (chooseConfigResult != EGL_TRUE) {
-        printf("eglChooseConfig failed\n");
-        return 0;
-    }
-#endif
-
-    surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
+    surface = eglCreateWindowSurface(dpy, myConfig, window, NULL);
     checkEglError("eglCreateWindowSurface");
     if (surface == EGL_NO_SURFACE) {
         printf("gelCreateWindowSurface failed.\n");
         return 0;
     }
-    EGLint gl2_0Attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
 
-    context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
+    context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs);
     checkEglError("eglCreateContext");
     if (context == EGL_NO_CONTEXT) {
         printf("eglCreateContext failed\n");
         return 0;
     }
-    eglMakeCurrent(dpy, surface, surface, context);
-    checkEglError("eglMakeCurrent");
+    returnValue = eglMakeCurrent(dpy, surface, surface, context);
+    checkEglError("eglMakeCurrent", returnValue);
+    if (returnValue != EGL_TRUE) {
+        return 0;
+    }
     eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
     checkEglError("eglQuerySurface");
     eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
diff --git a/opengl/tests/gl2_jni/Android.mk b/opengl/tests/gl2_jni/Android.mk
index ff15814..81247df 100644
--- a/opengl/tests/gl2_jni/Android.mk
+++ b/opengl/tests/gl2_jni/Android.mk
@@ -44,8 +44,6 @@
 
 LOCAL_MODULE := libgl2jni
 
-LOCAL_ARM_MODE := arm
-
 LOCAL_PRELINK_MODULE := false
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/tests/gl2_jni/jni/gl_code.cpp b/opengl/tests/gl2_jni/jni/gl_code.cpp
index 146d52a..c2fabe6 100644
--- a/opengl/tests/gl2_jni/jni/gl_code.cpp
+++ b/opengl/tests/gl2_jni/jni/gl_code.cpp
@@ -3,12 +3,12 @@
 #include <nativehelper/jni.h>
 #define LOG_TAG "GL2JNI gl_code.cpp"
 #include <utils/Log.h>
-

+
 #include <EGL/egl.h>
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
-#include <stdio.h>

+#include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
@@ -23,7 +23,7 @@
         LOGI("after %s() glError (0x%x)\n", op, error);
     }
 }
-

+
 static const char gVertexShader[] = "attribute vec4 vPosition;\n"
     "void main() {\n"
     "  gl_Position = vPosition;\n"
@@ -151,15 +151,15 @@
 extern "C" {
     JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height);
     JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj);
-};

-

-JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height)

-{

-    setupGraphics(width, height);

-}

+};
 
-JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj)

-{

-    renderFrame();

-}

+JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height)

+{
+    setupGraphics(width, height);
+}
+
+JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj)
+{
+    renderFrame();
+}
 
diff --git a/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIView.java b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIView.java
index baa10af..2dae090 100644
--- a/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIView.java
+++ b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIView.java
@@ -44,6 +44,7 @@
 import javax.microedition.khronos.egl.EGLContext;
 import javax.microedition.khronos.egl.EGLDisplay;
 import javax.microedition.khronos.opengles.GL10;
+
 /**
  * An implementation of SurfaceView that uses the dedicated surface for
  * displaying an OpenGL animation.  This allows the animation to run in a
@@ -67,13 +68,14 @@
 
     private void init() {
         setEGLContextFactory(new ContextFactory());
-        // setEGLConfigChooser(new ConfigChooser());
+        setEGLConfigChooser(new ConfigChooser());
         setRenderer(new Renderer());
     }
 
     private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
         private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
         public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
+            Log.w(TAG, "creating OpenGL ES 2.0 context");
             checkEglError("Before eglCreateContext", egl);
             int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
             EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
@@ -83,7 +85,7 @@
 
         public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
             egl.eglDestroyContext(display, context);
-        } 
+        }
     }
 
     private static void checkEglError(String prompt, EGL10 egl) {
@@ -95,11 +97,13 @@
 
     private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
         private static int EGL_OPENGL_ES2_BIT = 4;
-        private static int[]  s_configAttribs2 =
+        private static int[] s_configAttribs2 =
         {
-                EGL10.EGL_DEPTH_SIZE,     16,
-                // EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-                EGL10.EGL_NONE
+            EGL10.EGL_RED_SIZE, 4,
+            EGL10.EGL_GREEN_SIZE, 4,
+            EGL10.EGL_BLUE_SIZE, 4,
+            EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+            EGL10.EGL_NONE
         };
         public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
 
@@ -108,6 +112,7 @@
 
             int numConfigs = num_config[0];
 
+            Log.w(TAG, String.format("Found %d configurations", numConfigs));
             if (numConfigs <= 0) {
                 throw new IllegalArgumentException("No configs match configSpec");
             }
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index db1b5f1..fbfe755 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -30,6 +30,7 @@
     <bool name="def_screen_brightness_automatic_mode">false</bool>
     <fraction name="def_window_animation_scale">100%</fraction>
     <fraction name="def_window_transition_scale">100%</fraction>
+    <bool name="def_haptic_feedback">true</bool>
     
     <bool name="def_bluetooth_on">false</bool>
     <bool name="def_install_non_market_apps">false</bool>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index c561078..e25c648 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -71,7 +71,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 41;
+    private static final int DATABASE_VERSION = 42;
 
     private Context mContext;
 
@@ -502,6 +502,25 @@
             upgradeVersion = 41;
         }
 
+        if (upgradeVersion == 41) {
+            /*
+             * Initialize newly public haptic feedback setting
+             */
+            db.beginTransaction();
+            try {
+                db.execSQL("DELETE FROM system WHERE name='"
+                        + Settings.System.HAPTIC_FEEDBACK_ENABLED + "'");
+                SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+                        + " VALUES(?,?);");
+                loadDefaultHapticSettings(stmt);
+                stmt.close();
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+            }
+            upgradeVersion = 42;
+        }
+
         if (upgradeVersion != currentVersion) {
             Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
                     + ", must wipe the settings provider");
@@ -746,6 +765,8 @@
         loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
                 R.bool.def_accelerometer_rotation);
 
+        loadDefaultHapticSettings(stmt);
+
         stmt.close();
     }
 
@@ -756,6 +777,11 @@
                 R.fraction.def_window_transition_scale, 1);
     }
 
+    private void loadDefaultHapticSettings(SQLiteStatement stmt) {
+        loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED,
+                R.bool.def_haptic_feedback);
+    }
+
     private void loadSecureSettings(SQLiteDatabase db) {
         SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                 + " VALUES(?,?);");
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 323a11f..867f215 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -1103,6 +1103,12 @@
         return null;
     }
 
+    public boolean hasSystemFeature(String name) {
+        synchronized (mPackages) {
+            return mAvailableFeatures.containsKey(name);
+        }
+    }
+    
     public int checkPermission(String permName, String pkgName) {
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(pkgName);
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 78a82dd..8ebbc93 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -3122,7 +3122,7 @@
 
     public void overridePendingAppTransition(String packageName,
             int enterAnim, int exitAnim) {
-        if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET){
+        if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
             mNextAppTransitionPackage = packageName;
             mNextAppTransitionEnter = enterAnim;
             mNextAppTransitionExit = exitAnim;
@@ -9327,7 +9327,6 @@
                             transit = WindowManagerPolicy.TRANSIT_UNSET;
                         }
                         mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
-                        mNextAppTransitionPackage = null;
                         mAppTransitionReady = false;
                         mAppTransitionRunning = true;
                         mAppTransitionTimeout = false;
@@ -9484,6 +9483,8 @@
                             wtoken.allDrawn = true;
                         }
 
+                        mNextAppTransitionPackage = null;
+                        
                         mOpeningApps.clear();
                         mClosingApps.clear();
 
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 5581a24..1f0e5a5 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -425,26 +425,28 @@
      * will be sent by the ConnectivityManager when a connection to
      * the APN has been established.
      */
-    public int enableApnType(String type) {
+    public synchronized int enableApnType(String type) {
         int id = apnTypeToId(type);
         if (id == APN_INVALID_ID) {
             return Phone.APN_REQUEST_FAILED;
         }
 
-        // If already active, return
         if(DBG) Log.d(LOG_TAG, "enableApnType("+type+"), isApnTypeActive = "
                 + isApnTypeActive(type) + " and state = " + state);
 
-        if (isApnTypeActive(type)) {
-            if (state == State.INITING) return Phone.APN_REQUEST_STARTED;
-            else if (state == State.CONNECTED) return Phone.APN_ALREADY_ACTIVE;
-        }
-
         if (!isApnTypeAvailable(type)) {
             return Phone.APN_TYPE_NOT_AVAILABLE;
         }
 
+        // just because it's active doesn't mean we had it explicitly requested before
+        // (a broad default may handle many types).  make sure we mark it enabled
+        // so if the default is disabled we keep the connection for others
         setEnabled(id, true);
+
+        if (isApnTypeActive(type)) {
+            if (state == State.INITING) return Phone.APN_REQUEST_STARTED;
+            else if (state == State.CONNECTED) return Phone.APN_ALREADY_ACTIVE;
+        }
         return Phone.APN_REQUEST_STARTED;
     }
 
@@ -490,20 +492,21 @@
 
     protected synchronized void onEnableApn(int apnId, int enabled) {
         if (DBG) {
-            Log.d(LOG_TAG, "got EVENT_APN_ENABLE_REQUEST with apnType = " + apnId +
-                    " and enable = " + enabled);
-            Log.d(LOG_TAG, "dataEnabled[apnId] = " + dataEnabled[apnId] +
-                    ", enabledCount = " + enabledCount);
+            Log.d(LOG_TAG, "EVENT_APN_ENABLE_REQUEST " + apnId + ", " + enabled);
+            Log.d(LOG_TAG, " dataEnabled = " + dataEnabled[apnId] +
+                    ", enabledCount = " + enabledCount +
+                    ", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId)));
         }
         if (enabled == APN_ENABLED) {
             if (!dataEnabled[apnId]) {
-                mRequestedApnType = apnIdToType(apnId);
-                onEnableNewApn();
-
                 dataEnabled[apnId] = true;
                 enabledCount++;
             }
-            onTrySetupData(null);
+            String type = apnIdToType(apnId);
+            if (!isApnTypeActive(type)) {
+                mRequestedApnType = type;
+                onEnableNewApn();
+            }
         } else {
             // disable
             if (dataEnabled[apnId]) {
@@ -511,7 +514,8 @@
                 enabledCount--;
                 if (enabledCount == 0) {
                     onCleanUpConnection(true, Phone.REASON_DATA_DISABLED);
-                } else if (dataEnabled[APN_DEFAULT_ID] == true) {
+                } else if (dataEnabled[APN_DEFAULT_ID] == true &&
+                        !isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
                     mRequestedApnType = Phone.APN_TYPE_DEFAULT;
                     onEnableNewApn();
                 }
diff --git a/test-runner/android/test/mock/MockPackageManager.java b/test-runner/android/test/mock/MockPackageManager.java
index beb9044..2f313af 100644
--- a/test-runner/android/test/mock/MockPackageManager.java
+++ b/test-runner/android/test/mock/MockPackageManager.java
@@ -430,6 +430,11 @@
     }
     
     @Override
+    public boolean hasSystemFeature(String name) {
+        throw new UnsupportedOperationException();
+    }
+    
+    @Override
     public boolean isSafeMode() {
         throw new UnsupportedOperationException();
     }
diff --git a/tests/CoreTests/android/core/PipedStreamTest.java b/tests/CoreTests/android/core/PipedStreamTest.java
index 564b337..d98bc10 100644
--- a/tests/CoreTests/android/core/PipedStreamTest.java
+++ b/tests/CoreTests/android/core/PipedStreamTest.java
@@ -117,7 +117,7 @@
         for (; ;) {
             try {
                 reader.join(60 * 1000);
-                writer.join(1 * 1000);
+                writer.join(1000);
                 break;
             } catch (InterruptedException ex) {
             }
@@ -166,11 +166,11 @@
                     int readInt = (((int) readBytes[0] & 0xff) << 24)
                             | (((int) readBytes[1] & 0xff) << 16)
                             | (((int) readBytes[2] & 0xff) << 8)
-                            | (((int) readBytes[3] & 0xff) << 0);
+                            | (((int) readBytes[3] & 0xff));
 
 
-                    assertEquals(readInt, fib.next());
-                    assertEquals(0, readBytes[4]);
+                    assertEquals("Error at " + countRead, fib.next(), readInt);
+                    assertEquals("Error at " + countRead, 0, readBytes[4]);
                     countRead++;
                 }
             }
@@ -189,7 +189,7 @@
                     writeBytes[0] = (byte) (toWrite >> 24);
                     writeBytes[1] = (byte) (toWrite >> 16);
                     writeBytes[2] = (byte) (toWrite >> 8);
-                    writeBytes[3] = (byte) (toWrite >> 0);
+                    writeBytes[3] = (byte) (toWrite);
                     writeBytes[4] = 0;
                     out.write(writeBytes, 0, writeBytes.length);
                 }
@@ -203,37 +203,35 @@
         for (; ;) {
             try {
                 reader.join(60 * 1000);
-                writer.join(1 * 1000);
+                writer.join(1000);
                 break;
             } catch (InterruptedException ex) {
             }
         }
 
-        assertEquals(2000, reader.countRead);
-
-        if (writer.exception != null) {
-            throw new Exception(writer.exception);
-        }
         if (reader.exception != null) {
             throw new Exception(reader.exception);
         }
+        if (writer.exception != null) {
+            throw new Exception(writer.exception);
+        }
+
+        assertEquals(2000, reader.countRead);
     }
 
     @SmallTest
     public void testC() throws Exception {
         final PipedInputStream in = new PipedInputStream();
         final PipedOutputStream out = new PipedOutputStream(in);
+        final byte readBytes[] = new byte[1024 * 2];
 
         assertEquals(0, in.available());
 
         TestThread reader, writer;
 
         reader = new TestThread() {
-            Fibonacci fib = new Fibonacci();
-
             @Override
             public void runTest() throws Exception {
-                byte readBytes[] = new byte[1024 * 2];
                 int ret;
 
                 for (; ;) {
@@ -246,17 +244,6 @@
                         }
                         nread += ret;
                     }
-
-                    assertEquals(nread, readBytes.length);
-
-                    for (int i = 0; i < (readBytes.length - 4); i += 4) {
-                        int readInt = (((int) readBytes[i + 0] & 0xff) << 24)
-                                | (((int) readBytes[i + 1] & 0xff) << 16)
-                                | (((int) readBytes[i + 2] & 0xff) << 8)
-                                | (((int) readBytes[i + 3] & 0xff) << 0);
-
-                        assertEquals(readInt, fib.next());
-                    }
                 }
             }
         };
@@ -271,10 +258,10 @@
                 byte writeBytes[] = new byte[1024 * 2];
                 for (int i = 0; i < (writeBytes.length - 4); i += 4) {
                     int toWrite = fib.next();
-                    writeBytes[i + 0] = (byte) (toWrite >> 24);
+                    writeBytes[i    ] = (byte) (toWrite >> 24);
                     writeBytes[i + 1] = (byte) (toWrite >> 16);
                     writeBytes[i + 2] = (byte) (toWrite >> 8);
-                    writeBytes[i + 3] = (byte) (toWrite >> 0);
+                    writeBytes[i + 3] = (byte) (toWrite);
                 }
                 out.write(writeBytes, 0, writeBytes.length);
                 out.close();
@@ -287,17 +274,27 @@
         for (; ;) {
             try {
                 reader.join(60 * 1000);
-                writer.join(1 * 100);
+                writer.join(1000);
                 break;
             } catch (InterruptedException ex) {
             }
         }
 
+        if (reader.exception != null) {
+            throw new Exception(reader.exception);
+        }
         if (writer.exception != null) {
             throw new Exception(writer.exception);
         }
-        if (reader.exception != null) {
-            throw new Exception(reader.exception);
+
+        Fibonacci fib = new Fibonacci();
+        for (int i = 0; i < (readBytes.length - 4); i += 4) {
+            int readInt = (((int) readBytes[i] & 0xff) << 24)
+                    | (((int) readBytes[i + 1] & 0xff) << 16)
+                    | (((int) readBytes[i + 2] & 0xff) << 8)
+                    | (((int) readBytes[i + 3] & 0xff));
+
+            assertEquals("Error at " + i, readInt, fib.next());
         }
     }
 }