Merge "MTP: Use correct return type for getSupportedObjectProperties"
diff --git a/api/current.xml b/api/current.xml
index f02ec65..b90ac5f 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -20161,17 +20161,6 @@
  visibility="public"
 >
 </method>
-<method name="getGetter"
- return="java.lang.reflect.Method"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="getPropertyName"
  return="java.lang.String"
  abstract="false"
@@ -20183,17 +20172,6 @@
  visibility="public"
 >
 </method>
-<method name="getSetter"
- return="java.lang.reflect.Method"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="ofFloat"
  return="android.animation.PropertyValuesHolder"
  abstract="false"
@@ -20282,19 +20260,6 @@
 <parameter name="values" type="float...">
 </parameter>
 </method>
-<method name="setGetter"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="getter" type="java.lang.reflect.Method">
-</parameter>
-</method>
 <method name="setIntValues"
  return="void"
  abstract="false"
@@ -20347,19 +20312,6 @@
 <parameter name="propertyName" type="java.lang.String">
 </parameter>
 </method>
-<method name="setSetter"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="setter" type="java.lang.reflect.Method">
-</parameter>
-</method>
 </class>
 <class name="RGBEvaluator"
  extends="java.lang.Object"
@@ -75748,6 +75700,16 @@
  visibility="public"
 >
 </field>
+<field name="inPreferQualityOverSpeed"
+ type="boolean"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="inPreferredConfig"
  type="android.graphics.Bitmap.Config"
  transient="false"
@@ -184371,6 +184333,19 @@
 <parameter name="gmtoff" type="long">
 </parameter>
 </method>
+<method name="getJulianMondayFromWeeksSinceEpoch"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="week" type="int">
+</parameter>
+</method>
 <method name="getWeekNumber"
  return="int"
  abstract="false"
@@ -184382,6 +184357,21 @@
  visibility="public"
 >
 </method>
+<method name="getWeeksSinceEpochFromJulianDay"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="julianDay" type="int">
+</parameter>
+<parameter name="firstDayOfWeek" type="int">
+</parameter>
+</method>
 <method name="isEpoch"
  return="boolean"
  abstract="false"
@@ -184605,6 +184595,17 @@
  visibility="public"
 >
 </field>
+<field name="MONDAY_BEFORE_JULIAN_EPOCH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2440585"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="MONTH"
  type="int"
  transient="false"
@@ -227831,6 +227832,19 @@
  visibility="public"
 >
 </method>
+<method name="removeJavascriptInterface"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="interfaceName" type="java.lang.String">
+</parameter>
+</method>
 <method name="requestFocusNodeHref"
  return="void"
  abstract="false"
@@ -234517,7 +234531,7 @@
 >
 <parameter name="year" type="int">
 </parameter>
-<parameter name="monthOfYear" type="int">
+<parameter name="month" type="int">
 </parameter>
 <parameter name="dayOfMonth" type="int">
 </parameter>
@@ -234569,6 +234583,172 @@
 </parameter>
 </method>
 </interface>
+<class name="DayPicker"
+ extends="android.widget.FrameLayout"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="DayPicker"
+ type="android.widget.DayPicker"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<constructor name="DayPicker"
+ type="android.widget.DayPicker"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="attrs" type="android.util.AttributeSet">
+</parameter>
+</constructor>
+<constructor name="DayPicker"
+ type="android.widget.DayPicker"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="attrs" type="android.util.AttributeSet">
+</parameter>
+<parameter name="defStyle" type="int">
+</parameter>
+</constructor>
+<method name="getSelectedDay"
+ return="java.util.Calendar"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="goTo"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="year" type="int">
+</parameter>
+<parameter name="month" type="int">
+</parameter>
+<parameter name="dayOfMonth" type="int">
+</parameter>
+<parameter name="animate" type="boolean">
+</parameter>
+<parameter name="setSelected" type="boolean">
+</parameter>
+<parameter name="forceScroll" type="boolean">
+</parameter>
+</method>
+<method name="goTo"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="date" type="java.util.Calendar">
+</parameter>
+<parameter name="animate" type="boolean">
+</parameter>
+<parameter name="setSelected" type="boolean">
+</parameter>
+<parameter name="forceScroll" type="boolean">
+</parameter>
+</method>
+<method name="setOnDateChangeListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.widget.DayPicker.OnSelectedDayChangeListener">
+</parameter>
+</method>
+<method name="setRange"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startRangeDate" type="java.util.Calendar">
+</parameter>
+<parameter name="endRangeDate" type="java.util.Calendar">
+</parameter>
+</method>
+<method name="setSelectedDay"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="selectedDay" type="java.util.Calendar">
+</parameter>
+</method>
+</class>
+<interface name="DayPicker.OnSelectedDayChangeListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onSelectedDayChange"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.widget.DayPicker">
+</parameter>
+<parameter name="year" type="int">
+</parameter>
+<parameter name="month" type="int">
+</parameter>
+<parameter name="dayOfMonth" type="int">
+</parameter>
+</method>
+</interface>
 <class name="DialerFilter"
  extends="android.widget.RelativeLayout"
  abstract="false"
@@ -250407,7 +250587,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
 </parameter>
 </method>
 </interface>
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index f2b5638..a3d7a6e 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -3,6 +3,7 @@
 #include <media/IStreamSource.h>
 #include <media/mediaplayer.h>
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
 
 #include <binder/IServiceManager.h>
 #include <media/IMediaPlayerService.h>
@@ -56,7 +57,7 @@
 
     ssize_t n = read(mFd, mem->pointer(), mem->size());
     if (n <= 0) {
-        mListener->queueCommand(IStreamListener::EOS);
+        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
     } else {
         mListener->queueBuffer(index, n);
     }
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 61ef8f2..a815b3a 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -838,6 +838,44 @@
         }
     }
 
+    void getAuthTokenLabel(final IAccountManagerResponse response,
+            final Account account, final String authTokenType) {
+        if (account == null) throw new IllegalArgumentException("account is null");
+        if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
+
+        checkBinderPermission(Manifest.permission.USE_CREDENTIALS);
+
+        long identityToken = clearCallingIdentity();
+        try {
+            new Session(response, account.type, false,
+                    false /* stripAuthTokenFromResult */) {
+                protected String toDebugString(long now) {
+                    return super.toDebugString(now) + ", getAuthTokenLabel"
+                            + ", " + account
+                            + ", authTokenType " + authTokenType;
+                }
+
+                public void run() throws RemoteException {
+                    mAuthenticator.getAuthTokenLabel(this, authTokenType);
+                }
+
+                public void onResult(Bundle result) {
+                    if (result != null) {
+                        String label = result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL);
+                        Bundle bundle = new Bundle();
+                        bundle.putString(AccountManager.KEY_AUTH_TOKEN_LABEL, label);
+                        super.onResult(bundle);
+                        return;
+                    } else {
+                        super.onResult(result);
+                    }
+                }
+            }.bind();
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
     public void getAuthToken(IAccountManagerResponse response, final Account account,
             final String authTokenType, final boolean notifyOnAuthFailure,
             final boolean expectActivityLaunch, final Bundle loginOptions) {
@@ -956,36 +994,36 @@
         installNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), n);
     }
 
-    private Intent newGrantCredentialsPermissionIntent(Account account, int uid,
-            AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) {
+    String getAccountLabel(String accountType) {
         RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo =
-                mAuthenticatorCache.getServiceInfo(
-                        AuthenticatorDescription.newKey(account.type));
+            mAuthenticatorCache.getServiceInfo(
+                    AuthenticatorDescription.newKey(accountType));
         if (serviceInfo == null) {
-            throw new IllegalArgumentException("unknown account type: " + account.type);
+            throw new IllegalArgumentException("unknown account type: " + accountType);
         }
 
         final Context authContext;
         try {
             authContext = mContext.createPackageContext(
-                serviceInfo.type.packageName, 0);
+                    serviceInfo.type.packageName, 0);
         } catch (PackageManager.NameNotFoundException e) {
-            throw new IllegalArgumentException("unknown account type: " + account.type);
+            throw new IllegalArgumentException("unknown account type: " + accountType);
         }
+        return authContext.getString(serviceInfo.type.labelId);
+    }
+
+    private Intent newGrantCredentialsPermissionIntent(Account account, int uid,
+            AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) {
 
         Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.addCategory(
                 String.valueOf(getCredentialPermissionNotificationId(account, authTokenType, uid)));
+
         intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT, account);
-        intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_LABEL, authTokenLabel);
         intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE, authTokenType);
         intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_RESPONSE, response);
-        intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT_TYPE_LABEL,
-                        authContext.getString(serviceInfo.type.labelId));
-        intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_PACKAGES,
-                        mPackageManager.getPackagesForUid(uid));
         intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, uid);
+
         return intent;
     }
 
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index fd340cbe..83e4fd9 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -17,6 +17,7 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.os.RemoteException;
 import android.widget.TextView;
 import android.widget.LinearLayout;
 import android.widget.ImageView;
@@ -26,6 +27,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.RegisteredServicesCache;
 import android.text.TextUtils;
 import android.graphics.drawable.Drawable;
 import com.android.internal.R;
@@ -46,6 +48,7 @@
     private int mUid;
     private Bundle mResultBundle = null;
     protected LayoutInflater mInflater;
+    private final AccountManagerService accountManagerService = AccountManagerService.getSingleton();
 
     protected void onCreate(Bundle savedInstanceState) {
         requestWindowFeature(Window.FEATURE_NO_TITLE);
@@ -55,27 +58,56 @@
         mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
         final Bundle extras = getIntent().getExtras();
+
+        // Grant 'account'/'type' to mUID
         mAccount = extras.getParcelable(EXTRAS_ACCOUNT);
         mAuthTokenType = extras.getString(EXTRAS_AUTH_TOKEN_TYPE);
+        mUid = extras.getInt(EXTRAS_REQUESTING_UID);
+        final PackageManager pm = getPackageManager();
+        final String[] packages = pm.getPackagesForUid(mUid);
 
-        if (mAccount == null || mAuthTokenType == null) {
+        if (mAccount == null || mAuthTokenType == null || packages == null) {
             // we were somehow started with bad parameters. abort the activity.
             setResult(Activity.RESULT_CANCELED);
             finish();
             return;
         }
 
-        mUid = extras.getInt(EXTRAS_REQUESTING_UID);
-        final String accountTypeLabel = extras.getString(EXTRAS_ACCOUNT_TYPE_LABEL);
-        final String[] packages = extras.getStringArray(EXTRAS_PACKAGES);
-        final String authTokenLabel = extras.getString(EXTRAS_AUTH_TOKEN_LABEL);
+        final String accountTypeLabel = accountManagerService.getAccountLabel(mAccount.type);
+
+
+        final TextView authTokenTypeView = (TextView) findViewById(R.id.authtoken_type);
+        authTokenTypeView.setVisibility(View.GONE);
+
+        /** Handles the responses from the AccountManager */
+        IAccountManagerResponse response = new IAccountManagerResponse.Stub() {
+            public void onResult(Bundle bundle) {
+                final String authTokenLabel =
+                    bundle.getString(AccountManager.KEY_AUTH_TOKEN_LABEL);
+                if (!TextUtils.isEmpty(authTokenLabel)) {
+                    runOnUiThread(new Runnable() {
+                        public void run() {
+                            if (!isFinishing()) {
+                                authTokenTypeView.setText(authTokenLabel);
+                                authTokenTypeView.setVisibility(View.VISIBLE);
+                            }
+                        }
+                    });
+                }
+            }
+
+            public void onError(int code, String message) {
+            }
+        };
+
+        accountManagerService.getAuthTokenLabel(
+                response, mAccount, mAuthTokenType);
 
         findViewById(R.id.allow_button).setOnClickListener(this);
         findViewById(R.id.deny_button).setOnClickListener(this);
 
         LinearLayout packagesListView = (LinearLayout) findViewById(R.id.packages_list);
 
-        final PackageManager pm = getPackageManager();
         for (String pkg : packages) {
             String packageLabel;
             try {
@@ -88,12 +120,6 @@
 
         ((TextView) findViewById(R.id.account_name)).setText(mAccount.name);
         ((TextView) findViewById(R.id.account_type)).setText(accountTypeLabel);
-        TextView authTokenTypeView = (TextView) findViewById(R.id.authtoken_type);
-        if (TextUtils.isEmpty(authTokenLabel)) {
-            authTokenTypeView.setVisibility(View.GONE);
-        } else {
-            authTokenTypeView.setText(authTokenLabel);
-        }
     }
 
     private View newPackageView(String packageLabel) {
@@ -103,7 +129,6 @@
     }
 
     public void onClick(View v) {
-        final AccountManagerService accountManagerService = AccountManagerService.getSingleton();
         switch (v.getId()) {
             case R.id.allow_button:
                 accountManagerService.grantAppPermission(mAccount, mAuthTokenType, mUid);
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 22e04a7..5fe3644 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -36,22 +36,36 @@
      * this call, because all animation events are posted to a central timing loop so that animation
      * times are all synchronized on a single timing pulse on the UI thread. So the animation will
      * start the next time that event handler processes events.
+     *
+     * <p>The animation started by calling this method will be run on the thread that called
+     * this method. This thread should have a Looper on it (a runtime exception will be thrown if
+     * this is not the case). Also, if the animation will animate
+     * properties of objects in the view hierarchy, then the calling thread should be the UI
+     * thread for that view hierarchy.</p>
+     *
      */
     public void start() {
     }
 
     /**
      * Cancels the animation. Unlike {@link #end()}, <code>cancel()</code> causes the animation to
-     * stop in its tracks, sending an {@link android.animation.Animator.AnimatorListener#onAnimationCancel(Animator)} to
-     * its listeners, followed by an {@link android.animation.Animator.AnimatorListener#onAnimationEnd(Animator)} message.
+     * stop in its tracks, sending an
+     * {@link android.animation.Animator.AnimatorListener#onAnimationCancel(Animator)} to
+     * its listeners, followed by an
+     * {@link android.animation.Animator.AnimatorListener#onAnimationEnd(Animator)} message.
+     *
+     * <p>This method must be called on the thread that is running the animation.</p>
      */
     public void cancel() {
     }
 
     /**
      * Ends the animation. This causes the animation to assign the end value of the property being
-     * animated, then calling the {@link android.animation.Animator.AnimatorListener#onAnimationEnd(Animator)} method on
+     * animated, then calling the
+     * {@link android.animation.Animator.AnimatorListener#onAnimationEnd(Animator)} method on
      * its listeners.
+     *
+     * <p>This method must be called on the thread that is running the animation.</p>
      */
     public void end() {
     }
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 154e084..d77dbdc 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -96,6 +96,9 @@
     // The amount of time in ms to delay starting the animation after start() is called
     private long mStartDelay = 0;
 
+    // Animator used for a nonzero startDelay
+    private ValueAnimator mDelayAnim = null;
+
 
     // How long the child animations should last in ms. The default value is negative, which
     // simply means that there is no duration set on the AnimatorSet. When a real duration is
@@ -276,6 +279,19 @@
                 listener.onAnimationCancel(this);
             }
         }
+        if (mDelayAnim != null && mDelayAnim.isRunning()) {
+            // If we're currently in the startDelay period, just cancel that animator and
+            // send out the end event to all listeners
+            mDelayAnim.cancel();
+            if (mListeners != null) {
+                ArrayList<AnimatorListener> tmpListeners =
+                        (ArrayList<AnimatorListener>) mListeners.clone();
+                for (AnimatorListener listener : tmpListeners) {
+                    listener.onAnimationEnd(this);
+                }
+            }
+            return;
+        }
         if (mSortedNodes.size() > 0) {
             for (Node node : mSortedNodes) {
                 node.animation.cancel();
@@ -302,6 +318,9 @@
                 node.animation.addListener(mSetListener);
             }
         }
+        if (mDelayAnim != null) {
+            mDelayAnim.cancel();
+        }
         if (mSortedNodes.size() > 0) {
             for (Node node : mSortedNodes) {
                 node.animation.end();
@@ -411,12 +430,25 @@
         // contains the animation nodes in the correct order.
         sortNodes();
 
+        int numSortedNodes = mSortedNodes.size();
+        for (int i = 0; i < numSortedNodes; ++i) {
+            Node node = mSortedNodes.get(i);
+            // First, clear out the old listeners
+            ArrayList<AnimatorListener> oldListeners = node.animation.getListeners();
+            if (oldListeners != null && oldListeners.size() > 0) {
+                for (AnimatorListener listener : oldListeners) {
+                    if (listener instanceof DependencyListener) {
+                        node.animation.removeListener(listener);
+                    }
+                }
+            }
+        }
+
         // nodesToStart holds the list of nodes to be started immediately. We don't want to
         // start the animations in the loop directly because we first need to set up
         // dependencies on all of the nodes. For example, we don't want to start an animation
         // when some other animation also wants to start when the first animation begins.
         final ArrayList<Node> nodesToStart = new ArrayList<Node>();
-        int numSortedNodes = mSortedNodes.size();
         for (int i = 0; i < numSortedNodes; ++i) {
             Node node = mSortedNodes.get(i);
             if (mSetListener == null) {
@@ -443,19 +475,25 @@
             }
         } else {
             // TODO: Need to cancel out of the delay appropriately
-            ValueAnimator delayAnim = ValueAnimator.ofFloat(0f, 1f);
-            delayAnim.setDuration(mStartDelay);
-            delayAnim.addListener(new AnimatorListenerAdapter() {
+            mDelayAnim = ValueAnimator.ofFloat(0f, 1f);
+            mDelayAnim.setDuration(mStartDelay);
+            mDelayAnim.addListener(new AnimatorListenerAdapter() {
+                boolean canceled = false;
+                public void onAnimationCancel(Animator anim) {
+                    canceled = true;
+                }
                 public void onAnimationEnd(Animator anim) {
-                    int numNodes = nodesToStart.size();
-                    for (int i = 0; i < numNodes; ++i) {
-                        Node node = nodesToStart.get(i);
-                        node.animation.start();
-                        mPlayingSet.add(node.animation);
+                    if (!canceled) {
+                        int numNodes = nodesToStart.size();
+                        for (int i = 0; i < numNodes; ++i) {
+                            Node node = nodesToStart.get(i);
+                            node.animation.start();
+                            mPlayingSet.add(node.animation);
+                        }
                     }
                 }
             });
-            delayAnim.start();
+            mDelayAnim.start();
         }
         if (mListeners != null) {
             ArrayList<AnimatorListener> tmpListeners =
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index 7c2e70d..7f11871 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -19,6 +19,7 @@
 import android.util.Log;
 
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 
 /**
  * This subclass of {@link ValueAnimator} provides support for animating properties on target objects.
@@ -31,6 +32,7 @@
  *
  */
 public final class ObjectAnimator extends ValueAnimator {
+    private static final boolean DBG = false;
 
     // The target object on which the property exists, set in the constructor
     private Object mTarget;
@@ -265,6 +267,21 @@
         }
     }
 
+    @Override
+    public void start() {
+        if (DBG) {
+            Log.d("ObjectAnimator", "Anim target, duration" + mTarget + ", " + getDuration());
+            for (int i = 0; i < mValues.length; ++i) {
+                PropertyValuesHolder pvh = mValues[i];
+                ArrayList<Keyframe> keyframes = pvh.mKeyframeSet.mKeyframes;
+                Log.d("ObjectAnimator", "   Values[" + i + "]: " +
+                    pvh.getPropertyName() + ", " + keyframes.get(0).getValue() + ", " +
+                    keyframes.get(pvh.mKeyframeSet.mNumKeyframes - 1).getValue());
+            }
+        }
+        super.start();
+    }
+
     /**
      * This function is called immediately before processing the first animation
      * frame of an animation. If there is a nonzero <code>startDelay</code>, the
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 97aa5a1..1412f38 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -178,9 +178,8 @@
      * on the object. Also, if any value is null, the value will be filled in when the animation
      * starts in the same way. This mechanism of automatically getting null values only works
      * if the PropertyValuesHolder object is used in conjunction
-     * {@link ObjectAnimator}, and with a getter function either
-     * derived automatically from <code>propertyName</code> or set explicitly via
-     * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
+     * {@link ObjectAnimator}, and with a getter function
+     * derived automatically from <code>propertyName</code>, since otherwise PropertyValuesHolder has
      * no way of determining what the value should be.
      * @param propertyName The name of the property associated with this set of values. This
      * can be the actual property name to be used when using a ObjectAnimator object, or
@@ -210,9 +209,8 @@
      * on the object. Also, if any value is null, the value will be filled in when the animation
      * starts in the same way. This mechanism of automatically getting null values only works
      * if the PropertyValuesHolder object is used in conjunction
-     * {@link ObjectAnimator}, and with a getter function either
-     * derived automatically from <code>propertyName</code> or set explicitly via
-     * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
+     * {@link ObjectAnimator}, and with a getter function
+     * derived automatically from <code>propertyName</code>, since otherwise PropertyValuesHolder has
      * no way of determining what the value should be.
      *
      * @param values One or more values that the animation will animate between.
@@ -229,9 +227,8 @@
      * on the object. Also, if any value is null, the value will be filled in when the animation
      * starts in the same way. This mechanism of automatically getting null values only works
      * if the PropertyValuesHolder object is used in conjunction
-     * {@link ObjectAnimator}, and with a getter function either
-     * derived automatically from <code>propertyName</code> or set explicitly via
-     * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
+     * {@link ObjectAnimator}, and with a getter function
+     * derived automatically from <code>propertyName</code>, since otherwise PropertyValuesHolder has
      * no way of determining what the value should be.
      *
      * @param values One or more values that the animation will animate between.
@@ -263,9 +260,8 @@
      * on the object. Also, if any value is null, the value will be filled in when the animation
      * starts in the same way. This mechanism of automatically getting null values only works
      * if the PropertyValuesHolder object is used in conjunction
-     * {@link ObjectAnimator}, and with a getter function either
-     * derived automatically from <code>propertyName</code> or set explicitly via
-     * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
+     * {@link ObjectAnimator}, and with a getter function
+     * derived automatically from <code>propertyName</code>, since otherwise PropertyValuesHolder has
      * no way of determining what the value should be.
      * 
      * @param values One or more values that the animation will animate between.
@@ -329,7 +325,7 @@
             // If we got here, then no appropriate function was found
             Log.e("PropertyValuesHolder",
                     "Couldn't find setter/getter for property " + mPropertyName +
-                            "with value type "+ mValueType);
+                            " with value type "+ mValueType);
         }
 
         return returnVal;
@@ -544,67 +540,6 @@
     }
 
     /**
-     * Sets the <code>Method</code> that is called with the animated values calculated
-     * during the animation. Setting the setter method is an alternative to supplying a
-     * {@link #setPropertyName(String) propertyName} from which the method is derived. This
-     * approach is more direct, and is especially useful when a function must be called that does
-     * not correspond to the convention of <code>setName()</code>. For example, if a function
-     * called <code>offset()</code> is to be called with the animated values, there is no way
-     * to tell <code>ObjectAnimator</code> how to call that function simply through a property
-     * name, so a setter method should be supplied instead.
-     *
-     * <p>Note that the setter function must take the same parameter type as the
-     * <code>valueFrom</code> and <code>valueTo</code> properties, otherwise the call to
-     * the setter function will fail.</p>
-     *
-     * @param setter The setter method that should be called with the animated values.
-     */
-    public void setSetter(Method setter) {
-        mSetter = setter;
-    }
-
-    /**
-     * Gets the <code>Method</code> that is called with the animated values calculated
-     * during the animation.
-     */
-    public Method getSetter() {
-        return mSetter;
-    }
-
-    /**
-     * Sets the <code>Method</code> that is called to get unsupplied <code>valueFrom</code> or
-     * <code>valueTo</code> properties. Setting the getter method is an alternative to supplying a
-     * {@link #setPropertyName(String) propertyName} from which the method is derived. This
-     * approach is more direct, and is especially useful when a function must be called that does
-     * not correspond to the convention of <code>setName()</code>. For example, if a function
-     * called <code>offset()</code> is to be called to get an initial value, there is no way
-     * to tell <code>ObjectAnimator</code> how to call that function simply through a property
-     * name, so a getter method should be supplied instead.
-     *
-     * <p>Note that the getter method is only called whether supplied here or derived
-     * from the property name, if one of <code>valueFrom</code> or <code>valueTo</code> are
-     * null. If both of those values are non-null, then there is no need to get one of the
-     * values and the getter is not called.
-     *
-     * <p>Note that the getter function must return the same parameter type as the
-     * <code>valueFrom</code> and <code>valueTo</code> properties (whichever of them are
-     * non-null), otherwise the call to the getter function will fail.</p>
-     *
-     * @param getter The getter method that should be called to get initial animation values.
-     */
-    public void setGetter(Method getter) {
-        mGetter = getter;
-    }
-
-    /**
-     * Gets the <code>Method</code> that is called to get unsupplied <code>valueFrom</code> or
-     * <code>valueTo</code> properties.
-     */
-    public Method getGetter() {
-        return mGetter;
-    }
-
-    /**
      * Sets the name of the property that will be animated. This name is used to derive
      * a setter function that will be called to set animated values.
      * For example, a property name of <code>foo</code> will result
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 8e541c2..1542c49 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -62,9 +62,7 @@
      */
     private static final int STOPPED    = 0; // Not yet playing
     private static final int RUNNING    = 1; // Playing normally
-    private static final int CANCELED   = 2; // cancel() called - need to end it
-    private static final int ENDED      = 3; // end() called - need to end it
-    private static final int SEEKED     = 4; // Seeked to some time value
+    private static final int SEEKED     = 2; // Seeked to some time value
 
     /**
      * Internal variables
@@ -178,7 +176,7 @@
      * Flag that represents the current state of the animation. Used to figure out when to start
      * an animation (if state == STOPPED). Also used to end an animation that
      * has been cancel()'d or end()'d since the last animation frame. Possible values are
-     * STOPPED, RUNNING, ENDED, CANCELED.
+     * STOPPED, RUNNING, SEEKED.
      */
     private int mPlayingState = STOPPED;
 
@@ -581,8 +579,7 @@
                         for (int i = 0; i < count; ++i) {
                             ValueAnimator anim = pendingCopy.get(i);
                             // If the animation has a startDelay, place it on the delayed list
-                            if (anim.mStartDelay == 0 || anim.mPlayingState == ENDED ||
-                                    anim.mPlayingState == CANCELED) {
+                            if (anim.mStartDelay == 0) {
                                 anim.startAnimation();
                             } else {
                                 delayedAnims.add(anim);
@@ -619,14 +616,28 @@
                     // Now process all active animations. The return value from animationFrame()
                     // tells the handler whether it should now be ended
                     int numAnims = animations.size();
-                    for (int i = 0; i < numAnims; ++i) {
+                    int i = 0;
+                    while (i < numAnims) {
                         ValueAnimator anim = animations.get(i);
                         if (anim.animationFrame(currentTime)) {
                             endingAnims.add(anim);
                         }
+                        if (animations.size() == numAnims) {
+                            ++i;
+                        } else {
+                            // An animation might be canceled or ended by client code
+                            // during the animation frame. Check to see if this happened by
+                            // seeing whether the current index is the same as it was before
+                            // calling animationFrame(). Another approach would be to copy
+                            // animations to a temporary list and process that list instead,
+                            // but that entails garbage and processing overhead that would
+                            // be nice to avoid.
+                            --numAnims;
+                            endingAnims.remove(anim);
+                        }
                     }
                     if (endingAnims.size() > 0) {
-                        for (int i = 0; i < endingAnims.size(); ++i) {
+                        for (i = 0; i < endingAnims.size(); ++i) {
                             endingAnims.get(i).endAnimation();
                         }
                         endingAnims.clear();
@@ -918,9 +929,7 @@
         // to run
         if (mPlayingState != STOPPED || sPendingAnimations.get().contains(this) ||
                 sDelayedAnims.get().contains(this)) {
-            // Just set the CANCELED flag - this causes the animation to end the next time a frame
-            // is processed.
-            mPlayingState = CANCELED;
+            endAnimation();
         }
     }
 
@@ -929,23 +938,21 @@
         if (!sAnimations.get().contains(this) && !sPendingAnimations.get().contains(this)) {
             // Special case if the animation has not yet started; get it ready for ending
             mStartedDelay = false;
-            sPendingAnimations.get().add(this);
-            AnimationHandler animationHandler = sAnimationHandler.get();
-            if (animationHandler == null) {
-                animationHandler = new AnimationHandler();
-                sAnimationHandler.set(animationHandler);
-            }
-            animationHandler.sendEmptyMessage(ANIMATION_START);
+            startAnimation();
         }
-        // Just set the ENDED flag - this causes the animation to end the next time a frame
-        // is processed.
-        mPlayingState = ENDED;
+        // The final value set on the target varies, depending on whether the animation
+        // was supposed to repeat an odd number of times
+        if (mRepeatCount > 0 && (mRepeatCount & 0x01) == 1) {
+            animateValue(0f);
+        } else {
+            animateValue(1f);
+        }
+        endAnimation();
     }
 
     @Override
     public boolean isRunning() {
-        // ENDED or CANCELED indicate that it has been ended or canceled, but not processed yet
-        return (mPlayingState == RUNNING || mPlayingState == ENDED || mPlayingState == CANCELED);
+        return (mPlayingState == RUNNING);
     }
 
     /**
@@ -973,6 +980,8 @@
      */
     private void endAnimation() {
         sAnimations.get().remove(this);
+        sPendingAnimations.get().remove(this);
+        sDelayedAnims.get().remove(this);
         mPlayingState = STOPPED;
         if (mListeners != null) {
             ArrayList<AnimatorListener> tmpListeners =
@@ -1014,10 +1023,6 @@
      * should be added to the set of active animations.
      */
     private boolean delayedAnimationFrame(long currentTime) {
-        if (mPlayingState == CANCELED || mPlayingState == ENDED) {
-            // end the delay, process an animation frame to actually cancel it
-            return true;
-        }
         if (!mStartedDelay) {
             mStartedDelay = true;
             mDelayStartTime = currentTime;
@@ -1088,19 +1093,6 @@
             }
             animateValue(fraction);
             break;
-        case ENDED:
-            // The final value set on the target varies, depending on whether the animation
-            // was supposed to repeat an odd number of times
-            if (mRepeatCount > 0 && (mRepeatCount & 0x01) == 1) {
-                animateValue(0f);
-            } else {
-                animateValue(1f);
-            }
-            // Fall through to set done flag
-        case CANCELED:
-            done = true;
-            mPlayingState = STOPPED;
-            break;
         }
 
         return done;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index d2de382..f1842c6 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -532,10 +532,6 @@
         throw new RuntimeException("Not supported in system context");
     }
 
-    static File makeBackupFile(File prefsFile) {
-        return new File(prefsFile.getPath() + ".bak");
-    }
-
     public File getSharedPrefsFile(String name) {
         return makeFilename(getPreferencesDir(), name + ".xml");
     }
@@ -543,54 +539,19 @@
     @Override
     public SharedPreferences getSharedPreferences(String name, int mode) {
         SharedPreferencesImpl sp;
-        File prefsFile;
-        boolean needInitialLoad = false;
         synchronized (sSharedPrefs) {
             sp = sSharedPrefs.get(name);
-            if (sp != null && !sp.hasFileChangedUnexpectedly()) {
-                return sp;
-            }
-            prefsFile = getSharedPrefsFile(name);
             if (sp == null) {
-                sp = new SharedPreferencesImpl(prefsFile, mode, null);
+                File prefsFile = getSharedPrefsFile(name);
+                sp = new SharedPreferencesImpl(prefsFile, mode);
                 sSharedPrefs.put(name, sp);
-                needInitialLoad = true;
-            }
-        }
-
-        synchronized (sp) {
-            if (needInitialLoad && sp.isLoaded()) {
-                // lost the race to load; another thread handled it
                 return sp;
             }
-            File backup = makeBackupFile(prefsFile);
-            if (backup.exists()) {
-                prefsFile.delete();
-                backup.renameTo(prefsFile);
-            }
-
-            // Debugging
-            if (prefsFile.exists() && !prefsFile.canRead()) {
-                Log.w(TAG, "Attempt to read preferences file " + prefsFile + " without permission");
-            }
-
-            Map map = null;
-            FileStatus stat = new FileStatus();
-            if (FileUtils.getFileStatus(prefsFile.getPath(), stat) && prefsFile.canRead()) {
-                try {
-                    FileInputStream str = new FileInputStream(prefsFile);
-                    map = XmlUtils.readMapXml(str);
-                    str.close();
-                } catch (XmlPullParserException e) {
-                    Log.w(TAG, "getSharedPreferences", e);
-                } catch (FileNotFoundException e) {
-                    Log.w(TAG, "getSharedPreferences", e);
-                } catch (IOException e) {
-                    Log.w(TAG, "getSharedPreferences", e);
-                }
-            }
-            sp.replace(map, stat);
         }
+        // If somebody else (some other process) changed the prefs
+        // file behind our back, we reload it.  This has been the
+        // historical (if undocumented) behavior.
+        sp.startReloadIfChangedUnexpectedly();
         return sp;
     }
 
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index 37f8738..efe527f 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -16,23 +16,18 @@
 
 package android.app;
 
+import com.android.internal.R;
+
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.os.Build;
 import android.os.Bundle;
-import android.text.TextUtils.TruncateAt;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.DatePicker;
-import android.widget.TextView;
 import android.widget.DatePicker.OnDateChangedListener;
 
-import com.android.internal.R;
-
-import java.text.DateFormatSymbols;
-import java.util.Calendar;
-
 /**
  * A simple dialog containing an {@link android.widget.DatePicker}.
  *
@@ -48,13 +43,6 @@
 
     private final DatePicker mDatePicker;
     private final OnDateSetListener mCallBack;
-    private final Calendar mCalendar;
-    private final java.text.DateFormat mTitleDateFormat;
-    private final String[] mWeekDays;
-
-    private int mInitialYear;
-    private int mInitialMonth;
-    private int mInitialDay;
 
     /**
      * The callback used to indicate the user is done filling in the date.
@@ -106,40 +94,18 @@
         super(context, theme);
 
         mCallBack = callBack;
-        mInitialYear = year;
-        mInitialMonth = monthOfYear;
-        mInitialDay = dayOfMonth;
-        DateFormatSymbols symbols = new DateFormatSymbols();
-        mWeekDays = symbols.getShortWeekdays();
-
-        mTitleDateFormat = java.text.DateFormat.
-                                getDateInstance(java.text.DateFormat.FULL);
-        mCalendar = Calendar.getInstance();
-        updateTitle(mInitialYear, mInitialMonth, mInitialDay);
 
         setButton(BUTTON_POSITIVE, context.getText(R.string.date_time_set), this);
         setButton(BUTTON_NEGATIVE, context.getText(R.string.cancel), (OnClickListener) null);
-        setIcon(R.drawable.ic_dialog_time);
+        setIcon(0);
+        setTitle(R.string.date_picker_dialog_title);
 
         LayoutInflater inflater =
                 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         View view = inflater.inflate(R.layout.date_picker_dialog, null);
         setView(view);
         mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
-        mDatePicker.init(mInitialYear, mInitialMonth, mInitialDay, this);
-    }
-
-    @Override
-    public void show() {
-        super.show();
-
-        /* Sometimes the full month is displayed causing the title
-         * to be very long, in those cases ensure it doesn't wrap to
-         * 2 lines (as that looks jumpy) and ensure we ellipsize the end.
-         */
-        TextView title = (TextView) findViewById(R.id.alertTitle);
-        title.setSingleLine();
-        title.setEllipsize(TruncateAt.END);
+        mDatePicker.init(year, monthOfYear, dayOfMonth, this);
     }
 
     public void onClick(DialogInterface dialog, int which) {
@@ -152,23 +118,13 @@
 
     public void onDateChanged(DatePicker view, int year,
             int month, int day) {
-        updateTitle(year, month, day);
+        mDatePicker.init(year, month, day, null);
     }
 
     public void updateDate(int year, int monthOfYear, int dayOfMonth) {
-        mInitialYear = year;
-        mInitialMonth = monthOfYear;
-        mInitialDay = dayOfMonth;
         mDatePicker.updateDate(year, monthOfYear, dayOfMonth);
     }
 
-    private void updateTitle(int year, int month, int day) {
-        mCalendar.set(Calendar.YEAR, year);
-        mCalendar.set(Calendar.MONTH, month);
-        mCalendar.set(Calendar.DAY_OF_MONTH, day);
-        setTitle(mTitleDateFormat.format(mCalendar.getTime()));
-    }
-
     @Override
     public Bundle onSaveInstanceState() {
         Bundle state = super.onSaveInstanceState();
@@ -185,6 +141,5 @@
         int month = savedInstanceState.getInt(MONTH);
         int day = savedInstanceState.getInt(DAY);
         mDatePicker.init(year, month, day, this);
-        updateTitle(year, month, day);
     }
 }
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index a807d3b..8aee65c 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -25,9 +25,12 @@
 import com.google.android.collect.Maps;
 import com.android.internal.util.XmlUtils;
 
+import dalvik.system.BlockGuard;
+
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -61,32 +64,88 @@
 
     private final Object mWritingToDiskLock = new Object();
     private static final Object mContent = new Object();
-    private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners;
+    private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners =
+            new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
 
-    SharedPreferencesImpl(
-        File file, int mode, Map initialContents) {
+    SharedPreferencesImpl(File file, int mode) {
         mFile = file;
-        mBackupFile = ContextImpl.makeBackupFile(file);
+        mBackupFile = makeBackupFile(file);
         mMode = mode;
-        mLoaded = initialContents != null;
-        mMap = initialContents != null ? initialContents : new HashMap<String, Object>();
-        FileStatus stat = new FileStatus();
-        if (FileUtils.getFileStatus(file.getPath(), stat)) {
-            mStatTimestamp = stat.mtime;
-        }
-        mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
+        mLoaded = false;
+        mMap = null;
+        startLoadFromDisk();
     }
 
-    // Has this SharedPreferences ever had values assigned to it?
-    boolean isLoaded() {
+    private void startLoadFromDisk() {
         synchronized (this) {
-            return mLoaded;
+            mLoaded = false;
+        }
+        new Thread("SharedPreferencesImpl-load") {
+            public void run() {
+                synchronized (SharedPreferencesImpl.this) {
+                    loadFromDiskLocked();
+                }
+            }
+        }.start();
+    }
+
+    private void loadFromDiskLocked() {
+        if (mLoaded) {
+            return;
+        }
+        if (mBackupFile.exists()) {
+            mFile.delete();
+            mBackupFile.renameTo(mFile);
+        }
+
+        // Debugging
+        if (mFile.exists() && !mFile.canRead()) {
+            Log.w(TAG, "Attempt to read preferences file " + mFile + " without permission");
+        }
+
+        Map map = null;
+        FileStatus stat = new FileStatus();
+        if (FileUtils.getFileStatus(mFile.getPath(), stat) && mFile.canRead()) {
+            try {
+                FileInputStream str = new FileInputStream(mFile);
+                map = XmlUtils.readMapXml(str);
+                str.close();
+            } catch (XmlPullParserException e) {
+                Log.w(TAG, "getSharedPreferences", e);
+            } catch (FileNotFoundException e) {
+                Log.w(TAG, "getSharedPreferences", e);
+            } catch (IOException e) {
+                Log.w(TAG, "getSharedPreferences", e);
+            }
+        }
+        mLoaded = true;
+        if (map != null) {
+            mMap = map;
+            mStatTimestamp = stat.mtime;
+            mStatSize = stat.size;
+        } else {
+            mMap = new HashMap<String, Object>();
+        }
+        notifyAll();
+    }
+
+    private static File makeBackupFile(File prefsFile) {
+        return new File(prefsFile.getPath() + ".bak");
+    }
+
+    void startReloadIfChangedUnexpectedly() {
+        synchronized (this) {
+            // TODO: wait for any pending writes to disk?
+            if (!hasFileChangedUnexpectedly()) {
+                return;
+            }
+            startLoadFromDisk();
         }
     }
 
     // Has the file changed out from under us?  i.e. writes that
     // we didn't instigate.
-    public boolean hasFileChangedUnexpectedly() {
+    private boolean hasFileChangedUnexpectedly() {
         synchronized (this) {
             if (mDiskWritesInFlight > 0) {
                 // If we know we caused it, it's not unexpected.
@@ -103,19 +162,6 @@
         }
     }
 
-    /*package*/ void replace(Map newContents, FileStatus stat) {
-        synchronized (this) {
-            mLoaded = true;
-            if (newContents != null) {
-                mMap = newContents;
-            }
-            if (stat != null) {
-                mStatTimestamp = stat.mtime;
-                mStatSize = stat.size;
-            }
-        }
-    }
-
     public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
         synchronized(this) {
             mListeners.put(listener, mContent);
@@ -128,8 +174,24 @@
         }
     }
 
+    private void awaitLoadedLocked() {
+        if (!mLoaded) {
+            // Raise an explicit StrictMode onReadFromDisk for this
+            // thread, since the real read will be in a different
+            // thread and otherwise ignored by StrictMode.
+            BlockGuard.getThreadPolicy().onReadFromDisk();
+        }
+        while (!mLoaded) {
+            try {
+                wait();
+            } catch (InterruptedException unused) {
+            }
+        }
+    }
+
     public Map<String, ?> getAll() {
-        synchronized(this) {
+        synchronized (this) {
+            awaitLoadedLocked();
             //noinspection unchecked
             return new HashMap<String, Object>(mMap);
         }
@@ -137,6 +199,7 @@
 
     public String getString(String key, String defValue) {
         synchronized (this) {
+            awaitLoadedLocked();
             String v = (String)mMap.get(key);
             return v != null ? v : defValue;
         }
@@ -144,6 +207,7 @@
 
     public Set<String> getStringSet(String key, Set<String> defValues) {
         synchronized (this) {
+            awaitLoadedLocked();
             Set<String> v = (Set<String>) mMap.get(key);
             return v != null ? v : defValues;
         }
@@ -151,24 +215,28 @@
 
     public int getInt(String key, int defValue) {
         synchronized (this) {
+            awaitLoadedLocked();
             Integer v = (Integer)mMap.get(key);
             return v != null ? v : defValue;
         }
     }
     public long getLong(String key, long defValue) {
         synchronized (this) {
+            awaitLoadedLocked();
             Long v = (Long)mMap.get(key);
             return v != null ? v : defValue;
         }
     }
     public float getFloat(String key, float defValue) {
         synchronized (this) {
+            awaitLoadedLocked();
             Float v = (Float)mMap.get(key);
             return v != null ? v : defValue;
         }
     }
     public boolean getBoolean(String key, boolean defValue) {
         synchronized (this) {
+            awaitLoadedLocked();
             Boolean v = (Boolean)mMap.get(key);
             return v != null ? v : defValue;
         }
@@ -176,11 +244,23 @@
 
     public boolean contains(String key) {
         synchronized (this) {
+            awaitLoadedLocked();
             return mMap.containsKey(key);
         }
     }
 
     public Editor edit() {
+        // TODO: remove the need to call awaitLoadedLocked() when
+        // requesting an editor.  will require some work on the
+        // Editor, but then we should be able to do:
+        //
+        //      context.getSharedPreferences(..).edit().putString(..).apply()
+        //
+        // ... all without blocking.
+        synchronized (this) {
+            awaitLoadedLocked();
+        }
+
         return new EditorImpl();
     }
 
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 27be51a..b27f4cf 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -803,7 +803,7 @@
      *
      * @param intent The Intent to broadcast; all receivers matching this
      *               Intent will receive the broadcast.
-     * @param receiverPermission (optional) String naming a permissions that
+     * @param receiverPermission (optional) String naming a permission that
      *               a receiver must hold in order to receive your broadcast.
      *               If null, no permission is required.
      *
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 1b799ae..4a75514 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -1532,7 +1532,7 @@
      * </ul>
      *
      * <p>
-     * <center><img src="../../../images/axis_device_inverted.png"
+     * <center><img src="../../../images/axis_globe_inverted.png"
      * alt="Inverted world coordinate-system diagram." border="0" /></center>
      * </p>
      * <p>
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ecfa2c1..3d685cb 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -212,10 +212,13 @@
      * default connections.
      */
     public static final int TYPE_WIMAX       = 6;
+
+    /** {@hide} */
+    public static final int TYPE_DUMMY       = 7;
     /** {@hide} TODO: Need to adjust this for WiMAX. */
     public static final int MAX_RADIO_TYPE   = TYPE_WIFI;
     /** {@hide} TODO: Need to adjust this for WiMAX. */
-    public static final int MAX_NETWORK_TYPE = TYPE_MOBILE_HIPRI;
+    public static final int MAX_NETWORK_TYPE = TYPE_DUMMY;
 
     public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
 
diff --git a/core/java/android/net/DummyDataStateTracker.java b/core/java/android/net/DummyDataStateTracker.java
new file mode 100644
index 0000000..daa1c09
--- /dev/null
+++ b/core/java/android/net/DummyDataStateTracker.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+package android.net;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+import android.net.NetworkInfo.DetailedState;
+import android.net.NetworkInfo;
+import android.net.LinkProperties;
+import android.util.Slog;
+
+/**
+ * A dummy data state tracker for use when we don't have a real radio
+ * connection.  useful when bringing up a board or when you have network
+ * access through other means.
+ *
+ * {@hide}
+ */
+public class DummyDataStateTracker implements NetworkStateTracker {
+
+    private static final String TAG = "DummyDataStateTracker";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false;
+
+    private NetworkInfo mNetworkInfo;
+    private boolean mTeardownRequested = false;
+    private Handler mTarget;
+    private Context mContext;
+    private LinkProperties mLinkProperties;
+    private LinkCapabilities mLinkCapabilities;
+    private boolean mPrivateDnsRouteSet = false;
+    private boolean mDefaultRouteSet = false;
+
+    // DEFAULT and HIPRI are the same connection.  If we're one of these we need to check if
+    // the other is also disconnected before we reset sockets
+    private boolean mIsDefaultOrHipri = false;
+
+    /**
+     * Create a new DummyDataStateTracker
+     * @param netType the ConnectivityManager network type
+     * @param tag the name of this network
+     */
+    public DummyDataStateTracker(int netType, String tag) {
+        mNetworkInfo = new NetworkInfo(netType);
+    }
+
+    /**
+     * Begin monitoring data connectivity.
+     *
+     * @param context is the current Android context
+     * @param target is the Handler to which to return the events.
+     */
+    public void startMonitoring(Context context, Handler target) {
+        mTarget = target;
+        mContext = context;
+    }
+
+    /**
+     * Return the IP addresses of the DNS servers available for the mobile data
+     * network interface.
+     * @return a list of DNS addresses, with no holes.
+     */
+    public String[] getDnsPropNames() {
+        return new String[0];
+    }
+
+    public boolean isPrivateDnsRouteSet() {
+        return mPrivateDnsRouteSet;
+    }
+
+    public void privateDnsRouteSet(boolean enabled) {
+        mPrivateDnsRouteSet = enabled;
+    }
+
+    public NetworkInfo getNetworkInfo() {
+        return mNetworkInfo;
+    }
+
+    public int getDefaultGatewayAddr() {
+        return 0;
+    }
+
+    public boolean isDefaultRouteSet() {
+        return mDefaultRouteSet;
+    }
+
+    public void defaultRouteSet(boolean enabled) {
+        mDefaultRouteSet = enabled;
+    }
+
+    /**
+     * This is not implemented.
+     */
+    public void releaseWakeLock() {
+    }
+
+    /**
+     * Report whether data connectivity is possible.
+     */
+    public boolean isAvailable() {
+        return true;
+    }
+
+    /**
+     * Return the system properties name associated with the tcp buffer sizes
+     * for this network.
+     */
+    public String getTcpBufferSizesPropName() {
+        return "net.tcp.buffersize.unknown";
+    }
+
+    /**
+     * Tear down mobile data connectivity, i.e., disable the ability to create
+     * mobile data connections.
+     * TODO - make async and return nothing?
+     */
+    public boolean teardown() {
+        setDetailedState(NetworkInfo.DetailedState.DISCONNECTING, "disabled", null);
+        setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, "disabled", null);
+        return true;
+    }
+
+    /**
+     * Record the detailed state of a network, and if it is a
+     * change from the previous state, send a notification to
+     * any listeners.
+     * @param state the new @{code DetailedState}
+     * @param reason a {@code String} indicating a reason for the state change,
+     * if one was supplied. May be {@code null}.
+     * @param extraInfo optional {@code String} providing extra information about the state change
+     */
+    private void setDetailedState(NetworkInfo.DetailedState state, String reason,
+            String extraInfo) {
+        if (DBG) log("setDetailed state, old ="
+                + mNetworkInfo.getDetailedState() + " and new state=" + state);
+        mNetworkInfo.setDetailedState(state, reason, extraInfo);
+        Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
+        msg.sendToTarget();
+    }
+
+    public void setTeardownRequested(boolean isRequested) {
+        mTeardownRequested = isRequested;
+    }
+
+    public boolean isTeardownRequested() {
+        return mTeardownRequested;
+    }
+
+    /**
+     * Re-enable mobile data connectivity after a {@link #teardown()}.
+     * TODO - make async and always get a notification?
+     */
+    public boolean reconnect() {
+        setDetailedState(NetworkInfo.DetailedState.CONNECTING, "enabled", null);
+        setDetailedState(NetworkInfo.DetailedState.CONNECTED, "enabled", null);
+        setTeardownRequested(false);
+        return true;
+    }
+
+    /**
+     * Turn on or off the mobile radio. No connectivity will be possible while the
+     * radio is off. The operation is a no-op if the radio is already in the desired state.
+     * @param turnOn {@code true} if the radio should be turned on, {@code false} if
+     */
+    public boolean setRadio(boolean turnOn) {
+        return true;
+    }
+
+    public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
+        return -1;
+    }
+
+    public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
+        return -1;
+    }
+
+    public void setDataEnable(boolean enabled) {
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer("Dummy data state: none, dummy!");
+        return sb.toString();
+    }
+
+    /**
+     * @see android.net.NetworkStateTracker#getLinkProperties()
+     */
+    public LinkProperties getLinkProperties() {
+        return new LinkProperties(mLinkProperties);
+    }
+
+    /**
+     * @see android.net.NetworkStateTracker#getLinkCapabilities()
+     */
+    public LinkCapabilities getLinkCapabilities() {
+        return new LinkCapabilities(mLinkCapabilities);
+    }
+
+    static private void log(String s) {
+        Slog.d(TAG, s);
+    }
+
+    static private void loge(String s) {
+        Slog.e(TAG, s);
+    }
+}
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 4df8db5..b3a354f 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -20,14 +20,21 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Messenger;
 import android.os.RemoteException;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.ServiceManager;
+
+import com.android.internal.telephony.DataConnectionTracker;
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.AsyncChannel;
+
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkInfo;
 import android.net.LinkProperties;
@@ -67,6 +74,10 @@
     // the other is also disconnected before we reset sockets
     private boolean mIsDefaultOrHipri = false;
 
+    private Handler mHandler;
+    private AsyncChannel mDataConnectionTrackerAc;
+    private Messenger mMessenger;
+
     /**
      * Create a new MobileDataStateTracker
      * @param netType the ConnectivityManager network type
@@ -107,14 +118,54 @@
         mTarget = target;
         mContext = context;
 
+        HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
+        handlerThread.start();
+        mHandler = new MdstHandler(handlerThread.getLooper(), this);
+
         IntentFilter filter = new IntentFilter();
         filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
         filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
+        filter.addAction(DataConnectionTracker.ACTION_DATA_CONNECTION_TRACKER_MESSENGER);
 
         mContext.registerReceiver(new MobileDataStateReceiver(), filter);
         mMobileDataState = Phone.DataState.DISCONNECTED;
     }
 
+    static class MdstHandler extends Handler {
+        private MobileDataStateTracker mMdst;
+
+        MdstHandler(Looper looper, MobileDataStateTracker mdst) {
+            super(looper);
+            mMdst = mdst;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+                        if (DBG) {
+                            mMdst.log("MdstHandler connected");
+                        }
+                        mMdst.mDataConnectionTrackerAc = (AsyncChannel) msg.obj;
+                    } else {
+                        if (DBG) {
+                            mMdst.log("MdstHandler %s NOT connected error=" + msg.arg1);
+                        }
+                    }
+                    break;
+                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+                    mMdst.log("Disconnected from DataStateTracker");
+                    mMdst.mDataConnectionTrackerAc = null;
+                    break;
+                default: {
+                    mMdst.log("Ignorning unknown message=" + msg);
+                    break;
+                }
+            }
+        }
+    }
+
     /**
      * Return the IP addresses of the DNS servers available for the mobile data
      * network interface.
@@ -179,7 +230,7 @@
                         false));
 
                 if (DBG) {
-                    log(mApnType + " Received state=" + state + ", old=" + mMobileDataState +
+                    log("Received state=" + state + ", old=" + mMobileDataState +
                         ", reason=" + (reason == null ? "(unspecified)" : reason));
                 }
                 if (mMobileDataState != state) {
@@ -265,10 +316,16 @@
                 String reason = intent.getStringExtra(Phone.FAILURE_REASON_KEY);
                 String apnName = intent.getStringExtra(Phone.DATA_APN_KEY);
                 if (DBG) {
-                    log(mApnType + "Received " + intent.getAction() +
+                    log("Received " + intent.getAction() +
                                 " broadcast" + reason == null ? "" : "(" + reason + ")");
                 }
                 setDetailedState(DetailedState.FAILED, reason, apnName);
+            } else if (intent.getAction().
+                    equals(DataConnectionTracker.ACTION_DATA_CONNECTION_TRACKER_MESSENGER)) {
+                if (DBG) log(mApnType + " got ACTION_DATA_CONNECTION_TRACKER_MESSENGER");
+                mMessenger = intent.getParcelableExtra(DataConnectionTracker.EXTRA_MESSENGER);
+                AsyncChannel ac = new AsyncChannel();
+                ac.connect(mContext, MobileDataStateTracker.this.mHandler, mMessenger);
             } else {
                 if (DBG) log("Broadcast received: ignore " + intent.getAction());
             }
@@ -488,6 +545,20 @@
         return -1;
     }
 
+    /**
+     * @param enabled
+     */
+    public void setDataEnable(boolean enabled) {
+        try {
+            log("setDataEnable: E enabled=" + enabled);
+            mDataConnectionTrackerAc.sendMessage(DataConnectionTracker.CMD_SET_DATA_ENABLE,
+                    enabled ? DataConnectionTracker.ENABLED : DataConnectionTracker.DISABLED);
+            log("setDataEnable: X enabled=" + enabled);
+        } catch (Exception e) {
+            log("setDataEnable: X mAc was null" + e);
+        }
+    }
+
     @Override
     public String toString() {
         StringBuffer sb = new StringBuffer("Mobile data state: ");
@@ -543,7 +614,7 @@
             case ConnectivityManager.TYPE_MOBILE_HIPRI:
                 return Phone.APN_TYPE_HIPRI;
             default:
-                loge("Error mapping networkType " + netType + " to apnType.");
+                sloge("Error mapping networkType " + netType + " to apnType.");
                 return null;
         }
     }
@@ -562,11 +633,15 @@
         return new LinkCapabilities(mLinkCapabilities);
     }
 
-    static private void log(String s) {
-        Slog.d(TAG, s);
+    private void log(String s) {
+        Slog.d(TAG, mApnType + ": " + s);
     }
 
-    static private void loge(String s) {
+    private void loge(String s) {
+        Slog.e(TAG, mApnType + ": " + s);
+    }
+
+    static private void sloge(String s) {
         Slog.e(TAG, s);
     }
 }
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 8afdcee..e378506 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -169,6 +169,11 @@
     public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid);
 
     /**
+     * @param enabled
+     */
+    public void setDataEnable(boolean enabled);
+
+    /**
      * -------------------------------------------------------------
      * Storage API used by ConnectivityService for saving
      * Network specific information.
@@ -204,5 +209,4 @@
      * Indicate tear down requested from connectivity
      */
     public void setTeardownRequested(boolean isRequested);
-
 }
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 04304dd..ad05496 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -154,6 +154,7 @@
                 case TagTechnology.NFC_V: {
                     return new NfcV(adapter, this, extras);
                 }
+                case TagTechnology.MIFARE_CLASSIC_NDEF:
                 case TagTechnology.TYPE_1:
                 case TagTechnology.TYPE_2:
                 case TagTechnology.TYPE_3:
diff --git a/core/java/android/nfc/technology/MifareClassic.java b/core/java/android/nfc/technology/MifareClassic.java
index c25b71f..ba3a425 100644
--- a/core/java/android/nfc/technology/MifareClassic.java
+++ b/core/java/android/nfc/technology/MifareClassic.java
@@ -36,23 +36,21 @@
  */
 public final class MifareClassic extends BasicTagTechnology {
     /**
-     * The well-known, default factory MIFARE read key.
+     * The well-known, default MIFARE read key.
      * Use this key to effectively make the payload in this sector
      * public.
      */
-    public static final byte[] DEFAULT_KEY_FACTORY =
+    public static final byte[] KEY_DEFAULT =
             {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
-    public static final byte[] DEFAULT_KEY_ZERO =
-            {(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00};
     /**
      * The well-known, default Mifare Application Directory read key.
      */
-    public static final byte[] DEFAULT_KEY_MAD =
+    public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY =
             {(byte)0xA0,(byte)0xA1,(byte)0xA2,(byte)0xA3,(byte)0xA4,(byte)0xA5};
     /**
      * The well-known, default read key for NDEF data on a Mifare Classic
      */
-    public static final byte[] DEFAULT_KEY_NFC_FORUM =
+    public static final byte[] KEY_NFC_FORUM =
             {(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7};
 
     public static final int TYPE_CLASSIC = 0;
diff --git a/core/java/android/nfc/technology/NdefFormatable.java b/core/java/android/nfc/technology/NdefFormatable.java
new file mode 100644
index 0000000..7c4f9ab
--- /dev/null
+++ b/core/java/android/nfc/technology/NdefFormatable.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+package android.nfc.technology;
+
+import android.nfc.ErrorCodes;
+import android.nfc.FormatException;
+import android.nfc.NdefMessage;
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import java.io.IOException;
+
+/**
+ * An interface to a {@link Tag} allowing to format the tag as NDEF.
+ *
+ * <p>You can acquire this kind of interface with {@link Tag#getTechnology(int)}.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Use of this class requires the {@link android.Manifest.permission#NFC}
+ * permission.
+ */
+public final class NdefFormatable extends BasicTagTechnology {
+    /**
+     * Internal constructor, to be used by NfcAdapter
+     * @hide
+     */
+    public NdefFormatable(NfcAdapter adapter, Tag tag, int tech, Bundle extras) throws RemoteException {
+        super(adapter, tag, tech);
+    }
+
+    /**
+     * Returns whether a tag can be formatted with {@link
+     * NdefFormatable#format(NdefMessage)}
+     */
+    public boolean canBeFormatted() throws IOException {
+      throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Formats a tag as NDEF, if possible. You may supply a first
+     * NdefMessage to be written on the tag.
+     */
+    public void format(NdefMessage firstMessage) throws IOException {
+      throw new UnsupportedOperationException();
+    }
+}
diff --git a/core/java/android/nfc/technology/TagTechnology.java b/core/java/android/nfc/technology/TagTechnology.java
index 2b4f74c..9dfb297 100644
--- a/core/java/android/nfc/technology/TagTechnology.java
+++ b/core/java/android/nfc/technology/TagTechnology.java
@@ -67,6 +67,11 @@
     public static final int TYPE_4 = 104;
 
     /**
+     * This object is an instance of {@link NdefFormatable}
+     */
+    public static final int NDEF_FORMATABLE = 110;
+
+    /**
      * This object is an instance of {@link MifareClassic}
      */
     public static final int MIFARE_CLASSIC = 200;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ed71da2..1e80da7 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -977,6 +977,9 @@
         public static float getFloat(ContentResolver cr, String name)
                 throws SettingNotFoundException {
             String v = getString(cr, name);
+            if (v == null) {
+                throw new SettingNotFoundException(name);
+            }
             try {
                 return Float.parseFloat(v);
             } catch (NumberFormatException e) {
@@ -1577,7 +1580,7 @@
          * Default screen rotation when no other policy applies.
          * When {@link #ACCELEROMETER_ROTATION} is zero and no on-screen Activity expresses a
          * preference, this rotation value will be used. Must be one of the
-         * {@link android.view.Surface#ROTATION_0 Surface rotation constants}. 
+         * {@link android.view.Surface#ROTATION_0 Surface rotation constants}.
          *
          * @see Display#getRotation
          */
@@ -2296,6 +2299,9 @@
         public static float getFloat(ContentResolver cr, String name)
                 throws SettingNotFoundException {
             String v = getString(cr, name);
+            if (v == null) {
+                throw new SettingNotFoundException(name);
+            }
             try {
                 return Float.parseFloat(v);
             } catch (NumberFormatException e) {
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index c05a8fe..c6ffe58 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -42,6 +42,12 @@
     public static final int EPOCH_JULIAN_DAY = 2440588;
 
     /**
+     * The Julian day of the Monday in the week of the epoch, December 29, 1969
+     * on the Gregorian calendar.
+     */
+    public static final int MONDAY_BEFORE_JULIAN_EPOCH = EPOCH_JULIAN_DAY - 3;
+
+    /**
      * True if this is an allDay event. The hour, minute, second fields are
      * all zero, and the date is displayed the same in all time zones.
      */
@@ -770,4 +776,39 @@
         millis = normalize(true);
         return millis;
     }
+
+    /**
+     * Returns the week since {@link #EPOCH_JULIAN_DAY} (Jan 1, 1970) adjusted
+     * for first day of week. This takes a julian day and the week start day and
+     * calculates which week since {@link #EPOCH_JULIAN_DAY} that day occurs in,
+     * starting at 0. *Do not* use this to compute the ISO week number for the
+     * year.
+     *
+     * @param julianDay The julian day to calculate the week number for
+     * @param firstDayOfWeek Which week day is the first day of the week, see
+     *            {@link #SUNDAY}
+     * @return Weeks since the epoch
+     */
+    public static int getWeeksSinceEpochFromJulianDay(int julianDay, int firstDayOfWeek) {
+        int diff = THURSDAY - firstDayOfWeek;
+        if (diff < 0) {
+            diff += 7;
+        }
+        int refDay = EPOCH_JULIAN_DAY - diff;
+        return (julianDay - refDay) / 7;
+    }
+
+    /**
+     * Takes a number of weeks since the epoch and calculates the Julian day of
+     * the Monday for that week. This assumes that the week containing the
+     * {@link #EPOCH_JULIAN_DAY} is considered week 0. It returns the Julian day
+     * for the Monday week weeks after the Monday of the week containing the
+     * epoch.
+     *
+     * @param week Number of weeks since the epoch
+     * @return The julian day for the Monday of the given week since the epoch
+     */
+    public static int getJulianMondayFromWeeksSinceEpoch(int week) {
+        return MONDAY_BEFORE_JULIAN_EPOCH + week * 7;
+    }
 }
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index a34fe87..53cff91 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -1101,7 +1101,9 @@
                 }
             }
 
-            if (hwInitialized || (windowShouldResize && mAttachInfo.mHardwareRenderer != null)) {
+            if (hwInitialized || (windowShouldResize &&
+                    mAttachInfo.mHardwareRenderer != null &&
+                    mAttachInfo.mHardwareRenderer.isEnabled())) {
                 mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
             }
 
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 8f92458..2c38c93 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -599,13 +599,20 @@
 
     public void addJavascriptInterface(Object obj, String interfaceName) {
         assert obj != null;
+        removeJavascriptInterface(interfaceName);
         if (mJSInterfaceMap == null) {
             mJSInterfaceMap = new HashMap<String, Object>();
         }
+        mJSInterfaceMap.put(interfaceName, obj);
+    }
+
+    public void removeJavascriptInterface(String interfaceName) {
+        if (mJSInterfaceMap == null) {
+            return;
+        }
         if (mJSInterfaceMap.containsKey(interfaceName)) {
             mJSInterfaceMap.remove(interfaceName);
         }
-        mJSInterfaceMap.put(interfaceName, obj);
     }
 
     /**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index bb8f5d7..bf8f7db 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -434,9 +434,9 @@
     private float mLastVelX;
     private float mLastVelY;
 
-    // A pointer to the native scrollable layer when dragging layers.  Only
-    // valid when mTouchMode is TOUCH_DRAG_LAYER_MODE.
+    // The id of the native layer being scrolled.
     private int mScrollingLayer;
+    private Rect mScrollingLayerRect = new Rect();
 
     // only trigger accelerated fling if the new velocity is at least
     // MINIMUM_VELOCITY_RATIO_FOR_ACCELERATION times of the previous velocity
@@ -2646,6 +2646,15 @@
     @Override
     protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX,
             boolean clampedY) {
+        // Special-case layer scrolling so that we do not trigger normal scroll
+        // updating.
+        if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
+            nativeScrollLayer(mScrollingLayer, scrollX, scrollY);
+            mScrollingLayerRect.left = scrollX;
+            mScrollingLayerRect.top = scrollY;
+            invalidate();
+            return;
+        }
         mInOverScrollMode = false;
         int maxX = computeMaxScrollX();
         int maxY = computeMaxScrollY();
@@ -3048,18 +3057,37 @@
             invalidate();  // So we draw again
 
             if (!mScroller.isFinished()) {
-                final int rangeX = computeMaxScrollX();
-                final int rangeY = computeMaxScrollY();
+                int rangeX = computeMaxScrollX();
+                int rangeY = computeMaxScrollY();
+                int overflingDistance = mOverflingDistance;
+
+                // Use the layer's scroll data if needed.
+                if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
+                    oldX = mScrollingLayerRect.left;
+                    oldY = mScrollingLayerRect.top;
+                    rangeX = mScrollingLayerRect.right;
+                    rangeY = mScrollingLayerRect.bottom;
+                    // No overscrolling for layers.
+                    overflingDistance = 0;
+                }
+
                 overScrollBy(x - oldX, y - oldY, oldX, oldY,
                         rangeX, rangeY,
-                        mOverflingDistance, mOverflingDistance, false);
+                        overflingDistance, overflingDistance, false);
 
                 if (mOverScrollGlow != null) {
                     mOverScrollGlow.absorbGlow(x, y, oldX, oldY, rangeX, rangeY);
                 }
             } else {
-                mScrollX = x;
-                mScrollY = y;
+                if (mTouchMode != TOUCH_DRAG_LAYER_MODE) {
+                    mScrollX = x;
+                    mScrollY = y;
+                } else {
+                    // Update the layer position instead of WebView.
+                    nativeScrollLayer(mScrollingLayer, x, y);
+                    mScrollingLayerRect.left = x;
+                    mScrollingLayerRect.top = y;
+                }
                 abortAnimation();
                 mPrivateHandler.removeMessages(RESUME_WEBCORE_PRIORITY);
                 WebViewCore.resumePriority();
@@ -3495,7 +3523,8 @@
      * </ul></p>
      * @param obj The class instance to bind to Javascript, null instances are
      *            ignored.
-     * @param interfaceName The name to used to expose the class in JavaScript.
+     * @param interfaceName The name to used to expose the instance in
+     *                      JavaScript.
      */
     public void addJavascriptInterface(Object obj, String interfaceName) {
         if (obj == null) {
@@ -3508,6 +3537,16 @@
     }
 
     /**
+     * Removes a previously added JavaScript interface with the given name.
+     * @param interfaceName The name of the interface to remove.
+     */
+    public void removeJavascriptInterface(String interfaceName) {
+        WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
+        arg.mInterfaceName = interfaceName;
+        mWebViewCore.sendMessage(EventHub.REMOVE_JS_INTERFACE, arg);
+    }
+
+    /**
      * Return the WebSettings object used to control the settings for this
      * WebView.
      * @return A WebSettings object that can be used to control this WebView's
@@ -4828,6 +4867,11 @@
     /* package */ void setFocusControllerActive(boolean active) {
         if (mWebViewCore == null) return;
         mWebViewCore.sendMessage(EventHub.SET_ACTIVE, active ? 1 : 0, 0);
+        // Need to send this message after the document regains focus.
+        if (active && mListBoxMessage != null) {
+            mWebViewCore.sendMessage(mListBoxMessage);
+            mListBoxMessage = null;
+        }
     }
 
     @Override
@@ -5015,14 +5059,15 @@
         startTouch(detector.getFocusX(), detector.getFocusY(), mLastTouchTime);
     }
 
+    // See if there is a layer at x, y and switch to TOUCH_DRAG_LAYER_MODE if a
+    // layer is found.
     private void startScrollingLayer(float x, float y) {
-        if (mTouchMode != TOUCH_DRAG_LAYER_MODE) {
-            int contentX = viewToContentX((int) x + mScrollX);
-            int contentY = viewToContentY((int) y + mScrollY);
-            mScrollingLayer = nativeScrollableLayer(contentX, contentY);
-            if (mScrollingLayer != 0) {
-                mTouchMode = TOUCH_DRAG_LAYER_MODE;
-            }
+        int contentX = viewToContentX((int) x + mScrollX);
+        int contentY = viewToContentY((int) y + mScrollY);
+        mScrollingLayer = nativeScrollableLayer(contentX, contentY,
+                mScrollingLayerRect);
+        if (mScrollingLayer != 0) {
+            mTouchMode = TOUCH_DRAG_LAYER_MODE;
         }
     }
 
@@ -5067,8 +5112,7 @@
         final ScaleGestureDetector detector =
                 mZoomManager.getMultiTouchGestureDetector();
 
-        if (mZoomManager.supportsMultiTouchZoom() && ev.getPointerCount() > 1 &&
-                mTouchMode != TOUCH_DRAG_LAYER_MODE) {
+        if (mZoomManager.supportsMultiTouchZoom() && ev.getPointerCount() > 1) {
             if (!detector.isInProgress() &&
                     ev.getActionMasked() != MotionEvent.ACTION_POINTER_DOWN) {
                 // Insert a fake pointer down event in order to start
@@ -5298,7 +5342,7 @@
                     if (parent != null) {
                         parent.requestDisallowInterceptTouchEvent(true);
                     }
-                    int layer = nativeScrollableLayer(contentX, contentY);
+                    int layer = nativeScrollableLayer(contentX, contentY, mScrollingLayerRect);
                     if (layer == 0) {
                         mAutoScrollX = x <= SELECT_SCROLL ? -SELECT_SCROLL
                             : x >= getViewWidth() - SELECT_SCROLL
@@ -5358,6 +5402,7 @@
                     deltaX = 0;
                     deltaY = 0;
 
+                    startScrollingLayer(x, y);
                     startDrag();
                 }
 
@@ -5426,7 +5471,6 @@
                     mUserScroll = true;
                 }
 
-                startScrollingLayer(x, y);
                 doDrag(deltaX, deltaY);
 
                 // Turn off scrollbars when dragging a layer.
@@ -5649,21 +5693,47 @@
 
     private void doDrag(int deltaX, int deltaY) {
         if ((deltaX | deltaY) != 0) {
-            if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
-                deltaX = viewToContentDimension(deltaX);
-                deltaY = viewToContentDimension(deltaY);
-                if (nativeScrollLayer(mScrollingLayer, deltaX, deltaY)) {
-                    invalidate();
-                    return;
-                }
-                // Switch to drag mode and fall through.
-                mTouchMode = TOUCH_DRAG_MODE;
-            }
+            int oldX = mScrollX;
+            int oldY = mScrollY;
+            int rangeX = computeMaxScrollX();
+            int rangeY = computeMaxScrollY();
+            int overscrollDistance = mOverscrollDistance;
 
-            final int oldX = mScrollX;
-            final int oldY = mScrollY;
-            final int rangeX = computeMaxScrollX();
-            final int rangeY = computeMaxScrollY();
+            // Check for the original scrolling layer in case we change
+            // directions.  mTouchMode might be TOUCH_DRAG_MODE if we have
+            // reached the edge of a layer but mScrollingLayer will be non-zero
+            // if we initiated the drag on a layer.
+            if (mScrollingLayer != 0) {
+                final int contentX = viewToContentDimension(deltaX);
+                final int contentY = viewToContentDimension(deltaY);
+
+                // Check the scrolling bounds to see if we will actually do any
+                // scrolling.  The rectangle is in document coordinates.
+                final int maxX = mScrollingLayerRect.right;
+                final int maxY = mScrollingLayerRect.bottom;
+                final int resultX = Math.max(0,
+                        Math.min(mScrollingLayerRect.left + contentX, maxX));
+                final int resultY = Math.max(0,
+                        Math.min(mScrollingLayerRect.top + contentY, maxY));
+
+                if (resultX != mScrollingLayerRect.left ||
+                        resultY != mScrollingLayerRect.top) {
+                    // In case we switched to dragging the page.
+                    mTouchMode = TOUCH_DRAG_LAYER_MODE;
+                    deltaX = contentX;
+                    deltaY = contentY;
+                    oldX = mScrollingLayerRect.left;
+                    oldY = mScrollingLayerRect.top;
+                    rangeX = maxX;
+                    rangeY = maxY;
+                } else {
+                    // Scroll the main page if we are not going to scroll the
+                    // layer.  This does not reset mScrollingLayer in case the
+                    // user changes directions and the layer can scroll the
+                    // other way.
+                    mTouchMode = TOUCH_DRAG_MODE;
+                }
+            }
 
             if (mOverScrollGlow != null) {
                 mOverScrollGlow.setOverScrollDeltas(deltaX, deltaY);
@@ -6062,6 +6132,21 @@
         int vx = (int) mVelocityTracker.getXVelocity();
         int vy = (int) mVelocityTracker.getYVelocity();
 
+        int scrollX = mScrollX;
+        int scrollY = mScrollY;
+        int overscrollDistance = mOverscrollDistance;
+        int overflingDistance = mOverflingDistance;
+
+        // Use the layer's scroll data if applicable.
+        if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
+            scrollX = mScrollingLayerRect.left;
+            scrollY = mScrollingLayerRect.top;
+            maxX = mScrollingLayerRect.right;
+            maxY = mScrollingLayerRect.bottom;
+            // No overscrolling for layers.
+            overscrollDistance = overflingDistance = 0;
+        }
+
         if (mSnapScrollMode != SNAP_NONE) {
             if ((mSnapScrollMode & SNAP_X) == SNAP_X) {
                 vy = 0;
@@ -6079,8 +6164,7 @@
             if (!mSelectingText) {
                 WebViewCore.resumeUpdatePicture(mWebViewCore);
             }
-            if (mScroller.springBack(mScrollX, mScrollY, 0, computeMaxScrollX(),
-                    0, computeMaxScrollY())) {
+            if (mScroller.springBack(scrollX, scrollY, 0, maxX, 0, maxY)) {
                 invalidate();
             }
             return;
@@ -6107,24 +6191,25 @@
                     + " current=" + currentVelocity
                     + " vx=" + vx + " vy=" + vy
                     + " maxX=" + maxX + " maxY=" + maxY
-                    + " mScrollX=" + mScrollX + " mScrollY=" + mScrollY);
+                    + " scrollX=" + scrollX + " scrollY=" + scrollY
+                    + " layer=" + mScrollingLayer);
         }
 
         // Allow sloppy flings without overscrolling at the edges.
-        if ((mScrollX == 0 || mScrollX == maxX) && Math.abs(vx) < Math.abs(vy)) {
+        if ((scrollX == 0 || scrollX == maxX) && Math.abs(vx) < Math.abs(vy)) {
             vx = 0;
         }
-        if ((mScrollY == 0 || mScrollY == maxY) && Math.abs(vy) < Math.abs(vx)) {
+        if ((scrollY == 0 || scrollY == maxY) && Math.abs(vy) < Math.abs(vx)) {
             vy = 0;
         }
 
-        if (mOverscrollDistance < mOverflingDistance) {
-            if ((vx > 0 && mScrollX == -mOverscrollDistance) ||
-                    (vx < 0 && mScrollX == maxX + mOverscrollDistance)) {
+        if (overscrollDistance < overflingDistance) {
+            if ((vx > 0 && scrollX == -overscrollDistance) ||
+                    (vx < 0 && scrollX == maxX + overscrollDistance)) {
                 vx = 0;
             }
-            if ((vy > 0 && mScrollY == -mOverscrollDistance) ||
-                    (vy < 0 && mScrollY == maxY + mOverscrollDistance)) {
+            if ((vy > 0 && scrollY == -overscrollDistance) ||
+                    (vy < 0 && scrollY == maxY + overscrollDistance)) {
                 vy = 0;
             }
         }
@@ -6134,8 +6219,8 @@
         mLastVelocity = velocity;
 
         // no horizontal overscroll if the content just fits
-        mScroller.fling(mScrollX, mScrollY, -vx, -vy, 0, maxX, 0, maxY,
-                maxX == 0 ? 0 : mOverflingDistance, mOverflingDistance);
+        mScroller.fling(scrollX, scrollY, -vx, -vy, 0, maxX, 0, maxY,
+                maxX == 0 ? 0 : overflingDistance, overflingDistance);
         // Duration is calculated based on velocity. With range boundaries and overscroll
         // we may not know how long the final animation will take. (Hence the deprecation
         // warning on the call below.) It's not a big deal for scroll bars but if webcore
@@ -6505,6 +6590,9 @@
     public boolean requestChildRectangleOnScreen(View child,
                                                  Rect rect,
                                                  boolean immediate) {
+        if (mNativeClass == 0) {
+            return false;
+        }
         // don't scroll while in zoom animation. When it is done, we will adjust
         // the necessary components (e.g., WebTextView if it is in editing mode)
         if (mZoomManager.isFixedLengthAnimationInProgress()) {
@@ -6940,6 +7028,7 @@
                                     mDeferTouchMode = TOUCH_DRAG_MODE;
                                     mLastDeferTouchX = x;
                                     mLastDeferTouchY = y;
+                                    startScrollingLayer(x, y);
                                     startDrag();
                                 }
                                 int deltaX = pinLocX((int) (mScrollX
@@ -6948,7 +7037,6 @@
                                 int deltaY = pinLocY((int) (mScrollY
                                         + mLastDeferTouchY - y))
                                         - mScrollY;
-                                startScrollingLayer(x, y);
                                 doDrag(deltaX, deltaY);
                                 if (deltaX != 0) mLastDeferTouchX = x;
                                 if (deltaY != 0) mLastDeferTouchY = y;
@@ -7429,8 +7517,10 @@
                 listView.setOnItemClickListener(new OnItemClickListener() {
                     public void onItemClick(AdapterView parent, View v,
                             int position, long id) {
-                        mWebViewCore.sendMessage(
-                                EventHub.SINGLE_LISTBOX_CHOICE, (int)id, 0);
+                        // Rather than sending the message right away, send it
+                        // after the page regains focus.
+                        mListBoxMessage = Message.obtain(null,
+                                EventHub.SINGLE_LISTBOX_CHOICE, (int) id, 0);
                         mListBoxDialog.dismiss();
                         mListBoxDialog = null;
                     }
@@ -7455,6 +7545,8 @@
         }
     }
 
+    private Message mListBoxMessage;
+
     /*
      * Request a dropdown menu for a listbox with multiple selection.
      *
@@ -7840,6 +7932,6 @@
     native int nativeGetBlockLeftEdge(int x, int y, float scale);
 
     // Returns a pointer to the scrollable LayerAndroid at the given point.
-    private native int      nativeScrollableLayer(int x, int y);
+    private native int      nativeScrollableLayer(int x, int y, Rect scrollRect);
     private native boolean  nativeScrollLayer(int layer, int dx, int dy);
 }
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index cc94fd0..d2c7fce 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -852,6 +852,7 @@
             "VALID_NODE_BOUNDS", // = 146
             "SAVE_WEBARCHIVE", // = 147
             "WEBKIT_DRAW_LAYERS", // = 148;
+            "REMOVE_JS_INTERFACE", // = 149;
         };
 
     class EventHub {
@@ -925,6 +926,8 @@
         // Update layers
         static final int WEBKIT_DRAW_LAYERS = 148;
 
+        static final int REMOVE_JS_INTERFACE = 149;
+
         // Network-based messaging
         static final int CLEAR_SSL_PREF_TABLE = 150;
 
@@ -1290,6 +1293,12 @@
                                     jsData.mInterfaceName);
                             break;
 
+                        case REMOVE_JS_INTERFACE:
+                            jsData = (JSInterfaceData) msg.obj;
+                            mBrowserFrame.removeJavascriptInterface(
+                                    jsData.mInterfaceName);
+                            break;
+
                         case REQUEST_EXT_REPRESENTATION:
                             mBrowserFrame.externalRepresentation(
                                     (Message) msg.obj);
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index b94dc3b..230cc51 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -580,7 +580,7 @@
         mInvZoomOverviewWidth = 1.0f / width;
     }
 
-    private float getZoomOverviewScale() {
+    /* package */ float getZoomOverviewScale() {
         return mWebView.getViewWidth() * mInvZoomOverviewWidth;
     }
 
@@ -672,7 +672,10 @@
         }
 
         public boolean onScale(ScaleGestureDetector detector) {
-            float scale = Math.round(detector.getScaleFactor() * mActualScale * 100) * 0.01f;
+            // Prevent scaling beyond overview scale.
+            float scale = Math.max(
+                Math.round(detector.getScaleFactor() * mActualScale * 100) * 0.01f,
+                getZoomOverviewScale());
             if (willScaleTriggerZoom(scale)) {
                 mPinchToZoomAnimating = true;
                 // limit the scale change per step
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 595b487..261992b 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -16,6 +16,8 @@
 
 package android.widget;
 
+import com.android.internal.R;
+
 import android.annotation.Widget;
 import android.content.Context;
 import android.content.res.TypedArray;
@@ -26,50 +28,44 @@
 import android.util.AttributeSet;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
-import android.widget.NumberPicker;
 import android.widget.NumberPicker.OnChangedListener;
 
-import com.android.internal.R;
-
-import java.text.DateFormatSymbols;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Locale;
 
 /**
  * A view for selecting a month / year / day based on a calendar like layout.
- *
- * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date Picker
- * tutorial</a>.</p>
- *
+ * <p>
+ * See the <a href="{@docRoot}
+ * resources/tutorials/views/hello-datepicker.html">Date Picker tutorial</a>.
+ * </p>
  * For a dialog using this view, see {@link android.app.DatePickerDialog}.
  */
 @Widget
 public class DatePicker extends FrameLayout {
 
     private static final int DEFAULT_START_YEAR = 1900;
+
     private static final int DEFAULT_END_YEAR = 2100;
 
-    // This ignores Undecimber, but we only support real Gregorian calendars.
-    private static final int NUMBER_OF_MONTHS = 12;
-
-    /* UI Components */
     private final NumberPicker mDayPicker;
+
     private final NumberPicker mMonthPicker;
+
     private final NumberPicker mYearPicker;
 
-    /**
-     * How we notify users the date has changed.
-     */
-    private OnDateChangedListener mOnDateChangedListener;
-    
-    private int mDay;
-    private int mMonth;
-    private int mYear;
+    private final DayPicker mMiniMonthDayPicker;
 
-    private Object mMonthUpdateLock = new Object();
-    private volatile Locale mMonthLocale;
-    private String[] mShortMonths;
+    private OnDateChangedListener mOnDateChangedListener;
+
+    private Locale mMonthLocale;
+
+    private final Calendar mTempCalendar = Calendar.getInstance();
+
+    private final int mNumberOfMonths = mTempCalendar.getActualMaximum(Calendar.MONTH) + 1;
+
+    private final String[] mShortMonths = new String[mNumberOfMonths];
 
     /**
      * The callback used to indicate the user changes the date.
@@ -80,7 +76,7 @@
          * @param view The view associated with this listener.
          * @param year The year that was set.
          * @param monthOfYear The month that was set (0-11) for compatibility
-         *  with {@link java.util.Calendar}.
+         *            with {@link java.util.Calendar}.
          * @param dayOfMonth The day of the month that was set.
          */
         void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth);
@@ -89,7 +85,7 @@
     public DatePicker(Context context) {
         this(context, null);
     }
-    
+
     public DatePicker(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
@@ -97,103 +93,85 @@
     public DatePicker(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
-        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        LayoutInflater inflater = (LayoutInflater) context
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         inflater.inflate(R.layout.date_picker, this, true);
 
+        OnChangedListener onChangeListener = new OnChangedListener() {
+            public void onChanged(NumberPicker picker, int oldVal, int newVal) {
+                notifyDateChanged();
+                updateMiniMonth();
+            }
+        };
+
+        // day
         mDayPicker = (NumberPicker) findViewById(R.id.day);
         mDayPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
         mDayPicker.setSpeed(100);
-        mDayPicker.setOnChangeListener(new OnChangedListener() {
-            public void onChanged(NumberPicker picker, int oldVal, int newVal) {
-                mDay = newVal;
-                notifyDateChanged();
-            }
-        });
+        mDayPicker.setOnChangeListener(onChangeListener);
+
+        // month
         mMonthPicker = (NumberPicker) findViewById(R.id.month);
-        mMonthPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
-        final String[] months = getShortMonths();
-
-        /*
-         * If the user is in a locale where the month names are numeric,
-         * use just the number instead of the "month" character for
-         * consistency with the other fields.
-         */
-        if (months[0].startsWith("1")) {
-            for (int i = 0; i < months.length; i++) {
-                months[i] = String.valueOf(i + 1);
-            }
-            mMonthPicker.setRange(1, NUMBER_OF_MONTHS);
-        } else {
-            mMonthPicker.setRange(1, NUMBER_OF_MONTHS, months);
-        }
-
+        mMonthPicker.setRange(0, mNumberOfMonths - 1, getShortMonths());
         mMonthPicker.setSpeed(200);
-        mMonthPicker.setOnChangeListener(new OnChangedListener() {
-            public void onChanged(NumberPicker picker, int oldVal, int newVal) {
-                
-                /* We display the month 1-12 but store it 0-11 so always
-                 * subtract by one to ensure our internal state is always 0-11
-                 */
-                mMonth = newVal - 1;
-                // Adjust max day of the month
-                adjustMaxDay();
-                notifyDateChanged();
-                updateDaySpinner();
-            }
-        });
+        mMonthPicker.setOnChangeListener(onChangeListener);
+
+        // year
         mYearPicker = (NumberPicker) findViewById(R.id.year);
         mYearPicker.setSpeed(100);
-        mYearPicker.setOnChangeListener(new OnChangedListener() {
-            public void onChanged(NumberPicker picker, int oldVal, int newVal) {
-                mYear = newVal;
-                // Adjust max day for leap years if needed
-                adjustMaxDay();
-                notifyDateChanged();
-                updateDaySpinner();
-            }
-        });
-        
-        // attributes
+        mYearPicker.setOnChangeListener(onChangeListener);
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker);
-
         int mStartYear = a.getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR);
         int mEndYear = a.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
         mYearPicker.setRange(mStartYear, mEndYear);
-        
         a.recycle();
+
+        // mini-month day-picker
+        mMiniMonthDayPicker = (DayPicker) findViewById(R.id.mini_month_day_picker);
+        mTempCalendar.clear();
+        mTempCalendar.set(mStartYear, 0, 1);
+        Calendar endRangeDate = (Calendar) mTempCalendar.clone();
+        endRangeDate.set(mEndYear, 11, 31);
+        mMiniMonthDayPicker.setRange(mTempCalendar, endRangeDate);
+        mMiniMonthDayPicker.setOnDateChangeListener(new DayPicker.OnSelectedDayChangeListener() {
+            public void onSelectedDayChange(DayPicker view, int year, int month, int monthDay) {
+                updateDate(year, month, monthDay);
+            }
+        });
         
         // initialize to current date
-        Calendar cal = Calendar.getInstance();
-        init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), null);
-        
+        mTempCalendar.setTimeInMillis(System.currentTimeMillis());
+        init(mTempCalendar.get(Calendar.YEAR), mTempCalendar.get(Calendar.MONTH),
+                mTempCalendar.get(Calendar.DAY_OF_MONTH), null);
+
         // re-order the number pickers to match the current date format
-        reorderPickers(months);
-        
-        if (!isEnabled()) {
-            setEnabled(false);
-        }
+        reorderPickers();
     }
-    
+
     @Override
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
         mDayPicker.setEnabled(enabled);
         mMonthPicker.setEnabled(enabled);
         mYearPicker.setEnabled(enabled);
+        mMiniMonthDayPicker.setEnabled(enabled);
     }
 
-    private void reorderPickers(String[] months) {
+    /**
+     * Reorders the pickers according to the date format in the current locale.
+     */
+    private void reorderPickers() {
         java.text.DateFormat format;
         String order;
 
         /*
-         * If the user is in a locale where the medium date format is
-         * still numeric (Japanese and Czech, for example), respect
-         * the date format order setting.  Otherwise, use the order
-         * that the locale says is appropriate for a spelled-out date.
+         * If the user is in a locale where the medium date format is still
+         * numeric (Japanese and Czech, for example), respect the date format
+         * order setting. Otherwise, use the order that the locale says is
+         * appropriate for a spelled-out date.
          */
 
-        if (months[0].startsWith("1")) {
+        if (getShortMonths()[0].startsWith("1")) {
             format = DateFormat.getDateFormat(getContext());
         } else {
             format = DateFormat.getMediumDateFormat(getContext());
@@ -206,10 +184,11 @@
             order = new String(DateFormat.getDateFormatOrder(getContext()));
         }
 
-        /* Remove the 3 pickers from their parent and then add them back in the
+        /*
+         * Remove the 3 pickers from their parent and then add them back in the
          * required order.
          */
-        LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
+        LinearLayout parent = (LinearLayout) findViewById(R.id.pickers);
         parent.removeAllViews();
 
         boolean quoted = false;
@@ -230,7 +209,7 @@
                     parent.addView(mMonthPicker);
                     didMonth = true;
                 } else if (c == DateFormat.YEAR && !didYear) {
-                    parent.addView (mYearPicker);
+                    parent.addView(mYearPicker);
                     didYear = true;
                 }
             }
@@ -248,40 +227,145 @@
         }
     }
 
-    public void updateDate(int year, int monthOfYear, int dayOfMonth) {
-        if (mYear != year || mMonth != monthOfYear || mDay != dayOfMonth) {
-            mYear = year;
-            mMonth = monthOfYear;
-            mDay = dayOfMonth;
-            updateSpinners();
-            reorderPickers(getShortMonths());
+    /**
+     * Updates the current date.
+     *
+     * @param year The year.
+     * @param month The month which is <strong>starting from zero</strong>.
+     * @param dayOfMonth The day of the month.
+     */
+    public void updateDate(int year, int month, int dayOfMonth) {
+        if (mYearPicker.getCurrent() != year
+                || mDayPicker.getCurrent() != dayOfMonth
+                || mMonthPicker.getCurrent() != month) {
+            updatePickers(year, month, dayOfMonth);
+            updateMiniMonth();
             notifyDateChanged();
         }
     }
 
+    /**
+     * @return The short month abbreviations.
+     */
     private String[] getShortMonths() {
         final Locale currentLocale = Locale.getDefault();
-        if (currentLocale.equals(mMonthLocale) && mShortMonths != null) {
+        if (currentLocale.equals(mMonthLocale)) {
             return mShortMonths;
         } else {
-            synchronized (mMonthUpdateLock) {
-                if (!currentLocale.equals(mMonthLocale)) {
-                    mShortMonths = new String[NUMBER_OF_MONTHS];
-                    for (int i = 0; i < NUMBER_OF_MONTHS; i++) {
-                        mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i,
-                                DateUtils.LENGTH_MEDIUM);
-                    }
-                    mMonthLocale = currentLocale;
-                }
+            for (int i = 0; i < mNumberOfMonths; i++) {
+                mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i,
+                        DateUtils.LENGTH_MEDIUM);
             }
+            mMonthLocale = currentLocale;
             return mShortMonths;
         }
     }
 
+    // Override so we are in complete control of save / restore for this widget.
+    @Override
+    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+        dispatchThawSelfOnly(container);
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        Parcelable superState = super.onSaveInstanceState();
+        return new SavedState(superState, mYearPicker.getCurrent(), mMonthPicker.getCurrent(),
+                mDayPicker.getCurrent());
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        updatePickers(ss.mYear, ss.mMonth, ss.mDay);
+    }
+
+    /**
+     * Initialize the state. If the provided values designate an inconsistent
+     * date the values are normalized before updating the pickers.
+     *
+     * @param year The initial year.
+     * @param monthOfYear The initial month <strong>starting from zero</strong>.
+     * @param dayOfMonth The initial day of the month.
+     * @param onDateChangedListener How user is notified date is changed by
+     *            user, can be null.
+     */
+    public void init(int year, int monthOfYear, int dayOfMonth,
+            OnDateChangedListener onDateChangedListener) {
+        mOnDateChangedListener = onDateChangedListener;
+        updateDate(year, monthOfYear, dayOfMonth);
+    }
+
+    /**
+     * Updates the pickers with the given <code>year</code>, <code>month</code>,
+     * and <code>dayOfMonth</code>. If the provided values designate an inconsistent
+     * date the values are normalized before updating the pickers.
+     */
+    private void updatePickers(int year, int month, int dayOfMonth) {
+        // make sure the date is normalized
+        mTempCalendar.clear();
+        mTempCalendar.set(year, month, dayOfMonth);
+        mYearPicker.setCurrent(mTempCalendar.get(Calendar.YEAR));
+        mMonthPicker.setCurrent(mTempCalendar.get(Calendar.MONTH));
+        mDayPicker.setRange(1, mTempCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
+        mDayPicker.setCurrent(mTempCalendar.get(Calendar.DAY_OF_MONTH));
+    }
+
+    /**
+     * Updates the mini-month with the given year, month, and day selected by the
+     * number pickers.
+     */
+    private void updateMiniMonth() {
+        Calendar selectedDay = mMiniMonthDayPicker.getSelectedDay();
+        if (selectedDay.get(Calendar.YEAR) != mYearPicker.getCurrent()
+                || selectedDay.get(Calendar.MONTH) != mMonthPicker.getCurrent()
+                || selectedDay.get(Calendar.DAY_OF_MONTH) != mDayPicker.getCurrent()) {
+            mMiniMonthDayPicker.goTo(mYearPicker.getCurrent(), mMonthPicker.getCurrent(),
+                    mDayPicker.getCurrent(), false, true, false);
+        }
+    }
+
+    /**
+     * @return The selected year.
+     */
+    public int getYear() {
+        return mYearPicker.getCurrent();
+    }
+
+    /**
+     * @return The selected month.
+     */
+    public int getMonth() {
+        return mMonthPicker.getCurrent();
+    }
+
+    /**
+     * @return The selected day of month.
+     */
+    public int getDayOfMonth() {
+        return mDayPicker.getCurrent();
+    }
+
+    /**
+     * Notifies the listener, if such, for a change in the selected date.
+     */
+    private void notifyDateChanged() {
+        if (mOnDateChangedListener != null) {
+            mOnDateChangedListener.onDateChanged(DatePicker.this, mYearPicker.getCurrent(),
+                    mMonthPicker.getCurrent(), mDayPicker.getCurrent());
+        }
+    }
+
+    /**
+     * Class for managing state storing/restoring.
+     */
     private static class SavedState extends BaseSavedState {
 
         private final int mYear;
+
         private final int mMonth;
+
         private final int mDay;
 
         /**
@@ -293,7 +377,7 @@
             mMonth = month;
             mDay = day;
         }
-        
+
         /**
          * Constructor called from {@link #CREATOR}
          */
@@ -304,18 +388,6 @@
             mDay = in.readInt();
         }
 
-        public int getYear() {
-            return mYear;
-        }
-
-        public int getMonth() {
-            return mMonth;
-        }
-
-        public int getDay() {
-            return mDay;
-        }
-
         @Override
         public void writeToParcel(Parcel dest, int flags) {
             super.writeToParcel(dest, flags);
@@ -324,104 +396,17 @@
             dest.writeInt(mDay);
         }
 
-        public static final Parcelable.Creator<SavedState> CREATOR =
-                new Creator<SavedState>() {
+        @SuppressWarnings("all")
+        // suppress unused and hiding
+        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
 
-                    public SavedState createFromParcel(Parcel in) {
-                        return new SavedState(in);
-                    }
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
 
-                    public SavedState[] newArray(int size) {
-                        return new SavedState[size];
-                    }
-                };
-    }
-
-
-    /**
-     * Override so we are in complete control of save / restore for this widget.
-     */
-    @Override
-    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
-        dispatchThawSelfOnly(container);
-    }
-
-    @Override
-    protected Parcelable onSaveInstanceState() {
-        Parcelable superState = super.onSaveInstanceState();
-        
-        return new SavedState(superState, mYear, mMonth, mDay);
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Parcelable state) {
-        SavedState ss = (SavedState) state;
-        super.onRestoreInstanceState(ss.getSuperState());
-        mYear = ss.getYear();
-        mMonth = ss.getMonth();
-        mDay = ss.getDay();
-        updateSpinners();
-    }
-
-    /**
-     * Initialize the state.
-     * @param year The initial year.
-     * @param monthOfYear The initial month.
-     * @param dayOfMonth The initial day of the month.
-     * @param onDateChangedListener How user is notified date is changed by user, can be null.
-     */
-    public void init(int year, int monthOfYear, int dayOfMonth,
-            OnDateChangedListener onDateChangedListener) {
-        mYear = year;
-        mMonth = monthOfYear;
-        mDay = dayOfMonth;
-        mOnDateChangedListener = onDateChangedListener;
-        updateSpinners();
-    }
-
-    private void updateSpinners() {
-        updateDaySpinner();
-        mYearPicker.setCurrent(mYear);
-        
-        /* The month display uses 1-12 but our internal state stores it
-         * 0-11 so add one when setting the display.
-         */
-        mMonthPicker.setCurrent(mMonth + 1);
-    }
-
-    private void updateDaySpinner() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(mYear, mMonth, mDay);
-        int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
-        mDayPicker.setRange(1, max);
-        mDayPicker.setCurrent(mDay);
-    }
-
-    public int getYear() {
-        return mYear;
-    }
-
-    public int getMonth() {
-        return mMonth;
-    }
-
-    public int getDayOfMonth() {
-        return mDay;
-    }
-
-    private void adjustMaxDay(){
-        Calendar cal = Calendar.getInstance();
-        cal.set(Calendar.YEAR, mYear);
-        cal.set(Calendar.MONTH, mMonth);
-        int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
-        if (mDay > max) {
-            mDay = max;
-        }
-    }
-
-    private void notifyDateChanged() {
-        if (mOnDateChangedListener != null) {
-            mOnDateChangedListener.onDateChanged(DatePicker.this, mYear, mMonth, mDay);
-        }
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
     }
 }
diff --git a/core/java/android/widget/DayPicker.java b/core/java/android/widget/DayPicker.java
new file mode 100644
index 0000000..11c23ab
--- /dev/null
+++ b/core/java/android/widget/DayPicker.java
@@ -0,0 +1,1474 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+package android.widget;
+
+import com.android.internal.R;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.database.DataSetObserver;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.Paint.Style;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.text.format.DateFormat;
+import android.text.format.DateUtils;
+import android.text.format.Time;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.GestureDetector;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView.OnScrollListener;
+
+import java.security.InvalidParameterException;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Locale;
+
+import libcore.icu.LocaleData;
+
+/**
+ * Displays a day picker in the form of a calendar. The calendar
+ * is represented as a list where each row depicts a week. Each week is
+ * composed of items that are selectable days.
+ */
+public class DayPicker extends FrameLayout {
+
+    /**
+     * The number of milliseconds in a day.
+     *
+     * @hide
+     */
+    protected static final long MILLIS_IN_DAY = 86400000L;
+
+    /**
+     * The number of day in a week.
+     *
+     * @hide
+     */
+    protected static final int DAYS_PER_WEEK = 7;
+
+    /**
+     * The number of milliseconds in a week.
+     *
+     * @hide
+     */
+    protected static final long MILLIS_IN_WEEK = DAYS_PER_WEEK * MILLIS_IN_DAY;
+
+    /**
+     * Affects when the month selection will change while scrolling up
+     *
+     * @hide
+     */ 
+    protected static final int SCROLL_HYST_WEEKS = 2;
+
+    /**
+     * How long the GoTo fling animation should last.
+     *
+     * @hide
+     */
+    protected static final int GOTO_SCROLL_DURATION = 1000;
+
+    /**
+     * The duration of the adjustment upon a user scroll in milliseconds.
+     *
+     * @hide
+     */
+    protected static final int ADJUSTMENT_SCROLL_DURATION = 500;
+
+    /**
+     * How long to wait after receiving an onScrollStateChanged notification
+     * before acting on it.
+     *
+     * @hide
+     */
+    protected static final int SCROLL_CHANGE_DELAY = 40;
+
+    /**
+     * The scale used to compensate for different screen density.
+     *
+     * @hide
+     */
+    protected static float sScale;
+
+    /**
+     * The top offset of the weeks list.
+     *
+     * @hide
+     */
+    protected static int mListTopOffset = 2;
+
+    /**
+     * The visible height of a week view.
+     *
+     * @hide
+     */
+    protected int mWeekMinVisibleHeight = 12;
+
+
+    /**
+     * The visible height of a week view.
+     *
+     * @hide
+     */
+    protected int mBottomBuffer = 20;
+
+    /**
+     * The number of shown weeks.
+     *
+     * @hide
+     */
+    protected int mShownWeekCount = 6;
+
+    /**
+     * Flag whether to show the week number.
+     *
+     * @hide
+     */
+    protected boolean mShowWeekNumber = true;
+
+    /**
+     * The number of day per week to be shown
+     *
+     * @hide
+     */
+    protected int mDaysPerWeek = 7;
+
+    /**
+     * The friction of the week list while flinging.
+     *
+     * @hide
+     */
+    protected float mFriction = .05f;
+
+    /**
+     * Scale for adjusting velocity of the week list while flinging.
+     *
+     * @hide
+     */
+    protected float mVelocityScale = 0.333f;
+
+    /**
+     * The adapter for the weeks list.
+     *
+     * @hide
+     */
+    protected WeeksAdapter mAdapter;
+
+    /**
+     * The weeks list.
+     *
+     * @hide
+     */
+    protected ListView mListView;
+
+    /**
+     * The name of the month to display.
+     *
+     * @hide
+     */
+    protected TextView mMonthName;
+
+    /**
+     * The header with week day names.
+     *
+     * @hide
+     */
+    protected ViewGroup mDayNamesHeader;
+
+    /**
+     * Cached labels for the week names header.
+     *
+     * @hide
+     */
+    protected String[] mDayLabels;
+
+    /**
+     * Temporary instance to avoid multiple instantiations.
+     *
+     * @hide
+     */
+    protected Calendar mTempCalendar = Calendar.getInstance();
+
+    /**
+     * The first day of the week based on the current locale.
+     *
+     * @hide
+     */
+    protected int mFirstDayOfWeek = LocaleData.get(Locale.getDefault()).firstDayOfWeek;
+
+    /**
+     * The first day of the focused month.
+     *
+     * @hide
+     */
+    protected Calendar mFirstDayOfMonth = Calendar.getInstance();
+
+    /**
+     * Which month should be displayed/highlighted [0-11]
+     *
+     * @hide
+     */
+    protected int mCurrentMonthDisplayed;
+
+    /**
+     * Used for tracking during a scroll.
+     *
+     * @hide
+     */
+    protected long mPreviousScrollPosition;
+
+    /**
+     * Used for tracking which direction the view is scrolling.
+     *
+     * @hide
+     */
+    protected boolean mIsScrollingUp = false;
+
+    /**
+     * The previous scroll state of the weeks ListView.
+     *
+     * @hide
+     */
+    protected int mPreviousScrollState = OnScrollListener.SCROLL_STATE_IDLE;
+
+    /**
+     * The current scroll state of the weeks ListView.
+     *
+     * @hide
+     */
+    protected int mCurrentScrollState = OnScrollListener.SCROLL_STATE_IDLE;
+
+    /**
+     * Listener for changes in the selected day.
+     *
+     * @hide
+     */
+    protected OnSelectedDayChangeListener mOnChangeListener;
+
+    /**
+     * Command for adjusting the position after a scroll/fling.
+     *
+     * @hide
+     */
+    protected ScrollStateRunnable mScrollStateChangedRunnable = new ScrollStateRunnable();
+
+    /**
+     * The start date of the range supported by this picker.
+     *
+     * @hide
+     */
+    protected Calendar mStartRangeDate = Calendar.getInstance();
+
+    /**
+     * The end date of the range supported by this picker.
+     *
+     * @hide
+     */
+    protected Calendar mEndRangeDate = Calendar.getInstance();
+
+    /**
+     * String for formatting the month name in the title text view.
+     *
+     * @hide
+     */
+    protected String mMonthNameFormatSrting = "MMMM, yyyy";
+
+    /**
+     * The callback used to indicate the user changes the date.
+     */
+    public interface OnSelectedDayChangeListener {
+
+        /**
+         * Called upon change of the selected day.
+         *
+         * @param view The view associated with this listener.
+         * @param year The year that was set.
+         * @param month The month that was set [0-11].
+         * @param dayOfMonth The day of the month that was set.
+         */
+        public void onSelectedDayChange(DayPicker view, int year, int month, int dayOfMonth);
+    }
+
+    public DayPicker(Context context) {
+        this(context, null);
+    }
+
+    public DayPicker(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public DayPicker(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, 0);
+
+        LayoutInflater layoutInflater = (LayoutInflater) mContext
+                .getSystemService(Service.LAYOUT_INFLATER_SERVICE);
+        View content = layoutInflater.inflate(R.layout.day_picker, null, false);
+        addView(content);
+
+        mListView = (ListView) findViewById(R.id.list);
+        mDayNamesHeader = (ViewGroup) content.findViewById(com.android.internal.R.id.day_names);
+        mMonthName = (TextView) content.findViewById(com.android.internal.R.id.month_name);
+
+        // Adjust sizes for screen density
+        if (sScale == 0) {
+            sScale = mContext.getResources().getDisplayMetrics().density;
+            if (sScale != 1) {
+                mWeekMinVisibleHeight *= sScale;
+                mBottomBuffer *= sScale;
+                mListTopOffset *= sScale;
+            }
+        }
+
+        // set default range
+        mStartRangeDate.clear();
+        mStartRangeDate.set(1900, 0, 1);
+        mEndRangeDate.clear();
+        mEndRangeDate.set(2100, 0, 1);
+
+        setUpHeader();
+        updateHeader();
+        setUpListView();
+        setUpAdapter();
+
+        // go to today now
+        mTempCalendar.setTimeInMillis(System.currentTimeMillis());
+        goTo(mTempCalendar, false, true, true);
+        invalidate();
+    }
+
+    /**
+     * Sets the range supported by this day picker. This is the picker will not
+     * support dates before <code>startRangeDate</code> and <code>endRangeDate
+     * </code>.
+     *
+     * @param startRangeDate The start date.
+     * @param endRangeDate The end date.
+     */
+    public void setRange(Calendar startRangeDate, Calendar endRangeDate) {
+        boolean doSetupAdapter = false;
+        if (mStartRangeDate.get(Calendar.DAY_OF_YEAR) != startRangeDate.get(Calendar.DAY_OF_YEAR)
+                || mStartRangeDate.get(Calendar.YEAR) != startRangeDate.get(Calendar.YEAR)) {
+            mStartRangeDate = startRangeDate;
+            doSetupAdapter = true;
+        }
+        if (mEndRangeDate.get(Calendar.DAY_OF_YEAR) != endRangeDate.get(Calendar.DAY_OF_YEAR)
+                || mEndRangeDate.get(Calendar.YEAR) != endRangeDate.get(Calendar.YEAR)) {
+            mEndRangeDate = endRangeDate;
+            doSetupAdapter = true;
+            
+        }
+        if (doSetupAdapter) {
+            setUpAdapter();
+        }
+    }
+
+    /**
+     * Sets the listener to be notified upon day selection changes.
+     *
+     * @param listener The listener to be called back.
+     */
+    public void setOnDateChangeListener(OnSelectedDayChangeListener listener) {
+        mOnChangeListener = listener;
+    }
+
+    /**
+     * Gets the selected day.
+     *
+     * @return The selected day.
+     */
+    public Calendar getSelectedDay() {
+        return mAdapter.mSelectedDay;
+    }
+
+    /**
+     * Sets the selected day. This is equivalent to a call to
+     * {@link #goTo(Calendar, boolean, boolean, boolean)} with
+     * the arguments <code>selectedDay</code>, <code>false</code>,
+     * <code>true</code>, <code>false</code> respectively.
+     *
+     * @param selectedDay The selected day.
+     */
+    public void setSelectedDay(Calendar selectedDay) {
+        goTo(selectedDay, false, true, false);
+    }
+
+    /**
+     * Creates a new adapter if necessary and sets up its parameters. Override
+     * this method to provide a custom adapter.
+     *
+     * @hide
+     */
+    protected void setUpAdapter() {
+        if (mAdapter == null) {
+            mAdapter = new WeeksAdapter(getContext());
+            mAdapter.registerDataSetObserver(new DataSetObserver() {
+                @Override
+                public void onChanged() {
+                    if (mOnChangeListener != null) {
+                        Calendar selectedDay = mAdapter.getSelectedDay();
+                        mOnChangeListener.onSelectedDayChange(DayPicker.this,
+                                selectedDay.get(Calendar.YEAR),
+                                selectedDay.get(Calendar.MONTH),
+                                selectedDay.get(Calendar.DAY_OF_MONTH));
+                    }
+                }
+            });
+            mListView.setAdapter(mAdapter);
+        }
+
+        // refresh the view with the new parameters
+        mAdapter.notifyDataSetChanged();
+    }
+
+    /**
+     * Sets up the strings to be used by the header. Override this method to use
+     * different strings or modify the view params.
+     *
+     * @hide
+     */
+    protected void setUpHeader() {
+        mDayLabels = new String[mDaysPerWeek];
+        for (int i = mFirstDayOfWeek, count = mFirstDayOfWeek + mDaysPerWeek; i < count; i++) {
+            int calendarDay = (i < mDaysPerWeek) ? i : 1; // Calendar.MONDAY is
+            // 1
+            mDayLabels[i - mFirstDayOfWeek] = DateUtils.getDayOfWeekString(calendarDay,
+                    DateUtils.LENGTH_SHORTEST);
+        }
+    }
+
+    /**
+     * Sets all the required fields for the list view. Override this method to
+     * set a different list view behavior.
+     *
+     * @hide
+     */
+    protected void setUpListView() {
+        // Configure the listview
+        mListView.setDivider(null);
+        mListView.setItemsCanFocus(true);
+        mListView.setVerticalScrollBarEnabled(false);
+        mListView.setOnScrollListener(new OnScrollListener() {
+            public void onScrollStateChanged(AbsListView view, int scrollState) {
+                DayPicker.this.onScrollStateChanged(view, scrollState);
+            }
+
+            public void onScroll(
+                    AbsListView view, int firstVisibleItem, int visibleItemCount,
+                    int totalItemCount) {
+                DayPicker.this.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
+            }
+        });
+        // Make the scrolling behavior nicer
+        mListView.setFriction(mFriction);
+        mListView.setVelocityScale(mVelocityScale);
+    }
+
+    /**
+     * Fixes the day names header to provide correct spacing and updates the
+     * label text. Override this to set up a custom header.
+     *
+     * @hide
+     */
+    protected void updateHeader() {
+        TextView label = (TextView) mDayNamesHeader.getChildAt(0);
+        if (mShowWeekNumber) {
+            label.setVisibility(View.VISIBLE);
+        } else {
+            label.setVisibility(View.GONE);
+        }
+        for (int i = 1, count = mDayNamesHeader.getChildCount(); i < count; i++) {
+            label = (TextView) mDayNamesHeader.getChildAt(i);
+            if (i < mDaysPerWeek + 1) {
+                label.setText(mDayLabels[i - 1]);
+                label.setVisibility(View.VISIBLE);
+            } else {
+                label.setVisibility(View.GONE);
+            }
+        }
+        mDayNamesHeader.invalidate();
+    }
+
+    /**
+     * This moves to the specified time in the view. If the time is not already
+     * in range it will move the list so that the first of the month containing
+     * the time is at the top of the view. If the new time is already in view
+     * the list will not be scrolled unless forceScroll is true. This time may
+     * optionally be highlighted as selected as well.
+     *
+     * @param year The year to move to.
+     * @param month The month to move to <strong>starting from zero<strong>.
+     * @param dayOfMonth The month day to move to.
+     * @param animate Whether to scroll to the given time or just redraw at the
+     *            new location.
+     * @param setSelected Whether to set the given time as selected
+     * @param forceScroll Whether to recenter even if the time is already
+     *            visible.
+     */
+    public void goTo(int year, int month, int dayOfMonth, boolean animate, boolean setSelected,
+            boolean forceScroll) {
+        mTempCalendar.clear();
+        mTempCalendar.set(year, month, dayOfMonth);
+        goTo(mTempCalendar, animate, setSelected, forceScroll);
+    }
+
+    /**
+     * This moves to the specified time in the view. If the time is not already
+     * in range it will move the list so that the first of the month containing
+     * the time is at the top of the view. If the new time is already in view
+     * the list will not be scrolled unless forceScroll is true. This time may
+     * optionally be highlighted as selected as well.
+     * 
+     * @param date The time to move to.
+     * @param animate Whether to scroll to the given time or just redraw at the
+     *            new location.
+     * @param setSelected Whether to set the given time as selected.
+     * @param forceScroll Whether to recenter even if the time is already
+     *            visible.
+     */
+    public void goTo(Calendar date, boolean animate, boolean setSelected, boolean forceScroll) {
+        long timeInMillis = date.getTimeInMillis();
+        if (timeInMillis < mStartRangeDate.getTimeInMillis()
+                || timeInMillis > mEndRangeDate.getTimeInMillis()) {
+            throw new IllegalArgumentException("Time not between " + mStartRangeDate.getTime()
+                    + " and " + mEndRangeDate.getTime());
+        }
+        // Find the first and last entirely visible weeks
+        int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
+        View firstChild = mListView.getChildAt(0);
+        if (firstChild != null && firstChild.getTop() < 0) {
+            firstFullyVisiblePosition++;
+        }
+        int lastFullyVisiblePosition = firstFullyVisiblePosition + mShownWeekCount - 1;
+        if (firstChild != null && firstChild.getTop() > mBottomBuffer) {
+            lastFullyVisiblePosition--;
+        }
+        if (setSelected) {
+            mAdapter.setSelectedDay(date);
+        }
+        // Get the week we're going to
+        int position = getWeeksDelta(date);
+
+        // Check if the selected day is now outside of our visible range
+        // and if so scroll to the month that contains it
+        if (position < firstFullyVisiblePosition || position > lastFullyVisiblePosition
+                || forceScroll) {
+            mFirstDayOfMonth.setTimeInMillis(date.getTimeInMillis());
+            mFirstDayOfMonth.setTimeZone(date.getTimeZone());
+            mFirstDayOfMonth.set(Calendar.DAY_OF_MONTH, 1);
+
+            setMonthDisplayed(mFirstDayOfMonth);
+            position = getWeeksDelta(mFirstDayOfMonth);
+
+            mPreviousScrollState = OnScrollListener.SCROLL_STATE_FLING;
+            if (animate) {
+                mListView.smoothScrollToPositionFromTop(position, mListTopOffset,
+                        GOTO_SCROLL_DURATION);
+            } else {
+                mListView.setSelectionFromTop(position, mListTopOffset);
+                // Perform any after scroll operations that are needed
+                onScrollStateChanged(mListView, OnScrollListener.SCROLL_STATE_IDLE);
+            }
+        } else if (setSelected) {
+            // Otherwise just set the selection
+            setMonthDisplayed(date);
+        }
+    }
+
+    /**
+     * Called when a <code>view</code> transitions to a new <code>scrollState
+     * </code>.
+     *
+     * @hide
+     */
+    protected void onScrollStateChanged(AbsListView view, int scrollState) {
+        mScrollStateChangedRunnable.doScrollStateChange(view, scrollState);
+    }
+
+    /**
+     * Updates the title and selected month if the <code>view</code> has moved to a new
+     * month.
+     *
+     * @hide
+     */
+    protected void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+            int totalItemCount) {
+        WeekView child = (WeekView) view.getChildAt(0);
+        if (child == null) {
+            return;
+        }
+
+        // Figure out where we are
+        int offset = child.getBottom() < mWeekMinVisibleHeight ? 1 : 0;
+        long currScroll = view.getFirstVisiblePosition() * child.getHeight() - child.getBottom();
+
+        // If we have moved since our last call update the direction
+        if (currScroll < mPreviousScrollPosition) {
+            mIsScrollingUp = true;
+        } else if (currScroll > mPreviousScrollPosition) {
+            mIsScrollingUp = false;
+        } else {
+            return;
+        }
+
+        // Use some hysteresis for checking which month to highlight. This
+        // causes the month to transition when two full weeks of a month are
+        // visible when scrolling up, and when the first day in a month reaches
+        // the top of the screen when scrolling down.
+        if (mIsScrollingUp) {
+            child = (WeekView) view.getChildAt(SCROLL_HYST_WEEKS + offset);
+        } else if (offset != 0) {
+            child = (WeekView) view.getChildAt(offset);
+        }
+
+        // Find out which month we're moving into
+        int month;
+        if (mIsScrollingUp) {
+            month = child.getMonthOfFirstWeekDay();
+        } else {
+            month = child.getMonthOfLastWeekDay();
+        }
+
+        // And how it relates to our current highlighted month
+        int monthDiff;
+        if (mCurrentMonthDisplayed == 11 && month == 0) {
+            monthDiff = 1;
+        } else if (mCurrentMonthDisplayed == 0 && month == 11) {
+            monthDiff = -1;
+        } else {
+            monthDiff = month - mCurrentMonthDisplayed;
+        }
+
+        // Only switch months if we're scrolling away from the currently
+        // selected month
+        if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) {
+            Calendar firstDay = child.getFirstDay();
+            if (mIsScrollingUp) {
+                firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK);
+            } else {
+                firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK);
+            }
+            setMonthDisplayed(firstDay);
+        }
+        mPreviousScrollPosition = currScroll;
+        mPreviousScrollState = mCurrentScrollState;
+    }
+
+    /**
+     * Sets the month displayed at the top of this view based on time. Override
+     * to add custom events when the title is changed.
+     *
+     * @param calendar A day in the new focus month.
+     *
+     * @hide
+     */
+    protected void setMonthDisplayed(Calendar calendar) {
+        mMonthName.setText(DateFormat.format(mMonthNameFormatSrting, calendar));
+        mMonthName.invalidate();
+        mCurrentMonthDisplayed = calendar.get(Calendar.MONTH);
+        mAdapter.setFocusMonth(mCurrentMonthDisplayed);
+        // TODO Send Accessibility Event
+    }
+
+    /**
+     * @return Returns the number of weeks between the current week day of the
+     *         <code>fromDate</code> and the first day of week of
+     *         <code>toDate</code>.
+     *
+     * @hide
+     */
+    protected int getWeeksDelta(Calendar toDate) {
+        if (toDate.before(mStartRangeDate)) {
+            throw new IllegalArgumentException("fromDate: " + mStartRangeDate.getTime()
+                    + " does not precede toDate: " + toDate.getTime());
+        }
+        int fromDateDayOfWeek = mStartRangeDate.get(Calendar.DAY_OF_WEEK);
+        long diff = (fromDateDayOfWeek - toDate.getFirstDayOfWeek()) * MILLIS_IN_DAY;
+        if (diff < 0) {
+            diff = diff + MILLIS_IN_WEEK;
+        }
+        long refDay = mStartRangeDate.getTimeInMillis() - diff;
+        return (int) ((toDate.getTimeInMillis() - refDay) / MILLIS_IN_WEEK);
+    }
+
+    /**
+     * Command responsible for acting upon scroll state changes.
+     *
+     * @hide
+     */
+    protected class ScrollStateRunnable implements Runnable {
+        private AbsListView mView;
+
+        private int mNewState;
+
+        /**
+         * Sets up the runnable with a short delay in case the scroll state
+         * immediately changes again.
+         *
+         * @param view The list view that changed state
+         * @param scrollState The new state it changed to
+         */
+        public void doScrollStateChange(AbsListView view, int scrollState) {
+            removeCallbacks(this);
+            mView = view;
+            mNewState = scrollState;
+            removeCallbacks(this);
+            postDelayed(this, SCROLL_CHANGE_DELAY);
+        }
+
+        public void run() {
+            mCurrentScrollState = mNewState;
+            // Fix the position after a scroll or a fling ends
+            if (mNewState == OnScrollListener.SCROLL_STATE_IDLE
+                    && mPreviousScrollState != OnScrollListener.SCROLL_STATE_IDLE) {
+                mPreviousScrollState = mNewState;
+                View child = mView.getChildAt(0);
+                if (child == null) {
+                    // The view is no longer visible, just return
+                    return;
+                }
+                int dist = child.getBottom() - mListTopOffset;
+                if (dist > mListTopOffset) {
+                    if (mIsScrollingUp) {
+                        mView.smoothScrollBy(dist - child.getHeight(), ADJUSTMENT_SCROLL_DURATION);
+                    } else {
+                        mView.smoothScrollBy(dist, ADJUSTMENT_SCROLL_DURATION);
+                    }
+                }
+            } else {
+                mPreviousScrollState = mNewState;
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * This is a specialized adapter for creating a list of weeks with
+     * selectable days. It can be configured to display the week number, start
+     * the week on a given day, show a reduced number of days, or display an
+     * arbitrary number of weeks at a time.
+     * </p>
+     *
+     * @hide
+     */
+    public class WeeksAdapter extends BaseAdapter implements OnTouchListener {
+
+        /**
+         * The default maximum year supported by the Date Time Picker.
+         */
+        public static final int DEFAULT_MAX_CALENDAR_YEAR = 2100;
+
+        /**
+         * The default minimum year supported by the Date Time Picker.
+         */
+        public static final int DEFAULT_MIN_CALENDAR_YEAR = 1900;
+
+        /**
+         * The number of weeks to display at a time.
+         */
+        public static final String WEEK_PARAMS_NUM_WEEKS = "num_weeks";
+
+        /**
+         * Which month should be in focus currently.
+         */
+        public static final String WEEK_PARAMS_FOCUS_MONTH = "focus_month";
+
+        /**
+         * Whether the week number should be shown. Non-zero to show them.
+         */
+        public static final String WEEK_PARAMS_SHOW_WEEK = "week_numbers";
+
+        /**
+         * Which day the week should start on. {@link Time#SUNDAY} through
+         * {@link Time#SATURDAY}.
+         */
+        public static final String WEEK_PARAMS_WEEK_START = "week_start";
+
+        /**
+         * The year of the highlighted day.
+         */
+        public static final String WEEK_PARAMS_YEAR = "selected_year";
+
+        /**
+         * The month of the highlighted day.
+         */
+        public static final String WEEK_PARAMS_MONTH = "selected_month";
+
+        /**
+         * The year of the highlighted day.
+         */
+        public static final String WEEK_PARAMS_DAY_OF_MONTH = "selected_day_of_month";
+
+        /**
+         * The start date of the supported interval.
+         */
+        public static final String WEEK_PARAMS_START_DATE_RANGE_MILLIS = "start_date_gange_millis";
+
+        /**
+         * The end date of the supported interval.
+         */
+        public static final String WEEK_PARAMS_END_DATE_RANGE_MILLIS = "end_date_gange_millis";
+
+        /**
+         * How many days of the week to display [1-7].
+         */
+        public static final String WEEK_PARAMS_DAYS_PER_WEEK = "days_per_week";
+
+        protected int WEEK_7_OVERHANG_HEIGHT = 7;
+
+        protected int mSelectedWeek;
+
+        protected GestureDetector mGestureDetector;
+
+        protected int mFocusMonth = 0;
+
+        private final Calendar mSelectedDay = Calendar.getInstance();
+
+        private int mTotalWeekCount = -1;
+
+        public WeeksAdapter(Context context) {
+            mContext = context;
+
+            if (sScale == 0) {
+                sScale = context.getResources().getDisplayMetrics().density;
+                if (sScale != 1) {
+                    WEEK_7_OVERHANG_HEIGHT *= sScale;
+                }
+            }
+            init();
+        }
+
+        /**
+         * Set up the gesture detector and selected time
+         */
+        protected void init() {
+            mGestureDetector = new GestureDetector(mContext, new CalendarGestureListener());
+            mSelectedWeek = getWeeksDelta(mSelectedDay);
+            mTotalWeekCount = getWeeksDelta(mEndRangeDate);
+        }
+
+        /**
+         * Updates the selected day and related parameters.
+         * 
+         * @param selectedDay The time to highlight
+         */
+        public void setSelectedDay(Calendar selectedDay) {
+            if (selectedDay.get(Calendar.DAY_OF_YEAR) == mSelectedDay.get(Calendar.DAY_OF_YEAR)
+                    && selectedDay.get(Calendar.YEAR) == mSelectedDay.get(Calendar.YEAR)) {
+                return;
+            }
+            mSelectedDay.setTimeInMillis(selectedDay.getTimeInMillis());
+            mSelectedDay.setTimeZone(selectedDay.getTimeZone());
+            mSelectedWeek = getWeeksDelta(mSelectedDay);
+            mFocusMonth = mSelectedDay.get(Calendar.MONTH);
+            notifyDataSetChanged();
+            invalidate();  // Test
+        }
+
+        /**
+         * @return The selected day of month.
+         */
+        public Calendar getSelectedDay() {
+            return mSelectedDay;
+        }
+
+        /**
+         * updates any config options that may have changed and refreshes the
+         * view
+         */
+        public void refresh() {
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public int getCount() {
+            return mTotalWeekCount;
+        }
+
+        @Override
+        public Object getItem(int position) {
+            return null;
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            WeekView v;
+            HashMap<String, Object> drawingParams = null;
+            if (convertView != null) {
+                v = (WeekView) convertView;
+                // We store the drawing parameters in the view so it can be
+                // recycled
+                drawingParams = (HashMap<String, Object>) v.getTag();
+            } else {
+                v = getNewView();
+                // Set up the new view
+                android.widget.AbsListView.LayoutParams params =
+                    new android.widget.AbsListView.LayoutParams(
+                        LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+                v.setLayoutParams(params);
+                v.setClickable(true);
+                v.setOnTouchListener(this);
+
+                drawingParams = new HashMap<String, Object>();
+            }
+
+            // pass in all the view parameters
+            putDrawingParementer(drawingParams, WeekView.VIEW_PARAMS_SHOW_WK_NUM,
+                    mShowWeekNumber ? 1 : 0);
+            putDrawingParementer(drawingParams, WeekView.VIEW_PARAMS_WEEK_START, mFirstDayOfWeek);
+            putDrawingParementer(drawingParams, WeekView.VIEW_PARAMS_NUM_DAYS, mDaysPerWeek);
+            putDrawingParementer(drawingParams, WeekView.VIEW_PARAMS_WEEK, position);
+            putDrawingParementer(drawingParams, WeekView.VIEW_PARAMS_FOCUS_MONTH, mFocusMonth);
+            putDrawingParementer(drawingParams, WeekView.VIEW_PARAMS_SELECTED_DAY,
+                    (mSelectedWeek == position) ? mSelectedDay.get(Calendar.DAY_OF_WEEK) : -1);
+            v.setWeekParams(drawingParams);
+
+            return v;
+        }
+
+        /**
+         * Puts the given <code>value</code> for the drawing
+         * <code>parameter</code> in the <code>drawingParams</code>.
+         */
+        private void putDrawingParementer(HashMap<String, Object> drawingParams, String parameter,
+                int value) {
+            int[] valueArray = (int[]) drawingParams.get(parameter);
+            if (valueArray == null) {
+                valueArray = new int[1];
+                drawingParams.put(parameter, valueArray);
+            }
+            valueArray[0] = value;
+        }
+
+        /**
+         * Creates a new WeekView and returns it. Override this to customize the
+         * view creation.
+         *
+         * @return A new WeekView
+         */
+        protected WeekView getNewView() {
+            return new WeekView(mContext);
+        }
+
+        /**
+         * Changes which month is in focus and updates the view.
+         *
+         * @param month The month to show as in focus [0-11]
+         */
+        public void setFocusMonth(int month) {
+            if (mFocusMonth == month) {
+                return;
+            }
+            mFocusMonth = month;
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public boolean onTouch(View v, MotionEvent event) {
+            if (mGestureDetector.onTouchEvent(event)) {
+                WeekView weekView = (WeekView) v;
+                weekView.getDayFromLocation(event.getX(), mTempCalendar);
+                if (mTempCalendar.get(Calendar.YEAR) != 0) {
+                    onDayTapped(mTempCalendar);
+                }
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Maintains the same hour/min/sec but moves the day to the tapped day.
+         * 
+         * @param day The day that was tapped
+         */
+        protected void onDayTapped(Calendar day) {
+            setSelectedDay(day);
+        }
+
+        /**
+         * This is here so we can identify single tap events and set the
+         * selected day correctly
+         */
+        protected class CalendarGestureListener extends GestureDetector.SimpleOnGestureListener {
+            @Override
+            public boolean onSingleTapUp(MotionEvent e) {
+                return true;
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * This is a dynamic view for drawing a single week. It can be configured to
+     * display the week number, start the week on a given day, or show a reduced
+     * number of days. It is intended for use as a single view within a
+     * ListView. See {@link WeeksAdapter} for usage.
+     * </p>
+     *
+     * @hide
+     */
+    public class WeekView extends View {
+
+        /*
+         * These params can be passed into the view to control how it appears.
+         * {@link #VIEW_PARAMS_WEEK} is the only required field, though the
+         * default values are unlikely to fit most layouts correctly.
+         */
+
+        /**
+         * This sets the height of this week in pixels
+         */
+        public static final String VIEW_PARAMS_HEIGHT = "height";
+
+        /**
+         * This specifies the position (or weeks since the epoch) of this week.
+         */
+        public static final String VIEW_PARAMS_WEEK = "week";
+
+        /**
+         * This sets one of the days in this view as selected
+         * {@link Time#SUNDAY} through {@link Time#SATURDAY}.
+         */
+        public static final String VIEW_PARAMS_SELECTED_DAY = "selected_day";
+
+        /**
+         * Which day the week should start on. {@link Time#SUNDAY} through
+         * {@link Time#SATURDAY}.
+         */
+        public static final String VIEW_PARAMS_WEEK_START = "week_start";
+
+        /**
+         * How many days to display at a time. Days will be displayed starting
+         * with {@link #mFirstDay}.
+         */
+        public static final String VIEW_PARAMS_NUM_DAYS = "num_days";
+
+        /**
+         * Which month is currently in focus, as defined by {@link Time#month}
+         * [0-11].
+         */
+        public static final String VIEW_PARAMS_FOCUS_MONTH = "focus_month";
+
+        /**
+         * If this month should display week numbers. false if 0, true
+         * otherwise.
+         */
+        public static final String VIEW_PARAMS_SHOW_WK_NUM = "show_wk_num";
+
+        protected int mDefaultHeight = 32;
+
+        protected int mMinHeight = 10;
+
+        protected static final int DEFAULT_SELECTED_DAY = -1;
+
+        protected static final int DEFAULT_WEEK_START = Calendar.SUNDAY;
+
+        protected static final int DEFAULT_NUM_DAYS = 7;
+
+        protected static final int DEFAULT_SHOW_WK_NUM = 0;
+
+        protected static final int DEFAULT_FOCUS_MONTH = -1;
+
+        protected static final int DAY_SEPARATOR_WIDTH = 1;
+
+        protected int mNumberTextSize = 14;
+
+        // affects the padding on the sides of this view
+        protected int mPadding = 0;
+
+        protected final Rect mTempRect = new Rect();
+
+        protected final Paint mDrawPaint = new Paint();
+
+        protected Paint mMonthNumDrawPaint = new Paint();
+
+        protected Drawable mSelectedDayLine;
+
+        protected final int mSelectionBackgroundColor;
+
+        protected final int mFocusedMonthDateColor;
+
+        protected final int mOtherMonthDateColor;
+
+        protected final int mGridLinesColor;
+
+        protected final int mWeekNumberColor;
+
+        // Cache the number strings so we don't have to recompute them each time
+        protected String[] mDayNumbers;
+
+        // Quick lookup for checking which days are in the focus month
+        protected boolean[] mFocusDay;
+
+        // The first day displayed by this item
+        protected Calendar mFirstDay;
+
+        // The month of the first day in this week
+        protected int mMonthOfFirstWeekDay = -1;
+
+        // The month of the last day in this week
+        protected int mLastWeekDayMonth = -1;
+
+        // The position of this week, equivalent to weeks since the week of Jan
+        // 1st, 1900
+        protected int mWeek = -1;
+
+        // Quick reference to the width of this view, matches parent
+        protected int mWidth;
+
+        // The height this view should draw at in pixels, set by height param
+        protected int mHeight = mDefaultHeight;
+
+        // Whether the week number should be shown
+        protected boolean mShowWeekNum = false;
+
+        // If this view contains the selected day
+        protected boolean mHasSelectedDay = false;
+
+        // Which day is selected [0-6] or -1 if no day is selected
+        protected int mSelectedDay = DEFAULT_SELECTED_DAY;
+
+        // How many days to display
+        protected int mNumDays = DEFAULT_NUM_DAYS;
+
+        // The number of days + a spot for week number if it is displayed
+        protected int mNumCells = mNumDays;
+
+        // The left edge of the selected day
+        protected int mSelectedLeft = -1;
+
+        // The right edge of the selected day
+        protected int mSelectedRight = -1;
+
+        public WeekView(Context context) {
+            super(context);
+
+            TypedValue outTypedValue = new TypedValue();
+            context.getTheme().resolveAttribute(R.attr.dayPickerWeekViewStyle, outTypedValue, true);
+            TypedArray attributesArray = context.obtainStyledAttributes(outTypedValue.resourceId,
+                    R.styleable.DayPickerWeekView);
+
+            mSelectionBackgroundColor = attributesArray.getColor(
+                    R.styleable.DayPickerWeekView_selectionBackgroundColor, 0);
+            mFocusedMonthDateColor = attributesArray.getColor(
+                    R.styleable.DayPickerWeekView_focusedMonthDateColor, 0);
+            mOtherMonthDateColor = attributesArray.getColor(
+                    R.styleable.DayPickerWeekView_otherMonthDateColor, 0);
+            mGridLinesColor = attributesArray.getColor(
+                    R.styleable.DayPickerWeekView_gridLinesColor, 0);
+            mWeekNumberColor = attributesArray.getColor(
+                    R.styleable.DayPickerWeekView_weekNumberColor, 0);
+            mSelectedDayLine = attributesArray
+                    .getDrawable(R.styleable.DayPickerWeekView_selectedDayLine);
+            attributesArray.recycle();
+
+            if (sScale == 0) {
+                sScale = context.getResources().getDisplayMetrics().density;
+                if (sScale != 1) {
+                    mDefaultHeight *= sScale;
+                    mMinHeight *= sScale;
+                    mNumberTextSize *= sScale;
+                }
+            }
+
+            // Sets up any standard paints that will be used
+            setPaintProperties();
+        }
+
+        /**
+         * Sets all the parameters for displaying this week. The only required
+         * parameter is the week number. Other parameters have a default value
+         * and will only update if a new value is included, except for focus
+         * month, which will always default to no focus month if no value is
+         * passed in. See {@link #VIEW_PARAMS_HEIGHT} for more info on
+         * parameters.
+         *
+         * @param params A map of the new parameters, see
+         *            {@link #VIEW_PARAMS_HEIGHT}
+         */
+        public void setWeekParams(HashMap<String, Object> params) {
+            if (!params.containsKey(VIEW_PARAMS_WEEK)) {
+                throw new InvalidParameterException(
+                        "You must specify the week number for this view");
+            }
+            setTag(params);
+            // We keep the current value for any params not present
+            if (params.containsKey(VIEW_PARAMS_HEIGHT)) {
+                mHeight = ((int[]) params.get(VIEW_PARAMS_HEIGHT))[0];
+                if (mHeight < mMinHeight) {
+                    mHeight = mMinHeight;
+                }
+            }
+            if (params.containsKey(VIEW_PARAMS_SELECTED_DAY)) {
+                mSelectedDay = ((int[]) params.get(VIEW_PARAMS_SELECTED_DAY))[0];
+            }
+            mHasSelectedDay = mSelectedDay != -1;
+            if (params.containsKey(VIEW_PARAMS_NUM_DAYS)) {
+                mNumDays = ((int[]) params.get(VIEW_PARAMS_NUM_DAYS))[0];
+            }
+            if (params.containsKey(VIEW_PARAMS_SHOW_WK_NUM)) {
+                if (((int[]) params.get(VIEW_PARAMS_SHOW_WK_NUM))[0] != 0) {
+                    mNumCells = mNumDays + 1;
+                    mShowWeekNum = true;
+                } else {
+                    mShowWeekNum = false;
+                }
+            } else {
+                mNumCells = mShowWeekNum ? mNumDays + 1 : mNumDays;
+            }
+            mWeek = ((int[]) params.get(VIEW_PARAMS_WEEK))[0];
+            mTempCalendar.clear();
+            mTempCalendar.set(1900, 0, 1);
+            mTempCalendar.add(Calendar.WEEK_OF_YEAR, mWeek);
+            if (params.containsKey(VIEW_PARAMS_WEEK_START)) {
+                mTempCalendar.setFirstDayOfWeek(((int[]) params.get(VIEW_PARAMS_WEEK_START))[0]);
+            } else {
+                mTempCalendar.setFirstDayOfWeek(DEFAULT_WEEK_START);
+            }
+
+            // Allocate space for caching the day numbers and focus values
+            mDayNumbers = new String[mNumCells];
+            mFocusDay = new boolean[mNumCells];
+
+            // If we're showing the week number calculate it based on Monday
+            int i = 0;
+            if (mShowWeekNum) {
+                mDayNumbers[0] = Integer.toString(mTempCalendar.get(Calendar.WEEK_OF_YEAR));
+                i++;
+            }
+
+            // Now adjust our starting day based on the start day of the week
+            int diff = mTempCalendar.getFirstDayOfWeek() - mTempCalendar.get(Calendar.DAY_OF_WEEK);
+            mTempCalendar.add(Calendar.DAY_OF_MONTH, diff);
+
+            mFirstDay = (Calendar) mTempCalendar.clone();
+
+            mMonthOfFirstWeekDay = mTempCalendar.get(Calendar.MONTH);
+
+            int focusMonth = params.containsKey(VIEW_PARAMS_FOCUS_MONTH) ? ((int[]) params
+                    .get(VIEW_PARAMS_FOCUS_MONTH))[0] : DEFAULT_FOCUS_MONTH;
+
+            for (; i < mNumCells; i++) {
+                mFocusDay[i] = (mTempCalendar.get(Calendar.MONTH) == focusMonth);
+                mDayNumbers[i] = Integer.toString(mTempCalendar.get(Calendar.DAY_OF_MONTH));
+                mTempCalendar.add(Calendar.DAY_OF_MONTH, 1);
+            }
+            // We do one extra add at the end of the loop, if that pushed us to
+            // new month undo it
+            if (mTempCalendar.get(Calendar.DAY_OF_MONTH) == 1) {
+                mTempCalendar.add(Calendar.DAY_OF_MONTH, -1);
+            }
+            mLastWeekDayMonth = mTempCalendar.get(Calendar.MONTH);
+
+            updateSelectionPositions();
+        }
+
+        /**
+         * Sets up the text and style properties for painting. Override this if
+         * you want to use a different paint.
+         */
+        protected void setPaintProperties() {
+            mDrawPaint.setFakeBoldText(false);
+            mDrawPaint.setAntiAlias(true);
+            mDrawPaint.setTextSize(mNumberTextSize);
+            mDrawPaint.setStyle(Style.FILL);
+
+            mMonthNumDrawPaint.setFakeBoldText(true);
+            mMonthNumDrawPaint.setAntiAlias(true);
+            mMonthNumDrawPaint.setTextSize(mNumberTextSize);
+            mMonthNumDrawPaint.setColor(mFocusedMonthDateColor);
+            mMonthNumDrawPaint.setStyle(Style.FILL);
+            mMonthNumDrawPaint.setTextAlign(Align.CENTER);
+        }
+
+        /**
+         * Returns the month of the first day in this week.
+         *
+         * @return The month the first day of this view is in.
+         */
+        public int getMonthOfFirstWeekDay() {
+            return mMonthOfFirstWeekDay;
+        }
+
+        /**
+         * Returns the month of the last day in this week
+         *
+         * @return The month the last day of this view is in
+         */
+        public int getMonthOfLastWeekDay() {
+            return mLastWeekDayMonth;
+        }
+
+        /**
+         * Returns the first day in this view.
+         *
+         * @return The first day in the view.
+         */
+        public Calendar getFirstDay() {
+            return mFirstDay;
+        }
+
+        /**
+         * Returns the number of days this view will display.
+         */
+        public int getNumDays() {
+            return mNumDays;
+        }
+
+        /**
+         * Calculates the day that the given x position is in, accounting for
+         * week number. Returns a Time referencing that day or null if
+         *
+         * @param x The x position of the touch eventy
+         */
+        public void getDayFromLocation(float x, Calendar outCalendar) {
+            int dayStart = mShowWeekNum ? (mWidth - mPadding * 2) / mNumCells + mPadding : mPadding;
+            if (x < dayStart || x > mWidth - mPadding) {
+                outCalendar.set(0, 0, 0, 0, 0, 0);
+                return;
+            }
+            // Selection is (x - start) / (pixels/day) == (x -s) * day / pixels
+            int dayPosition = (int) ((x - dayStart) * mNumDays / (mWidth - dayStart - mPadding));
+            outCalendar.setTimeZone(mFirstDay.getTimeZone());
+            outCalendar.setTimeInMillis(mFirstDay.getTimeInMillis());
+            outCalendar.add(Calendar.DAY_OF_MONTH, dayPosition);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            drawBackground(canvas);
+            drawWeekNums(canvas);
+            drawDaySeparators(canvas);
+        }
+
+        /**
+         * This draws the selection highlight if a day is selected in this week.
+         * Override this method if you wish to have a different background
+         * drawn.
+         *
+         * @param canvas The canvas to draw on
+         */
+        protected void drawBackground(Canvas canvas) {
+            if (!mHasSelectedDay) {
+                return;
+            }
+            mDrawPaint.setColor(mSelectionBackgroundColor);
+
+            mTempRect.top = DAY_SEPARATOR_WIDTH;
+            mTempRect.bottom = mHeight;
+            mTempRect.left = mShowWeekNum ? mPadding + (mWidth - mPadding * 2) / mNumCells
+                    : mPadding;
+            mTempRect.right = mSelectedLeft - 2;
+            canvas.drawRect(mTempRect, mDrawPaint);
+
+            mTempRect.left = mSelectedRight + 3;
+            mTempRect.right = mWidth - mPadding;
+            canvas.drawRect(mTempRect, mDrawPaint);
+        }
+
+        /**
+         * Draws the week and month day numbers for this week. Override this
+         * method if you need different placement.
+         *
+         * @param canvas The canvas to draw on
+         */
+        protected void drawWeekNums(Canvas canvas) {
+            float textHeight = mDrawPaint.getTextSize();
+            int y = (int) ((mHeight + textHeight) / 2) - DAY_SEPARATOR_WIDTH;
+            int nDays = mNumCells;
+
+            mDrawPaint.setTextAlign(Align.CENTER);
+            int i = 0;
+            int divisor = 2 * nDays;
+            if (mShowWeekNum) {
+                mDrawPaint.setColor(mWeekNumberColor);
+                int x = (mWidth - mPadding * 2) / divisor + mPadding;
+                canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
+                i++;
+            }
+            for (; i < nDays; i++) {
+                mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
+                        : mOtherMonthDateColor);
+                int x = (2 * i + 1) * (mWidth - mPadding * 2) / divisor + mPadding;
+                canvas.drawText(mDayNumbers[i], x, y, mMonthNumDrawPaint);
+            }
+        }
+
+        /**
+         * Draws a horizontal line for separating the weeks. Override this
+         * method if you want custom separators.
+         *
+         * @param canvas The canvas to draw on
+         */
+        protected void drawDaySeparators(Canvas canvas) {
+            mDrawPaint.setColor(mGridLinesColor);
+            mDrawPaint.setStrokeWidth(DAY_SEPARATOR_WIDTH);
+            float x = mShowWeekNum ? mPadding + (mWidth - mPadding * 2) / mNumCells : mPadding;
+            canvas.drawLine(x, 0, mWidth - mPadding, 0, mDrawPaint);
+
+            if (mHasSelectedDay) {
+                mSelectedDayLine.setBounds(mSelectedLeft - 2, DAY_SEPARATOR_WIDTH,
+                        mSelectedLeft + 4, mHeight + 1);
+                mSelectedDayLine.draw(canvas);
+                mSelectedDayLine.setBounds(mSelectedRight - 3, DAY_SEPARATOR_WIDTH,
+                        mSelectedRight + 3, mHeight + 1);
+                mSelectedDayLine.draw(canvas);
+            }
+        }
+
+        @Override
+        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+            mWidth = w;
+            updateSelectionPositions();
+        }
+
+        /**
+         * This calculates the positions for the selected day lines.
+         */
+        protected void updateSelectionPositions() {
+            if (mHasSelectedDay) {
+                int selectedPosition = mSelectedDay - mTempCalendar.getFirstDayOfWeek();
+                if (selectedPosition < 0) {
+                    selectedPosition += 7;
+                }
+                if (mShowWeekNum) {
+                    selectedPosition++;
+                }
+                mSelectedLeft = selectedPosition * (mWidth - mPadding * 2) / mNumCells + mPadding;
+                mSelectedRight = (selectedPosition + 1) * (mWidth - mPadding * 2) / mNumCells
+                        + mPadding;
+            }
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mHeight);
+        }
+    }
+}
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 940fec1..26e191d 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -76,6 +76,8 @@
 
     boolean mForegroundBoundsChanged = false;
     
+    private static final int DEFAULT_CHILD_GRAVITY = Gravity.TOP | Gravity.LEFT;
+
     public FrameLayout(Context context) {
         super(context);
     }
@@ -307,41 +309,42 @@
                 int childLeft = parentLeft;
                 int childTop = parentTop;
 
-                final int gravity = lp.gravity;
+                int gravity = lp.gravity;
+                if (gravity == -1) {
+                    gravity = DEFAULT_CHILD_GRAVITY;
+                }
 
-                if (gravity != -1) {
-                    final int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
-                    final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+                final int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+                final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
 
-                    switch (horizontalGravity) {
-                        case Gravity.LEFT:
-                            childLeft = parentLeft + lp.leftMargin;
-                            break;
-                        case Gravity.CENTER_HORIZONTAL:
-                            childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +
-                                    lp.leftMargin - lp.rightMargin;
-                            break;
-                        case Gravity.RIGHT:
-                            childLeft = parentRight - width - lp.rightMargin;
-                            break;
-                        default:
-                            childLeft = parentLeft + lp.leftMargin;
-                    }
+                switch (horizontalGravity) {
+                    case Gravity.LEFT:
+                        childLeft = parentLeft + lp.leftMargin;
+                        break;
+                    case Gravity.CENTER_HORIZONTAL:
+                        childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +
+                        lp.leftMargin - lp.rightMargin;
+                        break;
+                    case Gravity.RIGHT:
+                        childLeft = parentRight - width - lp.rightMargin;
+                        break;
+                    default:
+                        childLeft = parentLeft + lp.leftMargin;
+                }
 
-                    switch (verticalGravity) {
-                        case Gravity.TOP:
-                            childTop = parentTop + lp.topMargin;
-                            break;
-                        case Gravity.CENTER_VERTICAL:
-                            childTop = parentTop + (parentBottom - parentTop - height) / 2 +
-                                    lp.topMargin - lp.bottomMargin;
-                            break;
-                        case Gravity.BOTTOM:
-                            childTop = parentBottom - height - lp.bottomMargin;
-                            break;
-                        default:
-                            childTop = parentTop + lp.topMargin;
-                    }
+                switch (verticalGravity) {
+                    case Gravity.TOP:
+                        childTop = parentTop + lp.topMargin;
+                        break;
+                    case Gravity.CENTER_VERTICAL:
+                        childTop = parentTop + (parentBottom - parentTop - height) / 2 +
+                        lp.topMargin - lp.bottomMargin;
+                        break;
+                    case Gravity.BOTTOM:
+                        childTop = parentBottom - height - lp.bottomMargin;
+                        break;
+                    default:
+                        childTop = parentTop + lp.topMargin;
                 }
 
                 child.layout(childLeft, childTop, childLeft + width, childTop + height);
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index c05e3ad..50867b9 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -1420,8 +1420,8 @@
                 final int height = getHeight();
 
                 canvas.rotate(270);
-                canvas.translate(-height * 1.5f, Math.min(0, scrollX));
-                mEdgeGlowLeft.setSize(getHeight() * 2, getWidth());
+                canvas.translate(-height, Math.min(0, scrollX));
+                mEdgeGlowLeft.setSize(getHeight(), getWidth());
                 if (mEdgeGlowLeft.draw(canvas)) {
                     invalidate();
                 }
@@ -1433,8 +1433,9 @@
                 final int height = getHeight();
 
                 canvas.rotate(90);
-                canvas.translate(-height / 2, -(Math.max(getScrollRange(), scrollX) + width));
-                mEdgeGlowRight.setSize(height * 2, width);
+                canvas.translate(0,
+                        -(Math.max(getScrollRange(), scrollX) + width));
+                mEdgeGlowRight.setSize(height, width);
                 if (mEdgeGlowRight.draw(canvas)) {
                     invalidate();
                 }
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 43d194f..bdd2e2c 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -30,8 +30,8 @@
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
-import android.graphics.Rect;
 import android.graphics.Paint.Align;
+import android.graphics.Rect;
 import android.text.InputFilter;
 import android.text.InputType;
 import android.text.Spanned;
@@ -41,11 +41,11 @@
 import android.util.SparseArray;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
+import android.view.LayoutInflater.Filter;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
-import android.view.LayoutInflater.Filter;
 import android.view.animation.OvershootInterpolator;
 import android.view.inputmethod.InputMethodManager;
 
@@ -166,7 +166,12 @@
     /**
      * Listener to be notified upon current value change.
      */
-    private OnChangedListener mListener;
+    private OnChangedListener mOnChangedListener;
+
+    /**
+     * Listener to be notified upon scroll state change.
+     */
+    private OnScrollListener mOnScrollListener;
 
     /**
      * Formatter for for displaying the current value.
@@ -308,6 +313,11 @@
     private final Rect mTempRect = new Rect();
 
     /**
+     * The current scroll state of the number picker.
+     */
+    private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
+
+    /**
      * The callback interface used to indicate the number value has changed.
      */
     public interface OnChangedListener {
@@ -320,6 +330,36 @@
     }
 
     /**
+     * Interface for listening to the picker scroll state.
+     */
+    public interface OnScrollListener {
+
+        /**
+         * The view is not scrolling.
+         */
+        public static int SCROLL_STATE_IDLE = 0;
+
+        /**
+         * The user is scrolling using touch, and their finger is still on the screen.
+         */
+        public static int SCROLL_STATE_TOUCH_SCROLL = 1;
+
+        /**
+         * The user had previously been scrolling using touch and performed a fling.
+         */
+        public static int SCROLL_STATE_FLING = 2;
+
+        /**
+         * Callback method to be invoked while the number picker is being scrolled.
+         *
+         * @param view The view whose scroll state is being reported
+         * @param scrollState The current scroll state. One of {@link #SCROLL_STATE_IDLE},
+         * {@link #SCROLL_STATE_TOUCH_SCROLL} or {@link #SCROLL_STATE_IDLE}.
+         */
+        public void onScrollStateChanged(NumberPicker view, int scrollState);
+    }
+
+    /**
      * Interface used to format the number into a string for presentation
      */
     public interface Formatter {
@@ -492,11 +532,15 @@
                 mBeginEditOnUpEvent = false;
                 mAdjustScrollerOnUpEvent = true;
                 if (mDrawSelectorWheel) {
-                    mBeginEditOnUpEvent = mFlingScroller.isFinished()
+                    boolean scrollersFinished = mFlingScroller.isFinished()
                             && mAdjustScroller.isFinished();
+                    if (!scrollersFinished) {
+                        mFlingScroller.forceFinished(true);
+                        mAdjustScroller.forceFinished(true);
+                        tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_IDLE);
+                    }
+                    mBeginEditOnUpEvent = scrollersFinished;
                     mAdjustScrollerOnUpEvent = true;
-                    mFlingScroller.forceFinished(true);
-                    mAdjustScroller.forceFinished(true);
                     hideInputControls();
                     return true;
                 }
@@ -512,6 +556,7 @@
                 int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
                 if (deltaDownY > mTouchSlop) {
                     mBeginEditOnUpEvent = false;
+                    tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
                     setDrawSelectorWheel(true);
                     hideInputControls();
                     return true;
@@ -531,10 +576,12 @@
         switch (action) {
             case MotionEvent.ACTION_MOVE:
                 float currentMoveY = ev.getY();
-                if (mBeginEditOnUpEvent) {
+                if (mBeginEditOnUpEvent
+                        || mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                     int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
                     if (deltaDownY > mTouchSlop) {
                         mBeginEditOnUpEvent = false;
+                        tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
                     }
                 }
                 int deltaMoveY = (int) (currentMoveY - mLastMotionEventY);
@@ -550,6 +597,7 @@
                     InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
                             Context.INPUT_METHOD_SERVICE);
                     imm.showSoftInput(mInputText, 0);
+                    mInputText.setSelection(0, mInputText.getText().length());
                     return true;
                 }
                 VelocityTracker velocityTracker = mVelocityTracker;
@@ -557,6 +605,7 @@
                 int initialVelocity = (int) velocityTracker.getYVelocity();
                 if (Math.abs(initialVelocity) > mMinimumFlingVelocity) {
                     fling(initialVelocity);
+                    tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_FLING);
                 } else {
                     if (mAdjustScrollerOnUpEvent) {
                         if (mFlingScroller.isFinished() && mAdjustScroller.isFinished()) {
@@ -689,10 +738,19 @@
     /**
      * Set the callback that indicates the number has been adjusted by the user.
      *
-     * @param listener the callback, should not be null.
+     * @param onChangeListener the callback, should not be null.
      */
-    public void setOnChangeListener(OnChangedListener listener) {
-        mListener = listener;
+    public void setOnChangeListener(OnChangedListener onChangeListener) {
+        mOnChangedListener = onChangeListener;
+    }
+
+    /**
+     * Set the callback that in notified for scroll state changes.
+     *
+     * @param onScrollListener the callback, should not be null.
+     */
+    public void setOnScrollListener(OnScrollListener onScrollListener) {
+        mOnScrollListener = onScrollListener;
     }
 
     /**
@@ -966,6 +1024,7 @@
     private void onScrollerFinished(Scroller scroller) {
         if (scroller == mFlingScroller) {
             postAdjustScrollerCommand(0);
+            tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_IDLE);
         } else {
             showInputControls();
             updateInputTextView();
@@ -973,6 +1032,17 @@
     }
 
     /**
+     * Notifies the scroll listener for the given <code>scrollState</code>
+     * if the scroll state differs from the current scroll state.
+     */
+    private void tryNotifyScrollListener(int scrollState) {
+        if (mOnScrollListener != null && mScrollState != scrollState) {
+            mScrollState = scrollState;
+            mOnScrollListener.onScrollStateChanged(this, scrollState);
+        }
+    }
+
+    /**
      * Flings the selector with the given <code>velocityY</code>.
      */
     private void fling(int velocityY) {
@@ -1118,7 +1188,8 @@
             scrollSelectorValue = "";
         } else {
             if (mDisplayedValues != null) {
-                scrollSelectorValue = mDisplayedValues[selectorIndex];
+                int displayedValueIndex = selectorIndex - mStart;
+                scrollSelectorValue = mDisplayedValues[displayedValueIndex];
             } else {
                 scrollSelectorValue = formatNumber(selectorIndex);
             }
@@ -1167,8 +1238,8 @@
      * NumberPicker.
      */
     private void notifyChange(int previous, int current) {
-        if (mListener != null) {
-            mListener.onChanged(this, previous, mCurrent);
+        if (mOnChangedListener != null) {
+            mOnChangedListener.onChanged(this, previous, mCurrent);
         }
     }
 
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 9fa90dc..f25edd8 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -1467,8 +1467,8 @@
                 final int restoreCount = canvas.save();
                 final int width = getWidth();
 
-                canvas.translate(-width / 2, Math.min(0, scrollY));
-                mEdgeGlowTop.setSize(width * 2, getHeight());
+                canvas.translate(0, Math.min(0, scrollY));
+                mEdgeGlowTop.setSize(width, getHeight());
                 if (mEdgeGlowTop.draw(canvas)) {
                     invalidate();
                 }
@@ -1479,9 +1479,9 @@
                 final int width = getWidth();
                 final int height = getHeight();
 
-                canvas.translate(-width / 2, Math.max(getScrollRange(), scrollY) + height);
+                canvas.translate(-width, Math.max(getScrollRange(), scrollY) + height);
                 canvas.rotate(180, width, 0);
-                mEdgeGlowBottom.setSize(width * 2, height);
+                mEdgeGlowBottom.setSize(width, height);
                 if (mEdgeGlowBottom.draw(canvas)) {
                     invalidate();
                 }
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index b32bd42..e499e54 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -1271,7 +1271,7 @@
         public void onWindowFocusChanged(boolean hasWindowFocus) {
             super.onWindowFocusChanged(hasWindowFocus);
 
-            if (hasWindowFocus) {
+            if (hasWindowFocus && mSearchView.hasFocus() && getVisibility() == VISIBLE) {
                 InputMethodManager inputManager = (InputMethodManager) getContext()
                         .getSystemService(Context.INPUT_METHOD_SERVICE);
                 inputManager.showSoftInput(this, 0);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a86610dd..144cf9c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3933,6 +3933,9 @@
             hideError();
         }
 
+        if (mBlink != null) {
+            mBlink.cancel();
+        }
         hideControllers();
     }
 
@@ -6282,11 +6285,7 @@
         mCursorVisible = visible;
         invalidate();
 
-        if (visible) {
-            makeBlink();
-        } else if (mBlink != null) {
-            mBlink.removeCallbacks(mBlink);
-        }
+        makeBlink();
 
         // InsertionPointCursorController depends on mCursorVisible
         prepareCursorControllers();
@@ -6782,7 +6781,7 @@
     }
 
     private void makeBlink() {
-        if (!mCursorVisible) {
+        if (!mCursorVisible || !isTextEditable()) {
             if (mBlink != null) {
                 mBlink.removeCallbacks(mBlink);
             }
@@ -7134,6 +7133,7 @@
                 mLayout != null;
 
         if (!mInsertionControllerEnabled) {
+            hideInsertionPointCursorController();
             mInsertionPointCursorController = null;
         }
 
@@ -7388,14 +7388,14 @@
     }
 
     private boolean canSelectText() {
-        return textCanBeSelected() && mText.length() != 0;
+        return hasSelectionController() && mText.length() != 0;
     }
 
     private boolean textCanBeSelected() {
         // prepareCursorController() relies on this method.
         // If you change this condition, make sure prepareCursorController is called anywhere
         // the value of this condition might be changed.
-        return (mText instanceof Spannable && mMovement != null && mMovement.canSelectArbitrarily());
+        return mText instanceof Spannable && mMovement != null && mMovement.canSelectArbitrarily();
     }
 
     private boolean canCut() {
@@ -7529,6 +7529,10 @@
     }
 
     private void selectCurrentWord() {
+        if (!canSelectText()) {
+            return;
+        }
+
         if (hasPasswordTransformationMethod()) {
             // selectCurrentWord is not available on a password field and would return an
             // arbitrary 10-charater selection around pressed position. Select all instead.
@@ -7544,7 +7548,6 @@
             minOffset = getSelectionStart();
             maxOffset = getSelectionEnd();
         } else {
-            // selectionModifierCursorController is guaranteed to exist at that point
             SelectionModifierCursorController selectionController = getSelectionController();
             minOffset = selectionController.getMinTouchOffset();
             maxOffset = selectionController.getMaxTouchOffset();
@@ -7921,12 +7924,8 @@
 
         selectCurrentWord();
         ActionMode.Callback actionModeCallback = new SelectionActionModeCallback();
-        if (actionModeCallback != null) {
-            mSelectionActionMode = startActionMode(actionModeCallback);
-            return mSelectionActionMode != null;
-        }
-
-        return false;
+        mSelectionActionMode = startActionMode(actionModeCallback);
+        return mSelectionActionMode != null;
     }
 
     /**
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 6cf1387..e66eb8d 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -184,7 +184,7 @@
             setEnabled(false);
         }
     }
-    
+
     @Override
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
diff --git a/core/java/com/android/internal/app/NetInitiatedActivity.java b/core/java/com/android/internal/app/NetInitiatedActivity.java
index 36f45b2..6039cc2 100755
--- a/core/java/com/android/internal/app/NetInitiatedActivity.java
+++ b/core/java/com/android/internal/app/NetInitiatedActivity.java
@@ -26,6 +26,8 @@
 import android.widget.Toast;
 import android.util.Log;
 import android.location.LocationManager;
+
+import com.android.internal.R;
 import com.android.internal.location.GpsNetInitiatedHandler;
 
 /**
@@ -42,10 +44,6 @@
     private static final int POSITIVE_BUTTON = AlertDialog.BUTTON_POSITIVE;
     private static final int NEGATIVE_BUTTON = AlertDialog.BUTTON_NEGATIVE;
 
-    // Dialog button text
-    public static final String BUTTON_TEXT_ACCEPT = "Accept";
-    public static final String BUTTON_TEXT_DENY = "Deny";
-
     // Received ID from intent, -1 when no notification is in progress
     private int notificationId = -1;
 
@@ -67,12 +65,13 @@
         // Set up the "dialog"
         final Intent intent = getIntent();
         final AlertController.AlertParams p = mAlertParams;
+        Context context = getApplicationContext();
         p.mIconId = com.android.internal.R.drawable.ic_dialog_usb;
         p.mTitle = intent.getStringExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_TITLE);
         p.mMessage = intent.getStringExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_MESSAGE);
-        p.mPositiveButtonText = BUTTON_TEXT_ACCEPT;
+        p.mPositiveButtonText = String.format(context.getString(R.string.gpsVerifYes));
         p.mPositiveButtonListener = this;
-        p.mNegativeButtonText = BUTTON_TEXT_DENY;
+        p.mNegativeButtonText = String.format(context.getString(R.string.gpsVerifNo));
         p.mNegativeButtonListener = this;
 
         notificationId = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_NOTIF_ID, -1);
diff --git a/core/java/com/android/internal/widget/DrawableHolder.java b/core/java/com/android/internal/widget/DrawableHolder.java
index a528aeb..947e0f3 100644
--- a/core/java/com/android/internal/widget/DrawableHolder.java
+++ b/core/java/com/android/internal/widget/DrawableHolder.java
@@ -87,15 +87,12 @@
      * @param property
      */
     public void removeAnimationFor(String property) {
-        ArrayList<ObjectAnimator> removalList = new ArrayList<ObjectAnimator>();
-        for (ObjectAnimator currentAnim : mAnimators) {
+        ArrayList<ObjectAnimator> removalList = (ArrayList<ObjectAnimator>)mAnimators.clone();
+        for (ObjectAnimator currentAnim : removalList) {
             if (property.equals(currentAnim.getPropertyName())) {
                 currentAnim.cancel();
-                removalList.add(currentAnim);
             }
         }
-        if (DBG) Log.v(TAG, "Remove list size: " + removalList.size());
-        mAnimators.removeAll(removalList);
     }
 
     /**
diff --git a/core/res/res/drawable-hdpi/simple_week_dayline_holo_light.9.png b/core/res/res/drawable-hdpi/simple_week_dayline_holo_light.9.png
new file mode 100644
index 0000000..ed1a5e9
--- /dev/null
+++ b/core/res/res/drawable-hdpi/simple_week_dayline_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/simple_week_dayline_holo_light.9.png b/core/res/res/drawable-mdpi/simple_week_dayline_holo_light.9.png
new file mode 100644
index 0000000..f264cb6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/simple_week_dayline_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_chat.png b/core/res/res/drawable-mdpi/stat_notify_chat.png
index 068b7ec..8cf02cc 100644
--- a/core/res/res/drawable-mdpi/stat_notify_chat.png
+++ b/core/res/res/drawable-mdpi/stat_notify_chat.png
Binary files differ
diff --git a/core/res/res/layout/date_picker.xml b/core/res/res/layout/date_picker.xml
index 4fd46b3..5c023ee 100644
--- a/core/res/res/layout/date_picker.xml
+++ b/core/res/res/layout/date_picker.xml
@@ -19,45 +19,74 @@
 
 <!-- Layout of date picker-->
 
-<!-- Warning: everything within the parent is removed and re-ordered depending
-     on the date format selected by the user. -->
+<!-- Warning: everything within the "pickers" layout is removed and re-ordered
+     depending on the date format selected by the user.
+-->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/parent"
-    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
     android:layout_gravity="center_horizontal"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
+    android:orientation="horizontal"
+    android:gravity="center">
 
-    <!-- Month -->
-    <NumberPicker
-        android:id="@+id/month"
-        android:layout_width="80dip"
+    <LinearLayout android:id="@+id/pickers"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginLeft="1dip"
-        android:layout_marginRight="1dip"
-        android:focusable="true"
-        android:focusableInTouchMode="true"
-        />
+        android:layout_marginRight="15dip"
+        android:layout_weight="0.5"
+        android:orientation="horizontal"
+        android:gravity="center">
 
-    <!-- Day -->
-    <NumberPicker
-        android:id="@+id/day"
-        android:layout_width="80dip"
-        android:layout_height="wrap_content"
-        android:layout_marginLeft="1dip"
-        android:layout_marginRight="1dip"
-        android:focusable="true"
-        android:focusableInTouchMode="true"
-        />
+        <!-- Month -->
+        <NumberPicker
+            android:id="@+id/month"
+            android:layout_width="48dip"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="15dip"
+            android:layout_marginRight="15dip"
+            android:layout_marginTop="35dip"
+            android:layout_marginBottom="35dip"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            />
 
-    <!-- Year -->
-    <NumberPicker
-        android:id="@+id/year"
-        android:layout_width="95dip"
-        android:layout_height="wrap_content"
-        android:layout_marginLeft="1dip"
-        android:layout_marginRight="1dip"
-        android:focusable="true"
-        android:focusableInTouchMode="true"
-        />
+        <!-- Day -->
+        <NumberPicker
+            android:id="@+id/day"
+            android:layout_width="48dip"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="15dip"
+            android:layout_marginRight="15dip"
+            android:layout_marginTop="35dip"
+            android:layout_marginBottom="35dip"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            />
+
+        <!-- Year -->
+        <NumberPicker
+            android:id="@+id/year"
+            android:layout_width="48dip"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="15dip"
+            android:layout_marginRight="15dip"
+            android:layout_marginTop="35dip"
+            android:layout_marginBottom="35dip"       
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            />
+
+    </LinearLayout>
+
+    <!-- mini-month day-picker -->
+      <DayPicker
+          android:id="@+id/mini_month_day_picker"
+          android:layout_width="200dip"
+          android:layout_height="230dip"
+          android:layout_marginLeft="15dip"
+          android:layout_weight="0.5"
+          android:focusable="true"
+          android:focusableInTouchMode="true"
+          />
+
 </LinearLayout>
diff --git a/core/res/res/layout/date_picker_dialog.xml b/core/res/res/layout/date_picker_dialog.xml
index 949c8a3..90de1f5 100644
--- a/core/res/res/layout/date_picker_dialog.xml
+++ b/core/res/res/layout/date_picker_dialog.xml
@@ -17,9 +17,14 @@
 */
 -->
 
+<!-- Note: We want the DatePicker to take as much space as possible, therefore
+           we set the width and height bigger than the max AlertDialog size
+           determined by our parent WeightedLinearLayout.
+
+           See: alert_dialog.xml
+-->
 <DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/datePicker"
-    android:padding="5dip"
     android:layout_gravity="center_horizontal"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"/>
+    android:layout_width="250dip"
+    android:layout_height="600dip"/>
diff --git a/core/res/res/layout/day_picker.xml b/core/res/res/layout/day_picker.xml
new file mode 100644
index 0000000..46ab450
--- /dev/null
+++ b/core/res/res/layout/day_picker.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 2010, 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:fillViewport="true" >
+
+    <TextView android:id="@+android:id/month_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal" 
+        android:paddingTop="10dip"
+        android:paddingBottom="10dip"
+        style="@android:style/TextAppearance.Medium" />
+
+    <LinearLayout android:id="@+android:id/day_names"
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="6dip"
+        android:layout_marginRight="2dip"
+        android:layout_marginLeft="2dip"
+        android:gravity="center">
+
+        <TextView android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:gravity="center"
+            android:visibility="gone" />
+
+        <TextView android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:gravity="center"
+            style="?android:attr/dayPickerWeekDayViewStyle" />
+
+        <TextView android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:gravity="center"
+            style="?android:attr/dayPickerWeekDayViewStyle" />
+
+        <TextView android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:gravity="center"
+            style="?android:attr/dayPickerWeekDayViewStyle" />
+
+        <TextView android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:gravity="center"
+            style="?android:attr/dayPickerWeekDayViewStyle" />
+
+        <TextView android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:gravity="center"
+            style="?android:attr/dayPickerWeekDayViewStyle" />
+
+        <TextView android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:gravity="center"
+            style="?android:attr/dayPickerWeekDayViewStyle" />
+
+        <TextView android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:gravity="center"
+            style="?android:attr/dayPickerWeekDayViewStyle" />
+
+    </LinearLayout>
+
+    <ListView android:id="@android:id/list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:drawSelectorOnTop="false"
+            android:cacheColorHint="@android:color/transparent"
+            android:fastScrollEnabled="false"
+            android:overScrollMode="never" />
+
+</LinearLayout>
diff --git a/core/res/res/layout/time_picker.xml b/core/res/res/layout/time_picker.xml
index fa288422..bf81c18 100644
--- a/core/res/res/layout/time_picker.xml
+++ b/core/res/res/layout/time_picker.xml
@@ -30,7 +30,7 @@
         android:id="@+id/hour"
         android:layout_width="48dip"
         android:layout_height="wrap_content"
-        android:layout_marginRight="20dip"
+        android:layout_marginRight="13dip"
         android:layout_marginTop="35dip"
         android:layout_marginBottom="35dip"
         android:focusable="true"
@@ -50,8 +50,8 @@
         android:id="@+id/minute"
         android:layout_width="48dip"
         android:layout_height="wrap_content"
-        android:layout_marginLeft="20dip"
-        android:layout_marginRight="22dip"
+        android:layout_marginLeft="13dip"
+        android:layout_marginRight="15dip"
         android:layout_marginTop="35dip"
         android:layout_marginBottom="35dip"
         android:focusable="true"
@@ -63,7 +63,7 @@
         android:id="@+id/amPm"
         android:layout_width="48dip"
         android:layout_height="wrap_content"
-        android:layout_marginLeft="22dip"
+        android:layout_marginLeft="15dip"
         android:layout_marginTop="35dip"
         android:layout_marginBottom="35dip"
         android:focusable="true"
diff --git a/core/res/res/layout/time_picker_dialog.xml b/core/res/res/layout/time_picker_dialog.xml
index d5a6b5e..09326c8 100644
--- a/core/res/res/layout/time_picker_dialog.xml
+++ b/core/res/res/layout/time_picker_dialog.xml
@@ -22,4 +22,4 @@
     android:layout_gravity="center_horizontal"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:padding="5dip" />
+    />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 109fb0d..81191ff 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -503,16 +503,23 @@
         <attr name="listPopupWindowStyle" format="reference" />
         <!-- Default PopupMenu style. -->
         <attr name="popupMenuStyle" format="reference" />
-        <!-- NumberPicker up button style -->
+
+        <!-- @hide NumberPicker up button style -->
         <attr name="numberPickerUpButtonStyle" format="reference" />
-        <!-- NumberPicker down button style -->
+        <!-- @hide NumberPicker down button style -->
         <attr name="numberPickerDownButtonStyle" format="reference" />
-        <!-- NumberPicker input text style -->
+        <!-- @hide NumberPicker input text style -->
         <attr name="numberPickerInputTextStyle" format="reference" />
 
-        <!-- NumberPicker the fading edge length of the selector wheel -->
+        <!-- @hide NumberPicker the fading edge length of the selector wheel -->
         <attr name="numberPickerStyle" format="reference" />
 
+        <!-- @hide DayPicker$WeekView style-->
+        <attr name="dayPickerWeekViewStyle" format="reference" />
+
+        <!-- @hide DayPickerDayView style-->
+        <attr name="dayPickerWeekDayViewStyle" format="reference" />
+
         <!-- =================== -->
         <!-- Action bar styles   -->
         <!-- =================== -->
@@ -2943,6 +2950,16 @@
     </declare-styleable>
 
     <!-- @hide -->
+    <declare-styleable name="DayPickerWeekView">
+        <attr name="selectionBackgroundColor" format="color|reference" />
+        <attr name="focusedMonthDateColor" format="color|reference" />
+        <attr name="otherMonthDateColor" format="color|reference" />
+        <attr name="weekNumberColor" format="color|reference" />
+        <attr name="gridLinesColor" format="color|reference" />
+        <attr name="selectedDayLine" format="reference" />
+    </declare-styleable>
+
+    <!-- @hide -->
     <declare-styleable name="NumberPicker">
         <attr name="orientation" />
         <attr name="solidColor" format="color|reference" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index ae029e5..8fa1d32 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1567,6 +1567,6 @@
   <public type="style" name="Holo.Light.ButtonBar.AlertDialog" />
   <public type="style" name="Holo.SegmentedButton" />
   <public type="style" name="Holo.Light.SegmentedButton" />
-
   <public type="string" name="selectTextMode" />
+
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 0f5ff05..2e235f0 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2295,6 +2295,8 @@
 
     <!-- The title of the time picker dialog. [CHAR LIMIT=NONE] -->
     <string name="time_picker_dialog_title">Set time</string>
+    <!-- The title of the date picker dialog. [CHAR LIMIT=NONE] -->
+    <string name="date_picker_dialog_title">Set date</string>
     <!-- Name of the button in the date/time picker to accept the date/time change -->
     <string name="date_time_set">Set</string>
 
@@ -2621,4 +2623,19 @@
     <!-- ActionBar action to use the current selection to open the Find on page functionality [CHAR LIMIT=10]-->
     <string name="find">Find</string>
 
+    <!-- Network positioning notification ticker. The name of the user (e.g. John Doe) who sent
+         the request is shown as a dynamic string. -->
+    <string name="gpsNotifTicker">Location request from <xliff:g id="name">%s</xliff:g></string>
+    <!-- Network positioning notification and verification title to inform the user about
+         an incoming location request. -->
+    <string name="gpsNotifTitle">Location request</string>
+    <!-- Network positioning notification message. The name of the user (e.g. John Doe) and
+         service (SUPL-service) who sent the request is shown as dynamic strings.
+         Translation should not be longer than master text. -->
+    <string name="gpsNotifMessage">Requested by <xliff:g id="name">%1$s</xliff:g> (<xliff:g id="service" example="SUPL-service">%2$s</xliff:g>)</string>
+    <!-- Network positioning verification Yes. Button to push to share location information. -->
+    <string name="gpsVerifYes">Yes</string>
+    <!-- Network positioning verification No. Button to push to deny sharing of location
+         information. -->
+    <string name="gpsVerifNo">No</string>
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 58553e1..8d7556f 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -238,6 +238,11 @@
         <item name="android:textColor">#ff272727</item>
     </style>
 
+    <!-- @hide -->
+    <style name="TextAppearance.Small.DayPickerWeekDayView">
+        <item name="android:textStyle">bold</item>
+    </style>
+
     <!-- Widget Styles -->
 
     <style name="Widget">
@@ -468,21 +473,35 @@
         <item name="android:background">@android:drawable/btn_default</item>
     </style>
 
+    <!-- @hide -->
+    <style name="Widget.DayPickerWeekView">
+        <item name="android:selectionBackgroundColor">#330099FF</item>
+        <item name="android:focusedMonthDateColor">#FFFFFFFF</item>
+        <item name="android:otherMonthDateColor">#66FFFFFF</item>
+        <item name="android:weekNumberColor">#33FFFFFF</item>
+        <item name="android:gridLinesColor">#19FFFFFF</item>
+        <item name="selectedDayLine">@android:drawable/simple_week_dayline_holo_light</item>
+    </style>
+
+    <!-- @hide -->
     <style name="Widget.NumberPicker">
         <item name="android:orientation">vertical</item>
         <item name="android:fadingEdge">vertical</item>
         <item name="android:fadingEdgeLength">50dip</item>
-        <item name="android:solidColor">?android:attr/colorBackground</item>
+        <item name="android:solidColor">@android:color/transparent</item>
     </style>
 
+    <!-- @hide -->
     <style name="Widget.ImageButton.NumberPickerUpButton">
         <item name="android:background">@android:drawable/timepicker_up_btn</item>
     </style>
 
+    <!-- @hide -->
     <style name="Widget.ImageButton.NumberPickerDownButton">
         <item name="android:background">@android:drawable/timepicker_down_btn</item>
     </style>
 
+    <!-- @hide -->
     <style name="Widget.EditText.NumberPickerInputText">
         <item name="android:textAppearance">@style/TextAppearance.Large.Inverse.NumberPickerInputText</item>
         <item name="android:gravity">center</item>
@@ -834,6 +853,7 @@
         <item name="android:textStyle">bold</item>
     </style>
 
+    <!-- @hide -->
     <style name="TextAppearance.Large.Inverse.NumberPickerInputText">
         <item name="android:textColor">@android:color/primary_text_light</item>
         <item name="android:textSize">30sp</item>
@@ -1200,6 +1220,11 @@
         <item name="android:textSize">18sp</item>
     </style>
 
+    <!-- @hide -->
+    <style name="TextAppearance.Holo.DayPickerWeekDayView" parent="TextAppearance.Small.DayPickerWeekDayView">
+        <item name="android:textColor">#505050</item>
+    </style>
+
     <!-- Light text styles -->
     <style name="TextAppearance.Holo.Light" parent="TextAppearance.Holo">
     </style>
@@ -1296,6 +1321,10 @@
         <item name="android:textSize">18sp</item>
     </style>
 
+    <!-- @hide -->
+    <style name="TextAppearance.Holo.Light.DayPickerWeekDayView" parent="TextAppearance.Small.DayPickerWeekDayView">
+    </style>
+
     <!-- Widget Styles -->
 
     <style name="Widget.Holo" parent="Widget">
@@ -1406,22 +1435,35 @@
         <item name="android:listSelector">?android:attr/selectableItemBackground</item>
     </style>
 
+    <!-- @hide -->
+    <style name="Widget.Holo.DayPickerWeekView">
+        <item name="android:selectionBackgroundColor">#330099FF</item>
+        <item name="android:focusedMonthDateColor">#FFFFFFFF</item>
+        <item name="android:otherMonthDateColor">#66FFFFFF</item>
+        <item name="android:weekNumberColor">#33FFFFFF</item>
+        <item name="android:gridLinesColor">#19FFFFFF</item>
+        <item name="selectedDayLine">@android:drawable/simple_week_dayline_holo_light</item>
+    </style>
+
     <style name="Widget.Holo.ImageButton" parent="Widget.ImageButton">
         <item name="android:background">@android:drawable/btn_default_holo_dark</item>
     </style>
 
+    <!-- @hide -->
     <style name="Widget.Holo.ImageButton.NumberPickerUpButton">
         <item name="android:background">@null</item>
         <item name="android:paddingBottom">26sp</item>
         <item name="android:src">@android:drawable/timepicker_up_btn_holo_dark</item>
     </style>
 
+    <!-- @hide -->
     <style name="Widget.Holo.ImageButton.NumberPickerDownButton">
         <item name="android:background">@null</item>
         <item name="android:paddingTop">26sp</item>
         <item name="android:src">@android:drawable/timepicker_down_btn_holo_dark</item>
     </style>
 
+    <!-- @hide -->
     <style name="Widget.Holo.EditText.NumberPickerInputText">
         <item name="android:paddingTop">13sp</item>
         <item name="android:paddingBottom">13sp</item>
@@ -1767,14 +1809,21 @@
         <item name="android:background">@android:drawable/btn_default_holo_light</item>
     </style>
 
+    <!-- @hide -->
+    <style name="Widget.Holo.Light.DayPickerWeekView" parent="Widget.DayPickerWeekView">
+    </style>
+
+    <!-- @hide -->
     <style name="Widget.Holo.Light.ImageButton.NumberPickerUpButton" parent="Widget.Holo.Light.ImageButton.NumberPickerUpButton">
         <item name="android:background">@android:drawable/timepicker_up_btn_holo_light</item>
     </style>
 
+    <!-- @hide -->
     <style name="Widget.Holo.Light.ImageButton.NumberPickerDownButton" parent="Widget.Holo.ImageButton.NumberPickerDownButton">
         <item name="android:background">@android:drawable/timepicker_down_btn_holo_light</item>
     </style>
 
+    <!-- @hide -->
     <style name="Widget.Holo.Light.EditText.NumberPickerInputText" parent="Widget.Holo.EditText.NumberPickerInputText">
     </style>
 
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 0f21e9f..94e8f96 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -26,7 +26,7 @@
          of it a dark color.
     -->
     <style name="Theme">
-    
+
         <item name="colorForeground">@android:color/bright_foreground_dark</item>
         <item name="colorForegroundInverse">@android:color/bright_foreground_dark_inverse</item>
         <item name="colorBackground">@android:color/background_dark</item>
@@ -280,6 +280,12 @@
         <item name="numberPickerInputTextStyle">@style/Widget.EditText.NumberPickerInputText</item>
         <item name="numberPickerStyle">@style/Widget.NumberPicker</item>
 
+        <!-- DayPicker$WeekView style-->
+        <item name="dayPickerWeekViewStyle">@style/Widget.DayPickerWeekView</item>
+
+        <!-- DayPickerWeekDayView style-->
+        <item name="dayPickerWeekDayViewStyle">@style/TextAppearance.Small.DayPickerWeekDayView</item>
+
     </style>
 
     <!-- Variant of the default (dark) theme with no title bar -->
@@ -917,6 +923,12 @@
         <item name="numberPickerDownButtonStyle">@style/Widget.Holo.ImageButton.NumberPickerDownButton</item>
         <item name="numberPickerInputTextStyle">@style/Widget.Holo.EditText.NumberPickerInputText</item>
 
+        <!-- DayPicker$WeekView style-->
+        <item name="dayPickerWeekViewStyle">@style/Widget.Holo.DayPickerWeekView</item>
+
+        <!-- DayPickerWeekDayView style-->
+        <item name="dayPickerWeekDayViewStyle">@style/TextAppearance.Holo.DayPickerWeekDayView</item>
+
     </style>
 
     <!-- New Honeycomb holographic theme. Light version.  The widgets in the
@@ -1162,6 +1174,12 @@
         <item name="numberPickerDownButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerDownButton</item>
         <item name="numberPickerInputTextStyle">@style/Widget.Holo.Light.EditText.NumberPickerInputText</item>
 
+        <!-- DayPicker$WeekView style-->
+        <item name="dayPickerWeekViewStyle">@style/Widget.Holo.Light.DayPickerWeekView</item>
+
+        <!-- DayPickerWeekDayView style-->
+        <item name="dayPickerWeekDayViewStyle">@style/TextAppearance.Holo.Light.DayPickerWeekDayView</item>
+
     </style>
 
     <!-- Development legacy name; if you're using this, switch. -->
diff --git a/core/tests/ConnectivityManagerTest/Android.mk b/core/tests/ConnectivityManagerTest/Android.mk
index a1546fa..56011f7 100644
--- a/core/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/ConnectivityManagerTest/Android.mk
@@ -25,6 +25,6 @@
 
 LOCAL_PACKAGE_NAME := ConnectivityManagerTest
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index b116bea..05f8b39 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -16,7 +16,8 @@
 
 <!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.connectivitymanagertest">
+  package="com.android.connectivitymanagertest"
+  android:sharedUserId="com.android.uid.test">
 
     <!-- We add an application tag here just so that we can indicate that
          this package needs to link against the android.test library,
@@ -67,5 +68,9 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.DEVICE_POWER" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
 </manifest>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
index 47f208a..5b76e39 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
@@ -19,8 +19,8 @@
 import android.os.Bundle;
 import android.test.InstrumentationTestRunner;
 import android.test.InstrumentationTestSuite;
-import android.util.Log;
 import com.android.connectivitymanagertest.stress.WifiApStress;
+import com.android.connectivitymanagertest.stress.WifiStressTest;
 
 import junit.framework.TestSuite;
 
@@ -34,10 +34,18 @@
  */
 
 public class ConnectivityManagerStressTestRunner extends InstrumentationTestRunner {
+    public int mSoftapIterations = 100;
+    public int mScanIterations = 100;
+    public int mReconnectIterations = 100;
+    public int mSleepTime = 30 * 1000;  // default sleep time is 30 seconds
+    public String mReconnectSsid = "securenetdhcp";
+    public String mReconnectPassword = "androidwifi";
+
     @Override
     public TestSuite getAllTests() {
         TestSuite suite = new InstrumentationTestSuite(this);
         suite.addTestSuite(WifiApStress.class);
+        suite.addTestSuite(WifiStressTest.class);
         return suite;
     }
 
@@ -49,14 +57,46 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        String stressValue = (String) icicle.get("stressnum");
-        if (stressValue != null) {
-            int iteration = Integer.parseInt(stressValue);
+        String valueStr = (String) icicle.get("softap_iterations");
+        if (valueStr != null) {
+            int iteration = Integer.parseInt(valueStr);
             if (iteration > 0) {
-                numStress = iteration;
+                mSoftapIterations = iteration;
+            }
+        }
+
+        String scanIterationStr = (String) icicle.get("scan_iterations");
+        if (scanIterationStr != null) {
+            int scanIteration = Integer.parseInt(scanIterationStr);
+            if (scanIteration > 0) {
+                mScanIterations = scanIteration;
+            }
+        }
+
+        String ssidStr= (String) icicle.get("reconnect_ssid");
+        if (ssidStr != null) {
+            mReconnectSsid = ssidStr;
+        }
+
+        String passwordStr = (String) icicle.get("reconnect_password");
+        if (passwordStr != null) {
+            mReconnectPassword = passwordStr;
+        }
+
+        String reconnectStr = (String) icicle.get("reconnect_iterations");
+        if (reconnectStr != null) {
+            int iteration = Integer.parseInt(reconnectStr);
+            if (iteration > 0) {
+                mReconnectIterations = iteration;
+            }
+        }
+
+        String sleepTimeStr = (String) icicle.get("sleep_time");
+        if (sleepTimeStr != null) {
+            int sleepTime = Integer.parseInt(sleepTimeStr);
+            if (sleepTime > 0) {
+                mSleepTime = 1000 * sleepTime;
             }
         }
     }
-
-    public int numStress = 100;
 }
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 2888696..af74c6f 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -76,6 +76,7 @@
     public String mBssid;
     public String mPowerSsid = "GoogleGuest"; //Default power SSID
     private Context mContext;
+    public boolean scanResultAvailable = false;
 
     /*
      * Control Wifi States
@@ -142,6 +143,7 @@
             String action = intent.getAction();
             Log.v("WifiReceiver", "onReceive() is calleld with " + intent);
             if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+                log("scan results are available");
                 notifyScanResult();
             } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                 mWifiNetworkInfo =
@@ -174,6 +176,7 @@
 
     public ConnectivityManagerTestActivity() {
         mState = State.UNKNOWN;
+        scanResultAvailable = false;
     }
 
     @Override
@@ -267,6 +270,7 @@
     private void notifyScanResult() {
         synchronized (this) {
             log("notify that scan results are available");
+            scanResultAvailable = true;
             this.notify();
         }
     }
@@ -328,6 +332,8 @@
         long startTime = System.currentTimeMillis();
         while (true) {
             if ((System.currentTimeMillis() - startTime) > timeout) {
+                log("waitForNetworkState time out, the state of network type " + networkType +
+                        " is: " + mCM.getNetworkInfo(networkType).getState());
                 if (mCM.getNetworkInfo(networkType).getState() != expectedState) {
                     return false;
                 } else {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
index cc53ddc..21ab0e6 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
@@ -19,25 +19,36 @@
 
 import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
 import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
-import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
 
+import android.content.Context;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
+import android.net.wifi.WifiManager;
+import android.os.Environment;
+import android.os.PowerManager;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+
 /**
  * Stress the wifi driver as access point.
  */
 public class WifiApStress
     extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
     private final static String TAG = "WifiApStress";
-    private ConnectivityManagerTestActivity mAct;
     private static String NETWORK_ID = "AndroidAPTest";
     private static String PASSWD = "androidwifi";
-    private int max_num;
+    private final static String OUTPUT_FILE = "WifiApStressOutput.txt";
+    private ConnectivityManagerTestActivity mAct;
+    private int iterations;
+    private PowerManager.WakeLock mWakelock = null;
+    private BufferedWriter mOutputWriter = null;
+    private int mLastIteration = 0;
 
     public WifiApStress() {
         super(ConnectivityManagerTestActivity.class);
@@ -47,11 +58,27 @@
     public void setUp() throws Exception {
         super.setUp();
         mAct = getActivity();
-        max_num = ((ConnectivityManagerStressTestRunner)getInstrumentation()).numStress;
+        ConnectivityManagerStressTestRunner mRunner =
+            (ConnectivityManagerStressTestRunner)getInstrumentation();
+        iterations = mRunner.mSoftapIterations;
+        PowerManager pm =
+            (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
+        mWakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "wifiApStress");
+        mWakelock.acquire();
     }
 
     @Override
     public void tearDown() throws Exception {
+        if (mWakelock != null) {
+            mWakelock.release();
+        }
+        // write the total number of iterations into output file
+        mOutputWriter = new BufferedWriter(new FileWriter(new File(
+                Environment.getExternalStorageDirectory(), OUTPUT_FILE)));
+        mOutputWriter.write(String.format("iteration %d out of %d"
+                + "\n", mLastIteration, iterations));
+        mOutputWriter.flush();
+        mOutputWriter.close();
         super.tearDown();
     }
 
@@ -67,15 +94,18 @@
         if (mAct.mWifiManager.isWifiEnabled()) {
             mAct.disableWifi();
         }
-        for (int i = 0; i < max_num; i++) {
+        int i;
+        for (i = 0; i < iterations; i++) {
             Log.v(TAG, "iteration: " + i);
+            mLastIteration = i;
             // enable Wifi tethering
             assertTrue(mAct.mWifiManager.setWifiApEnabled(config, true));
             // Wait for wifi ap state to be ENABLED
-            assertTrue(mAct.waitForWifiAPState(mAct.mWifiManager.WIFI_AP_STATE_ENABLED,
-                    mAct.LONG_TIMEOUT));
+            assertTrue(mAct.waitForWifiAPState(WifiManager.WIFI_AP_STATE_ENABLED,
+                    ConnectivityManagerTestActivity.LONG_TIMEOUT));
             // Wait for wifi tethering result
-            assertEquals(mAct.SUCCESS, mAct.waitForTetherStateChange(2*mAct.SHORT_TIMEOUT));
+            assertEquals(ConnectivityManagerTestActivity.SUCCESS,
+                    mAct.waitForTetherStateChange(2*ConnectivityManagerTestActivity.SHORT_TIMEOUT));
             // Allow the wifi tethering to be enabled for 10 seconds
             try {
                 Thread.sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
@@ -84,6 +114,9 @@
             }
             assertTrue(mAct.mWifiManager.setWifiApEnabled(config, false));
         }
+        if (i == iterations) {
+            mLastIteration = iterations;
+        }
     }
 
 }
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
new file mode 100644
index 0000000..0756a72
--- /dev/null
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2010, 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.
+ */
+
+package com.android.connectivitymanagertest.stress;
+
+import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
+import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo.State;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.IpAssignment;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WifiConfiguration.ProxySettings;
+import android.net.wifi.WifiManager;
+import android.os.Environment;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import android.util.Log;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Stress Wi-Fi connection, scanning and reconnection after sleep.
+ *
+ * To run this stress test suite, type
+ * adb shell am instrument -e class com.android.connectivitymanagertest.stress.WifiStressTest
+ *                  -w com.android.connectivitymanagertest/.ConnectivityManagerStressTestRunner
+ */
+public class WifiStressTest
+    extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
+    private final static String TAG = "WifiStressTest";
+
+    /**
+     * Wi-Fi idle time for default sleep policy
+     */
+    private final static long WIFI_IDLE_MS = 5 * 1000;
+
+    /**
+     * The delay for Wi-Fi to get into idle, after screen off + WIFI_IDEL_MS + WIFI_IDLE_DELAY
+     * the Wi-Fi should be in idle mode and device should be in cellular mode.
+     */
+    private final static long WIFI_IDLE_DELAY = 3 * 1000;
+
+    private final static String OUTPUT_FILE = "WifiStressTestOutput.txt";
+    private ConnectivityManagerTestActivity mAct;
+    private int mReconnectIterations;
+    private int mWifiSleepTime;
+    private int mScanIterations;
+    private String mSsid;
+    private String mPassword;
+    private ConnectivityManagerStressTestRunner mRunner;
+    private PowerManager.WakeLock wl = null;
+    private BufferedWriter mOutputWriter = null;
+
+    public WifiStressTest() {
+        super(ConnectivityManagerTestActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mAct = getActivity();
+        mRunner = (ConnectivityManagerStressTestRunner) getInstrumentation();
+        mReconnectIterations = mRunner.mReconnectIterations;
+        mSsid = mRunner.mReconnectSsid;
+        mPassword = mRunner.mReconnectPassword;
+        mScanIterations = mRunner.mScanIterations;
+        mWifiSleepTime = mRunner.mSleepTime;
+        wl = null;
+        mOutputWriter = new BufferedWriter(new FileWriter(new File(
+                Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
+        if (!mAct.mWifiManager.isWifiEnabled()) {
+            if (!mAct.enableWifi()) {
+                tearDown();
+                fail("enable wifi failed.");
+            }
+            sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT,
+                    "Interruped while waiting for wifi on");
+        }
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        log("tearDown()");
+        if ((wl != null) && wl.isHeld()) {
+            wl.release();
+        }
+        if (mOutputWriter != null) {
+            mOutputWriter.close();
+        }
+        super.tearDown();
+    }
+
+    private void writeOutput(String s) {
+        log("write message: " + s);
+        if (mOutputWriter == null) {
+            log("no writer attached to file " + OUTPUT_FILE);
+            return;
+        }
+        try {
+            mOutputWriter.write(s + "\n");
+            mOutputWriter.flush();
+        } catch (IOException e) {
+            log("failed to write output.");
+        }
+    }
+
+    private void turnScreenOff() {
+        log("Turn screen off");
+        if (wl != null) {
+            log("release wake lock");
+            wl.release();
+        }
+        PowerManager pm =
+            (PowerManager) mRunner.getContext().getSystemService(Context.POWER_SERVICE);
+        pm.goToSleep(SystemClock.uptimeMillis() + 50);
+    }
+
+    private void turnScreenOn() {
+        log("Turn screen on");
+        PowerManager pm =
+            (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
+        wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
+                "wifiStressTest");
+        wl.acquire();
+    }
+
+    public void log(String message) {
+        Log.v(TAG, message);
+    }
+
+    private void sleep(long sometime, String errorMsg) {
+        try {
+            Thread.sleep(sometime);
+        } catch (InterruptedException e) {
+            fail(errorMsg);
+        }
+    }
+
+    /**
+     *  Stress Wifi Scanning
+     *  TODO: test the scanning quality for each frequency band
+     */
+    @LargeTest
+    public void testWifiScanning() {
+        int scanTimeSum = 0;
+        int i;
+        int averageScanTime = 0;
+        int ssidAppearInScanResultsCount = 0; // count times of given ssid appear in scan results.
+        for (i = 0; i < mScanIterations; i++) {
+            log("testWifiScanning: iteration: " + i);
+            writeOutput(String.format("scan iteration %d out of %d",
+                    i, mScanIterations));
+            writeOutput(String.format("average scanning time is %d", averageScanTime));
+            writeOutput(String.format("ssid appear %d out of %d scan iterations",
+                    ssidAppearInScanResultsCount, mScanIterations));
+            long startTime = System.currentTimeMillis();
+            mAct.scanResultAvailable = false;
+            assertTrue("start scan failed", mAct.mWifiManager.startScanActive());
+            while (true) {
+                if ((System.currentTimeMillis() - startTime) >
+                ConnectivityManagerTestActivity.WIFI_SCAN_TIMEOUT) {
+                    fail("Wifi scanning takes more than " +
+                            ConnectivityManagerTestActivity.WIFI_SCAN_TIMEOUT + " ms");
+                }
+                synchronized(mAct) {
+                    try {
+                        mAct.wait(ConnectivityManagerTestActivity.WAIT_FOR_SCAN_RESULT);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    if (mAct.scanResultAvailable) {
+                        long scanTime = (System.currentTimeMillis() - startTime);
+                        scanTimeSum += scanTime;
+                        averageScanTime = scanTimeSum/mScanIterations;
+                        log("average scanning time: " + averageScanTime);
+                        break;
+                    }
+                }
+            }
+            if ((mAct.mWifiManager.getScanResults() == null) ||
+                    (mAct.mWifiManager.getScanResults().size() <= 0)) {
+                fail("Scan results are empty ");
+            }
+
+            List<ScanResult> netList = mAct.mWifiManager.getScanResults();
+            if (netList != null) {
+                log("size of scan result list: " + netList.size());
+                for (int s = 0; s < netList.size(); s++) {
+                    ScanResult sr= netList.get(s);
+                    log(String.format("scan result for %s is: %s", sr.SSID, sr.toString()));
+                    log(String.format("signal level for %s is %d ", sr.SSID, sr.level));
+                    if (sr.SSID.equals(mSsid)) {
+                        ssidAppearInScanResultsCount += 1;
+                        log("Number of times " + mSsid + " appear in the scan list: " +
+                                ssidAppearInScanResultsCount);
+                        break;
+                    }
+                }
+            }
+        }
+        if (i == mScanIterations) {
+            writeOutput(String.format("scan iteration %d out of %d",
+                    i, mScanIterations));
+            writeOutput(String.format("average scanning time is %d", averageScanTime));
+            writeOutput(String.format("ssid appear %d out of %d scan iterations",
+                    ssidAppearInScanResultsCount, mScanIterations));
+        }
+    }
+
+    // Stress Wifi reconnection to secure net after sleep
+    @LargeTest
+    public void testWifiReconnectionAfterSleep() {
+        int value = Settings.System.getInt(mRunner.getContext().getContentResolver(),
+                Settings.System.WIFI_SLEEP_POLICY, -1);
+        if (value < 0) {
+            Settings.System.putInt(mRunner.getContext().getContentResolver(),
+                    Settings.System.WIFI_SLEEP_POLICY, Settings.System.WIFI_SLEEP_POLICY_DEFAULT);
+            log("set wifi sleep policy to default value");
+        }
+        Settings.Secure.putLong(mRunner.getContext().getContentResolver(),
+                Settings.Secure.WIFI_IDLE_MS, WIFI_IDLE_MS);
+
+        // Connect to a Wi-Fi network
+        turnScreenOn();
+        WifiConfiguration config = new WifiConfiguration();
+        config.SSID = mSsid;
+        config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
+        if (mPassword.matches("[0-9A-Fa-f]{64}")) {
+            config.preSharedKey = mPassword;
+        } else {
+            config.preSharedKey = '"' + mPassword + '"';
+        }
+        config.ipAssignment = IpAssignment.DHCP;
+        config.proxySettings = ProxySettings.NONE;
+
+        assertTrue("Failed to connect to Wi-Fi network: " + mSsid,
+                mAct.connectToWifiWithConfiguration(config));
+        assertTrue(mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
+                ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+        assertTrue(mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                ConnectivityManagerTestActivity.LONG_TIMEOUT));
+        int i;
+        for (i = 0; i < mReconnectIterations; i++) {
+            // 1. Put device into sleep
+            // 2. Wait for the device to sleep for sometime, very 3G is connected
+            // 3. Wake up the device
+            writeOutput(String.format("reconnection after sleep iteration %d out of %d",
+                    i, mReconnectIterations));
+            log("iteration: " + i);
+            turnScreenOff();
+            PowerManager pm =
+                (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
+            assertFalse(pm.isScreenOn());
+            sleep(WIFI_IDLE_MS + WIFI_IDLE_DELAY, "Interruped while wait for wifi to be idle");
+            assertTrue("Wait for Wi-Fi to idle timeout",
+                    mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
+                    ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+            assertTrue("Wait for cellular connection timeout",
+                    mAct.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
+                    ConnectivityManagerTestActivity.LONG_TIMEOUT));
+            sleep(mWifiSleepTime + WIFI_IDLE_DELAY, "Interrupted while device is in sleep mode");
+            // Turn screen on again
+            turnScreenOn();
+            assertTrue("Wait for Wi-Fi enable timeout after wake up",
+                    mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
+                    ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+            assertTrue("Wait for Wi-Fi connection timeout after wake up",
+                    mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                    ConnectivityManagerTestActivity.LONG_TIMEOUT));
+        }
+        if (i == mReconnectIterations) {
+            writeOutput(String.format("reconnection after sleep iteration %d out of %d",
+                    i, mReconnectIterations));
+        }
+    }
+}
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 8450c3a..66f8f70 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -210,7 +210,6 @@
          * expense of the decoding speed. Currently the field only affects JPEG
          * decode, in the case of which a more accurate, but slightly slower,
          * IDCT method will be used instead.
-         * @hide
          */
         public boolean inPreferQualityOverSpeed;
 
diff --git a/include/media/IStreamSource.h b/include/media/IStreamSource.h
index 6291124..4b698e6 100644
--- a/include/media/IStreamSource.h
+++ b/include/media/IStreamSource.h
@@ -22,6 +22,7 @@
 
 namespace android {
 
+struct AMessage;
 struct IMemory;
 struct IStreamListener;
 
@@ -38,13 +39,14 @@
     DECLARE_META_INTERFACE(StreamListener);
 
     enum Command {
-        FLUSH,
+        EOS,
         DISCONTINUITY,
-        EOS
     };
 
     virtual void queueBuffer(size_t index, size_t size) = 0;
-    virtual void queueCommand(Command cmd) = 0;
+
+    virtual void issueCommand(
+            Command cmd, bool synchronous, const sp<AMessage> &msg = NULL) = 0;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h
index c674cba..2fbdddc 100644
--- a/include/media/stagefright/foundation/AMessage.h
+++ b/include/media/stagefright/foundation/AMessage.h
@@ -26,10 +26,14 @@
 namespace android {
 
 struct AString;
+struct Parcel;
 
 struct AMessage : public RefBase {
     AMessage(uint32_t what = 0, ALooper::handler_id target = 0);
 
+    static sp<AMessage> FromParcel(const Parcel &parcel);
+    void writeToParcel(Parcel *parcel) const;
+
     void setWhat(uint32_t what);
     uint32_t what() const;
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index fc14777..1a89ca0 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -954,11 +954,11 @@
                 mSnapshot->region && mesh->hasEmptyQuads) {
             const size_t count = mesh->quads.size();
             for (size_t i = 0; i < count; i++) {
-                Rect bounds = mesh->quads.itemAt(i);
+                const Rect& bounds = mesh->quads.itemAt(i);
                 if (pureTranslate) {
                     const float x = (int) floorf(bounds.left + 0.5f);
                     const float y = (int) floorf(bounds.top + 0.5f);
-                    dirtyLayer(x, y, x + bounds.getWidth(), y + bounds.getBottom(),
+                    dirtyLayer(x, y, x + bounds.getWidth(), y + bounds.getHeight(),
                             *mSnapshot->transform);
                 } else {
                     dirtyLayer(bounds.left, bounds.top, bounds.right, bounds.bottom,
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 17b1d86..e5cb67b 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -35,7 +35,7 @@
         mXCount(xCount), mYCount(yCount), mEmptyQuads(emptyQuads) {
     // Initialized with the maximum number of vertices we will need
     // 2 triangles per patch, 3 vertices per triangle
-    const int maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
+    uint32_t maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
     mVertices = new TextureVertex[maxVertices];
     mUploaded = false;
 
@@ -160,7 +160,7 @@
         float y2 = 0.0f;
         if (i & 1) {
             const float segment = stepY - previousStepY;
-            y2 = y1 + segment * stretchY;
+            y2 = y1 + floorf(segment * stretchY + 0.5f);
         } else {
             y2 = y1 + stepY - previousStepY;
         }
@@ -206,7 +206,7 @@
         float x2 = 0.0f;
         if (i & 1) {
             const float segment = stepX - previousStepX;
-            x2 = x1 + segment * stretchX;
+            x2 = x1 + floorf(segment * stretchX + 0.5f);
         } else {
             x2 = x1 + stepX - previousStepX;
         }
@@ -226,7 +226,7 @@
 void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
             float u1, float v1, float u2, float v2, uint32_t& quadCount) {
     const uint32_t oldQuadCount = quadCount;
-    const bool valid = fabs(x2 - x1) > 0.9999f && fabs(y2 - y1) > 0.9999f;
+    const bool valid = x2 - x1 > 0.9999f && y2 - y1 > 0.9999f;
     if (valid) {
         quadCount++;
     }
diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h
index 16ad86d..0f0ffa2 100644
--- a/libs/hwui/Patch.h
+++ b/libs/hwui/Patch.h
@@ -52,9 +52,7 @@
     GLuint meshBuffer;
     uint32_t verticesCount;
     bool hasEmptyQuads;
-#if RENDER_LAYERS_AS_REGIONS
     Vector<Rect> quads;
-#endif
 
 private:
     TextureVertex* mVertices;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 6587b51..d4edafd 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -378,6 +378,12 @@
 static BCCvoid* symbolLookup(BCCvoid* pContext, const BCCchar* name) {
     const ScriptCState::SymbolTable_t *sym;
     ScriptC *s = (ScriptC *)pContext;
+    if (!strcmp(name, "__isThreadable")) {
+      return (BCCvoid*) s->mEnviroment.mIsThreadable;
+    } else if (!strcmp(name, "__clearThreadable")) {
+      s->mEnviroment.mIsThreadable = false;
+      return NULL;
+    }
     sym = ScriptCState::lookupSymbol(name);
     if (!sym) {
         sym = ScriptCState::lookupSymbolCL(name);
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index d3a71b3..d539833 100755
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -28,6 +28,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.android.internal.R;
+
 /**
  * A GPS Network-initiated Handler class used by LocationManager.
  *
@@ -182,8 +184,8 @@
             return;
         }
 
-        String title = getNotifTitle(notif);
-        String message = getNotifMessage(notif);
+        String title = getNotifTitle(notif, mContext);
+        String message = getNotifMessage(notif, mContext);
 
         if (DEBUG) Log.d(TAG, "setNiNotification, notifyId: " + notif.notificationId +
                 ", title: " + title +
@@ -203,7 +205,7 @@
         }        
 
         mNiNotification.flags = Notification.FLAG_ONGOING_EVENT;
-        mNiNotification.tickerText = getNotifTicker(notif);
+        mNiNotification.tickerText = getNotifTicker(notif, mContext);
 
         // if not to popup dialog immediately, pending intent will open the dialog
         Intent intent = !mPopupImmediately ? getDlgIntent(notif) : new Intent();
@@ -234,8 +236,8 @@
     private Intent getDlgIntent(GpsNiNotification notif)
     {
         Intent intent = new Intent();
-        String title = getDialogTitle(notif);
-        String message = getDialogMessage(notif);
+        String title = getDialogTitle(notif, mContext);
+        String message = getDialogMessage(notif, mContext);
 
         // directly bring up the NI activity
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -412,41 +414,40 @@
     }
 
     // change this to configure notification display
-    static private String getNotifTicker(GpsNiNotification notif)
+    static private String getNotifTicker(GpsNiNotification notif, Context context)
     {
-        String ticker = String.format("Position request! ReqId: [%s] ClientName: [%s]",
+        String ticker = String.format(context.getString(R.string.gpsNotifTicker),
                 decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
                 decodeString(notif.text, mIsHexInput, notif.textEncoding));
         return ticker;
     }
 
     // change this to configure notification display
-    static private String getNotifTitle(GpsNiNotification notif)
+    static private String getNotifTitle(GpsNiNotification notif, Context context)
     {
-        String title = String.format("Position Request");
+        String title = String.format(context.getString(R.string.gpsNotifTitle));
         return title;
     }
 
     // change this to configure notification display
-    static private String getNotifMessage(GpsNiNotification notif)
+    static private String getNotifMessage(GpsNiNotification notif, Context context)
     {
-        String message = String.format(
-                "NI Request received from [%s] for client [%s]!",
+        String message = String.format(context.getString(R.string.gpsNotifMessage),
                 decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
                 decodeString(notif.text, mIsHexInput, notif.textEncoding));
         return message;
     }       
 
     // change this to configure dialog display (for verification)
-    static public String getDialogTitle(GpsNiNotification notif)
+    static public String getDialogTitle(GpsNiNotification notif, Context context)
     {
-        return getNotifTitle(notif);
+        return getNotifTitle(notif, context);
     }
 
     // change this to configure dialog display (for verification)
-    static private String getDialogMessage(GpsNiNotification notif)
+    static private String getDialogMessage(GpsNiNotification notif, Context context)
     {
-        return getNotifMessage(notif);
+        return getNotifMessage(notif, context);
     }
 
 }
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 731c09d..74fb531 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -36,7 +36,8 @@
     fixedfft.cpp.arm
 
 LOCAL_SHARED_LIBRARIES := \
-	libui libcutils libutils libbinder libsonivox libicuuc libexpat libsurfaceflinger_client libcamera_client
+	libui libcutils libutils libbinder libsonivox libicuuc libexpat \
+        libsurfaceflinger_client libcamera_client libstagefright_foundation
 
 LOCAL_MODULE:= libmedia
 
diff --git a/media/libmedia/IStreamSource.cpp b/media/libmedia/IStreamSource.cpp
index 89f2b44..5069002 100644
--- a/media/libmedia/IStreamSource.cpp
+++ b/media/libmedia/IStreamSource.cpp
@@ -19,6 +19,7 @@
 #include <utils/Log.h>
 
 #include <media/IStreamSource.h>
+#include <media/stagefright/foundation/AMessage.h>
 
 #include <binder/IMemory.h>
 #include <binder/Parcel.h>
@@ -33,7 +34,7 @@
 
     // IStreamListener
     QUEUE_BUFFER,
-    QUEUE_COMMAND,
+    ISSUE_COMMAND,
 };
 
 struct BpStreamSource : public BpInterface<IStreamSource> {
@@ -125,12 +126,21 @@
         remote()->transact(QUEUE_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
-    virtual void queueCommand(Command cmd) {
+    virtual void issueCommand(
+            Command cmd, bool synchronous, const sp<AMessage> &msg) {
         Parcel data, reply;
         data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor());
         data.writeInt32(static_cast<int32_t>(cmd));
+        data.writeInt32(static_cast<int32_t>(synchronous));
 
-        remote()->transact(QUEUE_COMMAND, data, &reply, IBinder::FLAG_ONEWAY);
+        if (msg != NULL) {
+            data.writeInt32(1);
+            msg->writeToParcel(&data);
+        } else {
+            data.writeInt32(0);
+        }
+
+        remote()->transact(ISSUE_COMMAND, data, &reply, IBinder::FLAG_ONEWAY);
     }
 };
 
@@ -149,12 +159,20 @@
             break;
         }
 
-        case QUEUE_COMMAND:
+        case ISSUE_COMMAND:
         {
             CHECK_INTERFACE(IStreamListener, data, reply);
             Command cmd = static_cast<Command>(data.readInt32());
 
-            queueCommand(cmd);
+            bool synchronous = static_cast<bool>(data.readInt32());
+
+            sp<AMessage> msg;
+
+            if (data.readInt32()) {
+                msg = AMessage::FromParcel(data);
+            }
+
+            issueCommand(cmd, synchronous, msg);
             break;
         }
 
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 2743a3a..7613d04 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -50,6 +50,7 @@
 #include <surfaceflinger/Surface.h>
 
 #include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
 #include "include/LiveSession.h"
 
 #define USE_SURFACE_ALLOC 1
@@ -170,7 +171,9 @@
     void clearOwner();
 
     virtual void queueBuffer(size_t index, size_t size);
-    virtual void queueCommand(Command cmd);
+
+    virtual void issueCommand(
+            Command cmd, bool synchronous, const sp<AMessage> &msg);
 
 private:
     Mutex mLock;
@@ -188,7 +191,11 @@
     virtual ssize_t readAt(off64_t offset, void *data, size_t size);
 
     virtual void queueBuffer(size_t index, size_t size);
-    virtual void queueCommand(IStreamListener::Command cmd);
+
+    virtual void issueCommand(
+            IStreamListener::Command cmd,
+            bool synchronous,
+            const sp<AMessage> &msg);
 
 protected:
     virtual ~QueueDataSource();
@@ -198,7 +205,12 @@
         kNumBuffers = 16
     };
 
-    struct BufferInfo {
+    struct QueueEntry {
+        bool mIsCommand;
+
+        IStreamListener::Command mCommand;
+        sp<AMessage> mCommandMessage;
+
         size_t mIndex;
         size_t mOffset;
         size_t mSize;
@@ -212,7 +224,7 @@
     sp<MemoryDealer> mDealer;
     Vector<sp<IMemory> > mBuffers;
 
-    List<BufferInfo> mFilledBuffers;
+    List<QueueEntry> mQueue;
 
     off64_t mPosition;
     bool mEOS;
@@ -227,7 +239,7 @@
     mListener = new QueueListener(this);
     mSource->setListener(mListener);
 
-    static const size_t kBufferSize = 8192;
+    static const size_t kBufferSize = (8192 / 188) * 188;
 
     mDealer = new MemoryDealer(kNumBuffers * kBufferSize);
     for (size_t i = 0; i < kNumBuffers; ++i) {
@@ -246,10 +258,6 @@
 QueueDataSource::~QueueDataSource() {
     Mutex::Autolock autoLock(mLock);
 
-    while (mFilledBuffers.size() < kNumBuffers && !mEOS) {
-        mCondition.wait(mLock);
-    }
-
     mListener->clearOwner();
 }
 
@@ -264,40 +272,69 @@
 
     Mutex::Autolock autoLock(mLock);
 
+    if (mEOS) {
+        return ERROR_END_OF_STREAM;
+    }
+
     size_t sizeDone = 0;
 
     while (sizeDone < size) {
-        while (mFilledBuffers.empty() && !mEOS) {
+        while (mQueue.empty()) {
             mCondition.wait(mLock);
         }
 
-        if (mFilledBuffers.empty()) {
-            if (sizeDone > 0) {
-                mPosition += sizeDone;
-                return sizeDone;
+        QueueEntry &entry = *mQueue.begin();
+
+        if (entry.mIsCommand) {
+            switch (entry.mCommand) {
+                case IStreamListener::EOS:
+                {
+                    mEOS = true;
+
+                    if (sizeDone > 0) {
+                        offset += sizeDone;
+                        return sizeDone;
+                    } else {
+                        return ERROR_END_OF_STREAM;
+                    }
+                    break;
+                }
+
+                case IStreamListener::DISCONTINUITY:
+                {
+                    CHECK_EQ(size, 188u);
+                    CHECK_EQ(sizeDone, 0u);
+
+                    memset(data, 0, size);
+                    sizeDone = size;
+                    break;
+                }
+
+                default:
+                    break;
             }
-            return ERROR_END_OF_STREAM;
+
+            mQueue.erase(mQueue.begin());
+            continue;
         }
 
-        BufferInfo &info = *mFilledBuffers.begin();
-
         size_t copy = size - sizeDone;
-        if (copy > info.mSize) {
-            copy = info.mSize;
+        if (copy > entry.mSize) {
+            copy = entry.mSize;
         }
 
         memcpy((uint8_t *)data + sizeDone,
-               (const uint8_t *)mBuffers.itemAt(info.mIndex)->pointer()
-                    + info.mOffset,
+               (const uint8_t *)mBuffers.itemAt(entry.mIndex)->pointer()
+                    + entry.mOffset,
                copy);
 
-        info.mSize -= copy;
-        info.mOffset += copy;
+        entry.mSize -= copy;
+        entry.mOffset += copy;
         sizeDone += copy;
 
-        if (info.mSize == 0) {
-            mSource->onBufferAvailable(info.mIndex);
-            mFilledBuffers.erase(mFilledBuffers.begin());
+        if (entry.mSize == 0) {
+            mSource->onBufferAvailable(entry.mIndex);
+            mQueue.erase(mQueue.begin());
         }
     }
 
@@ -312,22 +349,31 @@
     CHECK_LT(index, mBuffers.size());
     CHECK_LE(size, mBuffers.itemAt(index)->size());
 
-    BufferInfo info;
-    info.mIndex = index;
-    info.mSize = size;
-    info.mOffset = 0;
+    QueueEntry entry;
+    entry.mIsCommand = false;
+    entry.mIndex = index;
+    entry.mSize = size;
+    entry.mOffset = 0;
 
-    mFilledBuffers.push_back(info);
+    mQueue.push_back(entry);
     mCondition.signal();
 }
 
-void QueueDataSource::queueCommand(IStreamListener::Command cmd) {
+void QueueDataSource::issueCommand(
+        IStreamListener::Command cmd,
+        bool synchronous,
+        const sp<AMessage> &msg) {
     Mutex::Autolock autoLock(mLock);
 
-    if (cmd == IStreamListener::EOS) {
-        mEOS = true;
-        mCondition.signal();
-    }
+    CHECK(!synchronous);
+
+    QueueEntry entry;
+    entry.mIsCommand = true;
+    entry.mCommand = cmd;
+    entry.mCommandMessage = msg;
+    mQueue.push_back(entry);
+
+    mCondition.signal();
 }
 
 void QueueListener::clearOwner() {
@@ -343,12 +389,13 @@
     mOwner->queueBuffer(index, size);
 }
 
-void QueueListener::queueCommand(Command cmd) {
+void QueueListener::issueCommand(
+        Command cmd, bool synchronous, const sp<AMessage> &msg) {
     Mutex::Autolock autoLock(mLock);
     if (mOwner == NULL) {
         return;
     }
-    mOwner->queueCommand(cmd);
+    mOwner->issueCommand(cmd, synchronous, msg);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -469,18 +516,9 @@
     reset_l();
 
     sp<DataSource> dataSource = new QueueDataSource(source);
-
-#if 0
-    sp<MediaExtractor> extractor =
-        MediaExtractor::Create(dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
+    sp<MediaExtractor> extractor = new MPEG2TSExtractor(dataSource);
 
     return setDataSource_l(extractor);
-#else
-    sp<NuCachedSource2> cached = new NuCachedSource2(dataSource);
-    dataSource = cached;
-
-    return setDataSource_l(dataSource);
-#endif
 }
 
 status_t AwesomePlayer::setDataSource_l(
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index 26c6d42..7da9cb8 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -23,6 +23,8 @@
 #include "ALooperRoster.h"
 #include "AString.h"
 
+#include <binder/Parcel.h>
+
 namespace android {
 
 AMessage::AMessage(uint32_t what, ALooper::handler_id target)
@@ -341,4 +343,136 @@
     return s;
 }
 
+// static
+sp<AMessage> AMessage::FromParcel(const Parcel &parcel) {
+    int32_t what = parcel.readInt32();
+    sp<AMessage> msg = new AMessage(what);
+
+    msg->mNumItems = static_cast<size_t>(parcel.readInt32());
+
+    for (size_t i = 0; i < msg->mNumItems; ++i) {
+        Item *item = &msg->mItems[i];
+
+        item->mName = AAtomizer::Atomize(parcel.readCString());
+        item->mType = static_cast<Type>(parcel.readInt32());
+
+        switch (item->mType) {
+            case kTypeInt32:
+            {
+                item->u.int32Value = parcel.readInt32();
+                break;
+            }
+
+            case kTypeInt64:
+            {
+                item->u.int64Value = parcel.readInt64();
+                break;
+            }
+
+            case kTypeSize:
+            {
+                item->u.sizeValue = static_cast<size_t>(parcel.readInt32());
+                break;
+            }
+
+            case kTypeFloat:
+            {
+                item->u.floatValue = parcel.readFloat();
+                break;
+            }
+
+            case kTypeDouble:
+            {
+                item->u.doubleValue = parcel.readDouble();
+                break;
+            }
+
+            case kTypeString:
+            {
+                item->u.stringValue = new AString(parcel.readCString());
+                break;
+            }
+
+            case kTypeMessage:
+            {
+                sp<AMessage> subMsg = AMessage::FromParcel(parcel);
+                subMsg->incStrong(msg.get());
+
+                item->u.refValue = subMsg.get();
+                break;
+            }
+
+            default:
+            {
+                LOGE("This type of object cannot cross process boundaries.");
+                TRESPASS();
+            }
+        }
+    }
+
+    return msg;
+}
+
+void AMessage::writeToParcel(Parcel *parcel) const {
+    parcel->writeInt32(static_cast<int32_t>(mWhat));
+    parcel->writeInt32(static_cast<int32_t>(mNumItems));
+
+    for (size_t i = 0; i < mNumItems; ++i) {
+        const Item &item = mItems[i];
+
+        parcel->writeCString(item.mName);
+        parcel->writeInt32(static_cast<int32_t>(item.mType));
+
+        switch (item.mType) {
+            case kTypeInt32:
+            {
+                parcel->writeInt32(item.u.int32Value);
+                break;
+            }
+
+            case kTypeInt64:
+            {
+                parcel->writeInt64(item.u.int64Value);
+                break;
+            }
+
+            case kTypeSize:
+            {
+                parcel->writeInt32(static_cast<int32_t>(item.u.sizeValue));
+                break;
+            }
+
+            case kTypeFloat:
+            {
+                parcel->writeFloat(item.u.floatValue);
+                break;
+            }
+
+            case kTypeDouble:
+            {
+                parcel->writeDouble(item.u.doubleValue);
+                break;
+            }
+
+            case kTypeString:
+            {
+                parcel->writeCString(item.u.stringValue->c_str());
+                break;
+            }
+
+            case kTypeMessage:
+            {
+                static_cast<AMessage *>(item.u.refValue)->writeToParcel(parcel);
+                break;
+            }
+
+            default:
+            {
+                LOGE("This type of object cannot cross process boundaries.");
+                TRESPASS();
+            }
+        }
+    }
+}
+
 }  // namespace android
diff --git a/media/libstagefright/foundation/Android.mk b/media/libstagefright/foundation/Android.mk
index ffa7db0..a4d4809 100644
--- a/media/libstagefright/foundation/Android.mk
+++ b/media/libstagefright/foundation/Android.mk
@@ -18,14 +18,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
         libbinder         \
-        libmedia          \
         libutils          \
-        libcutils         \
-        libui             \
-        libsonivox        \
-        libvorbisidec     \
-        libsurfaceflinger_client \
-        libcamera_client
 
 LOCAL_CFLAGS += -Wno-multichar
 
diff --git a/opengl/java/android/opengl/ETC1.java b/opengl/java/android/opengl/ETC1.java
index f3dac77..fb5f9b4 100644
--- a/opengl/java/android/opengl/ETC1.java
+++ b/opengl/java/android/opengl/ETC1.java
@@ -1,11 +1,11 @@
 /*
- *  Copyright 2009 Google Inc.
+ * 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
+ *      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,
diff --git a/opengl/java/android/opengl/ETC1Util.java b/opengl/java/android/opengl/ETC1Util.java
index dd28d1d..3629d41 100644
--- a/opengl/java/android/opengl/ETC1Util.java
+++ b/opengl/java/android/opengl/ETC1Util.java
@@ -1,11 +1,11 @@
 /*
- *  Copyright 2009 Google Inc.
+ * 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
+ *      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,
diff --git a/opengl/java/android/opengl/GLES10.java b/opengl/java/android/opengl/GLES10.java
index 790acbd..7c0f949 100644
--- a/opengl/java/android/opengl/GLES10.java
+++ b/opengl/java/android/opengl/GLES10.java
@@ -1,19 +1,18 @@
 /*
-**
-** Copyright 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.
-*/
+ * 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 source file is automatically generated
 
diff --git a/opengl/java/android/opengl/GLES10Ext.java b/opengl/java/android/opengl/GLES10Ext.java
index 81fc59e..116ab9d 100644
--- a/opengl/java/android/opengl/GLES10Ext.java
+++ b/opengl/java/android/opengl/GLES10Ext.java
@@ -1,19 +1,18 @@
 /*
-**
-** Copyright 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.
-*/
+ * 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 source file is automatically generated
 
diff --git a/opengl/java/android/opengl/GLES11.java b/opengl/java/android/opengl/GLES11.java
index 1ca179b..b24c043 100644
--- a/opengl/java/android/opengl/GLES11.java
+++ b/opengl/java/android/opengl/GLES11.java
@@ -1,19 +1,18 @@
 /*
-**
-** Copyright 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.
-*/
+ * 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 source file is automatically generated
 
diff --git a/opengl/java/android/opengl/GLES11Ext.java b/opengl/java/android/opengl/GLES11Ext.java
index 25d5467..a9a7a22 100644
--- a/opengl/java/android/opengl/GLES11Ext.java
+++ b/opengl/java/android/opengl/GLES11Ext.java
@@ -1,19 +1,18 @@
 /*
-**
-** Copyright 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.
-*/
+ * 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 source file is automatically generated
 
diff --git a/opengl/java/android/opengl/GLES20.java b/opengl/java/android/opengl/GLES20.java
index 635f811..700164b 100644
--- a/opengl/java/android/opengl/GLES20.java
+++ b/opengl/java/android/opengl/GLES20.java
@@ -1,19 +1,18 @@
 /*
-**
-** Copyright 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.
-*/
+ * 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 source file is automatically generated
 
diff --git a/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java b/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java
index b03392e..c2f4400 100644
--- a/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java
@@ -1,19 +1,18 @@
-/* 
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package com.google.android.gles_jni;
 
diff --git a/opengl/java/com/google/android/gles_jni/EGLContextImpl.java b/opengl/java/com/google/android/gles_jni/EGLContextImpl.java
index f10c02f..9cf5de7 100644
--- a/opengl/java/com/google/android/gles_jni/EGLContextImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLContextImpl.java
@@ -1,19 +1,18 @@
-/* 
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package com.google.android.gles_jni;
 
diff --git a/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java b/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java
index 6321632..cb94888 100644
--- a/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java
@@ -1,19 +1,18 @@
-/* 
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package com.google.android.gles_jni;
 
diff --git a/opengl/java/com/google/android/gles_jni/EGLImpl.java b/opengl/java/com/google/android/gles_jni/EGLImpl.java
index 3e06ded..8a7124d 100644
--- a/opengl/java/com/google/android/gles_jni/EGLImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLImpl.java
@@ -1,19 +1,18 @@
 /*
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package com.google.android.gles_jni;
 
diff --git a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
index 66cc200..f6b90ab 100644
--- a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
@@ -1,19 +1,18 @@
-/* 
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package com.google.android.gles_jni;
 
diff --git a/opengl/java/com/google/android/gles_jni/GLImpl.java b/opengl/java/com/google/android/gles_jni/GLImpl.java
index 090c0cb7..50f6760 100644
--- a/opengl/java/com/google/android/gles_jni/GLImpl.java
+++ b/opengl/java/com/google/android/gles_jni/GLImpl.java
@@ -1,19 +1,18 @@
-/* //device/java/android/com/google/android/gles_jni/GLImpl.java
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 // This source file is automatically generated
 
diff --git a/opengl/java/javax/microedition/khronos/egl/EGL.java b/opengl/java/javax/microedition/khronos/egl/EGL.java
index b743968..18f8ae6 100644
--- a/opengl/java/javax/microedition/khronos/egl/EGL.java
+++ b/opengl/java/javax/microedition/khronos/egl/EGL.java
@@ -1,19 +1,18 @@
-/* 
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package javax.microedition.khronos.egl;
 
diff --git a/opengl/java/javax/microedition/khronos/egl/EGLConfig.java b/opengl/java/javax/microedition/khronos/egl/EGLConfig.java
index a1e496c..c8a9ba2 100644
--- a/opengl/java/javax/microedition/khronos/egl/EGLConfig.java
+++ b/opengl/java/javax/microedition/khronos/egl/EGLConfig.java
@@ -1,19 +1,18 @@
-/* 
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package javax.microedition.khronos.egl;
 
diff --git a/opengl/java/javax/microedition/khronos/egl/EGLContext.java b/opengl/java/javax/microedition/khronos/egl/EGLContext.java
index fc94492..f8d745d 100644
--- a/opengl/java/javax/microedition/khronos/egl/EGLContext.java
+++ b/opengl/java/javax/microedition/khronos/egl/EGLContext.java
@@ -1,19 +1,18 @@
-/* 
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package javax.microedition.khronos.egl;
 
diff --git a/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java b/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java
index cd8a755..5368b4b 100644
--- a/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java
+++ b/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java
@@ -1,19 +1,18 @@
-/* 
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package javax.microedition.khronos.egl;
 
diff --git a/opengl/java/javax/microedition/khronos/egl/EGLSurface.java b/opengl/java/javax/microedition/khronos/egl/EGLSurface.java
index 5349bc1..e1d08d3 100644
--- a/opengl/java/javax/microedition/khronos/egl/EGLSurface.java
+++ b/opengl/java/javax/microedition/khronos/egl/EGLSurface.java
@@ -1,19 +1,18 @@
-/* 
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package javax.microedition.khronos.egl;
 
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL.java b/opengl/java/javax/microedition/khronos/opengles/GL.java
index 3b78f3d..d5b60c6 100644
--- a/opengl/java/javax/microedition/khronos/opengles/GL.java
+++ b/opengl/java/javax/microedition/khronos/opengles/GL.java
@@ -1,19 +1,18 @@
-/* //device/java/android/javax/microedition/khronos/opengles/GL.java
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package javax.microedition.khronos.opengles;
 
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL10.java b/opengl/java/javax/microedition/khronos/opengles/GL10.java
index 4fcfb52..f48ecde 100644
--- a/opengl/java/javax/microedition/khronos/opengles/GL10.java
+++ b/opengl/java/javax/microedition/khronos/opengles/GL10.java
@@ -1,19 +1,18 @@
-/* //device/java/android/javax/microedition/khronos/opengles/GL10.java
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 // This source file is automatically generated
 
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java b/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java
index 562b20a..f3252ab 100644
--- a/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java
+++ b/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java
@@ -1,19 +1,18 @@
-/* //device/java/android/javax/microedition/khronos/opengles/GL10Ext.java
-**
-** Copyright 2007, 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.
-*/
+/*
+ * Copyright (C) 2007 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 source file is automatically generated
 
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL11.java b/opengl/java/javax/microedition/khronos/opengles/GL11.java
index 3ba110c..943a5be 100644
--- a/opengl/java/javax/microedition/khronos/opengles/GL11.java
+++ b/opengl/java/javax/microedition/khronos/opengles/GL11.java
@@ -1,19 +1,18 @@
-/* //device/java/android/javax/microedition/khronos/opengles/GL11.java
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 // This source file is automatically generated
 
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java b/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java
index 459a1ab..842db7a 100644
--- a/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java
+++ b/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java
@@ -1,19 +1,18 @@
-/* //device/java/android/javax/microedition/khronos/opengles/GL11Ext.java
-**
-** Copyright 2007, 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.
-*/
+/*
+ * Copyright (C) 2007 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 source file is automatically generated
 
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java b/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java
index 933c91e..97d5fd8 100644
--- a/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java
+++ b/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java
@@ -1,19 +1,18 @@
-/* //device/java/android/javax/microedition/khronos/opengles/GL11ExtensionPack.java
-**
-** Copyright 2007, 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.
-*/
+/*
+ * Copyright (C) 2007 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 source file is automatically generated
 
diff --git a/opengl/tests/gl2_java/AndroidManifest.xml b/opengl/tests/gl2_java/AndroidManifest.xml
index 585b63f1..8bb6840 100644
--- a/opengl/tests/gl2_java/AndroidManifest.xml
+++ b/opengl/tests/gl2_java/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gl2_java/res/values/strings.xml b/opengl/tests/gl2_java/res/values/strings.xml
index d718b1d..06bd23c 100644
--- a/opengl/tests/gl2_java/res/values/strings.xml
+++ b/opengl/tests/gl2_java/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+<!-- Copyright (C) 2006 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/gl2_jni/AndroidManifest.xml b/opengl/tests/gl2_jni/AndroidManifest.xml
index a72a6a5..1827e5f 100644
--- a/opengl/tests/gl2_jni/AndroidManifest.xml
+++ b/opengl/tests/gl2_jni/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gl2_jni/res/values/strings.xml b/opengl/tests/gl2_jni/res/values/strings.xml
index e3f7331..a29c74b 100644
--- a/opengl/tests/gl2_jni/res/values/strings.xml
+++ b/opengl/tests/gl2_jni/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+<!-- Copyright (C) 2006 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/gl_jni/AndroidManifest.xml b/opengl/tests/gl_jni/AndroidManifest.xml
index 64bd6bf..5d0ec96 100644
--- a/opengl/tests/gl_jni/AndroidManifest.xml
+++ b/opengl/tests/gl_jni/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gl_jni/res/values/strings.xml b/opengl/tests/gl_jni/res/values/strings.xml
index 880f5c9..aee9fa0 100644
--- a/opengl/tests/gl_jni/res/values/strings.xml
+++ b/opengl/tests/gl_jni/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+<!-- Copyright (C) 2006 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/gl_perfapp/AndroidManifest.xml b/opengl/tests/gl_perfapp/AndroidManifest.xml
index 305d95f..ee4bd98 100644
--- a/opengl/tests/gl_perfapp/AndroidManifest.xml
+++ b/opengl/tests/gl_perfapp/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gl_perfapp/res/values/strings.xml b/opengl/tests/gl_perfapp/res/values/strings.xml
index dc21075..52cd961 100644
--- a/opengl/tests/gl_perfapp/res/values/strings.xml
+++ b/opengl/tests/gl_perfapp/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+<!-- Copyright (C) 2006 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/gldual/AndroidManifest.xml b/opengl/tests/gldual/AndroidManifest.xml
index 06f4c4d..a36f4f7 100644
--- a/opengl/tests/gldual/AndroidManifest.xml
+++ b/opengl/tests/gldual/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gldual/res/values/strings.xml b/opengl/tests/gldual/res/values/strings.xml
index 4267dff..b1f535d 100644
--- a/opengl/tests/gldual/res/values/strings.xml
+++ b/opengl/tests/gldual/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+<!-- Copyright (C) 2006 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/testFramerate/AndroidManifest.xml b/opengl/tests/testFramerate/AndroidManifest.xml
index e04342c..85617f4 100644
--- a/opengl/tests/testFramerate/AndroidManifest.xml
+++ b/opengl/tests/testFramerate/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/testFramerate/res/values/strings.xml b/opengl/tests/testFramerate/res/values/strings.xml
index e6b3088..baadf0e 100644
--- a/opengl/tests/testFramerate/res/values/strings.xml
+++ b/opengl/tests/testFramerate/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+<!-- Copyright (C) 2006 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/testLatency/AndroidManifest.xml b/opengl/tests/testLatency/AndroidManifest.xml
index 741266e..59f2643 100644
--- a/opengl/tests/testLatency/AndroidManifest.xml
+++ b/opengl/tests/testLatency/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/testLatency/res/values/strings.xml b/opengl/tests/testLatency/res/values/strings.xml
index 0309991..d80b77c 100644
--- a/opengl/tests/testLatency/res/values/strings.xml
+++ b/opengl/tests/testLatency/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+<!-- Copyright (C) 2006 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/testPauseResume/AndroidManifest.xml b/opengl/tests/testPauseResume/AndroidManifest.xml
index 3e8e7e7..1879bc3 100644
--- a/opengl/tests/testPauseResume/AndroidManifest.xml
+++ b/opengl/tests/testPauseResume/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/testPauseResume/res/values/strings.xml b/opengl/tests/testPauseResume/res/values/strings.xml
index 208fe15..b4c98fe2 100644
--- a/opengl/tests/testPauseResume/res/values/strings.xml
+++ b/opengl/tests/testPauseResume/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+<!-- Copyright (C) 2006 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/testViewport/AndroidManifest.xml b/opengl/tests/testViewport/AndroidManifest.xml
index 90a9d2d..ba178bb 100644
--- a/opengl/tests/testViewport/AndroidManifest.xml
+++ b/opengl/tests/testViewport/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/testViewport/res/values/strings.xml b/opengl/tests/testViewport/res/values/strings.xml
index f4b8bbb..c037a7c 100644
--- a/opengl/tests/testViewport/res/values/strings.xml
+++ b/opengl/tests/testViewport/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+<!-- Copyright (C) 2006 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tools/glgen/stubs/gles11/glGetString.java b/opengl/tools/glgen/stubs/gles11/glGetString.java
index d44a6dd..b02a0d1 100644
--- a/opengl/tools/glgen/stubs/gles11/glGetString.java
+++ b/opengl/tools/glgen/stubs/gles11/glGetString.java
@@ -1,21 +1,21 @@
-/*

- * 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.

- */

-

-    // C function const GLubyte * glGetString ( GLenum name )

-

-    public static native String glGetString(

-        int name

-    );

+/*
+ * 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.
+ */
+
+    // C function const GLubyte * glGetString ( GLenum name )
+
+    public static native String glGetString(
+        int name
+    );
diff --git a/packages/DefaultContainerService/Android.mk b/packages/DefaultContainerService/Android.mk
index 986b6c8..56b8005 100755
--- a/packages/DefaultContainerService/Android.mk
+++ b/packages/DefaultContainerService/Android.mk
@@ -7,7 +7,7 @@
 
 LOCAL_PACKAGE_NAME := DefaultContainerService
 
-LOCAL_JNI_SHARED_LIBRARIES := libdefcontainer_jni
+LOCAL_REQUIRED_MODULES := libdefcontainer_jni
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 535f07f..f1fa0ff 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1015,7 +1015,10 @@
 
     sp<Client> client = getClientFromCookie(user);
     if (client == 0) return;
-    if (!client->lockIfMessageWanted(msgType)) return;
+    if (!client->lockIfMessageWanted(msgType)) {
+        client->releaseRecordingFrame(dataPtr);
+        return;
+    }
 
     if (dataPtr == 0) {
         LOGE("Null data returned in data with timestamp callback");
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index f1fce3e..9d11d87 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -24,6 +24,7 @@
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.net.ConnectivityManager;
+import android.net.DummyDataStateTracker;
 import android.net.IConnectivityManager;
 import android.net.MobileDataStateTracker;
 import android.net.NetworkInfo;
@@ -386,7 +387,6 @@
          * the number of different network types is not going
          * to change very often.
          */
-        boolean noMobileData = !getMobileDataEnabled();
         for (int netType : mPriorityList) {
             switch (mNetAttributes[netType].mRadio) {
             case ConnectivityManager.TYPE_WIFI:
@@ -406,10 +406,11 @@
                 mNetTrackers[netType] = new MobileDataStateTracker(netType,
                         mNetAttributes[netType].mName);
                 mNetTrackers[netType].startMonitoring(context, mHandler);
-                if (noMobileData) {
-                    if (DBG) log("tearing down Mobile networks due to setting");
-                    mNetTrackers[netType].teardown();
-                }
+                break;
+            case ConnectivityManager.TYPE_DUMMY:
+                mNetTrackers[netType] = new DummyDataStateTracker(netType,
+                        mNetAttributes[netType].mName);
+                mNetTrackers[netType].startMonitoring(context, mHandler);
                 break;
             default:
                 loge("Trying to create a DataStateTracker for an unknown radio type " +
@@ -685,10 +686,6 @@
         // TODO - move this into the MobileDataStateTracker
         int usedNetworkType = networkType;
         if(networkType == ConnectivityManager.TYPE_MOBILE) {
-            if (!getMobileDataEnabled()) {
-                if (DBG) log("requested special network with data disabled - rejected");
-                return Phone.APN_TYPE_NOT_AVAILABLE;
-            }
             if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
                 usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS;
             } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
@@ -979,6 +976,9 @@
      * @see ConnectivityManager#getMobileDataEnabled()
      */
     public boolean getMobileDataEnabled() {
+        // TODO: This detail should probably be in DataConnectionTracker's
+        //       which is where we store the value and maybe make this
+        //       asynchronous.
         enforceAccessPermission();
         boolean retVal = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.MOBILE_DATA, 1) == 1;
@@ -998,42 +998,14 @@
     }
 
     private void handleSetMobileData(boolean enabled) {
-        if (getMobileDataEnabled() == enabled) return;
-
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.MOBILE_DATA, enabled ? 1 : 0);
-
-        if (enabled) {
-            if (mNetTrackers[ConnectivityManager.TYPE_MOBILE] != null) {
-                if (DBG) {
-                    log("starting up " + mNetTrackers[ConnectivityManager.TYPE_MOBILE]);
-                }
-                mNetTrackers[ConnectivityManager.TYPE_MOBILE].reconnect();
+        if (mNetTrackers[ConnectivityManager.TYPE_MOBILE] != null) {
+            if (DBG) {
+                Slog.d(TAG, mNetTrackers[ConnectivityManager.TYPE_MOBILE].toString() + enabled);
             }
-        } else {
-            for (NetworkStateTracker nt : mNetTrackers) {
-                if (nt == null) continue;
-                int netType = nt.getNetworkInfo().getType();
-                if (mNetAttributes[netType].mRadio == ConnectivityManager.TYPE_MOBILE) {
-                    if (DBG) log("tearing down " + nt);
-                    nt.teardown();
-                }
-            }
+            mNetTrackers[ConnectivityManager.TYPE_MOBILE].setDataEnable(enabled);
         }
     }
 
-    private int getNumConnectedNetworks() {
-        int numConnectedNets = 0;
-
-        for (NetworkStateTracker nt : mNetTrackers) {
-            if (nt != null && nt.getNetworkInfo().isConnected() &&
-                    !nt.isTeardownRequested()) {
-                ++numConnectedNets;
-            }
-        }
-        return numConnectedNets;
-    }
-
     private void enforceAccessPermission() {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE,
@@ -1153,16 +1125,9 @@
 
             int newType = -1;
             int newPriority = -1;
-            boolean noMobileData = !getMobileDataEnabled();
             for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
                 if (checkType == prevNetType) continue;
                 if (mNetAttributes[checkType] == null) continue;
-                if (mNetAttributes[checkType].mRadio == ConnectivityManager.TYPE_MOBILE &&
-                        noMobileData) {
-                    loge("not failing over to mobile type " + checkType +
-                            " because Mobile Data Disabled");
-                    continue;
-                }
                 if (mNetAttributes[checkType].isDefault()) {
                     /* TODO - if we have multiple nets we could use
                      * we may want to put more thought into which we choose
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 069e1b8..737342f 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -30,6 +30,7 @@
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
+import android.os.Messenger;
 import android.os.ServiceManager;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
@@ -81,6 +82,10 @@
         DORMANT
     }
 
+    public static String ACTION_DATA_CONNECTION_TRACKER_MESSENGER =
+        "com.android.internal.telephony";
+    public static String EXTRA_MESSENGER = "EXTRA_MESSENGER";
+
     /***** Event Codes *****/
     protected static final int EVENT_DATA_SETUP_COMPLETE = 1;
     protected static final int EVENT_RADIO_AVAILABLE = 3;
@@ -113,6 +118,8 @@
     protected static final int EVENT_SET_INTERNAL_DATA_ENABLE = 37;
     protected static final int EVENT_RESET_DONE = 38;
 
+    public static final int CMD_SET_DATA_ENABLE = 39;
+
     /***** Constants *****/
 
     protected static final int APN_INVALID_ID = -1;
@@ -123,13 +130,18 @@
     protected static final int APN_HIPRI_ID = 4;
     protected static final int APN_NUM_TYPES = 5;
 
-    protected static final int DISABLED = 0;
-    protected static final int ENABLED = 1;
+    public static final int DISABLED = 0;
+    public static final int ENABLED = 1;
 
     // responds to the setInternalDataEnabled call - used internally to turn off data
     // for example during emergency calls
     protected boolean mInternalDataEnabled = true;
 
+    // responds to public (user) API to enable/disable data use
+    // independent of mInternalDataEnabled and requests for APN access
+    // persisted
+    protected boolean mDataEnabled = true;
+
     protected boolean[] dataEnabled = new boolean[APN_NUM_TYPES];
 
     protected int enabledCount = 0;
@@ -289,6 +301,9 @@
         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
         filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
 
+        mDataEnabled = Settings.Secure.getInt(mPhone.getContext().getContentResolver(),
+                Settings.Secure.MOBILE_DATA, 1) == 1;
+
         // TODO: Why is this registering the phone as the receiver of the intent
         //       and not its own handler?
         mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
@@ -296,16 +311,8 @@
         // This preference tells us 1) initial condition for "dataEnabled",
         // and 2) whether the RIL will setup the baseband to auto-PS attach.
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
-        boolean dataEnabledSetting = true;
-        try {
-            dataEnabledSetting = IConnectivityManager.Stub.asInterface(ServiceManager.
-                    getService(Context.CONNECTIVITY_SERVICE)).getMobileDataEnabled();
-        } catch (Exception e) {
-            // nothing to do - use the old behavior and leave data on
-        }
         dataEnabled[APN_DEFAULT_ID] =
-                !sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false) &&
-                dataEnabledSetting;
+                !sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false);
         if (dataEnabled[APN_DEFAULT_ID]) {
             enabledCount++;
         }
@@ -316,6 +323,12 @@
         mPhone.getContext().unregisterReceiver(this.mIntentReceiver);
     }
 
+    protected void broadcastMessenger() {
+        Intent intent = new Intent(ACTION_DATA_CONNECTION_TRACKER_MESSENGER);
+        intent.putExtra(EXTRA_MESSENGER, new Messenger(this));
+        mPhone.getContext().sendBroadcast(intent);
+    }
+
     public Activity getActivity() {
         return mActivity;
     }
@@ -490,14 +503,20 @@
                 onCleanUpConnection(tearDown, (String) msg.obj);
                 break;
 
-            case EVENT_SET_INTERNAL_DATA_ENABLE:
+            case EVENT_SET_INTERNAL_DATA_ENABLE: {
                 boolean enabled = (msg.arg1 == ENABLED) ? true : false;
                 onSetInternalDataEnabled(enabled);
                 break;
-
+            }
             case EVENT_RESET_DONE:
                 onResetDone((AsyncResult) msg.obj);
                 break;
+            case CMD_SET_DATA_ENABLE: {
+                log("CMD_SET_DATA_ENABLE msg=" + msg);
+                boolean enabled = (msg.arg1 == ENABLED) ? true : false;
+                onSetDataEnabled(enabled);
+                break;
+            }
 
             default:
                 Log.e("DATA", "Unidentified event = " + msg.what);
@@ -512,7 +531,7 @@
      *         {@code true} otherwise.
      */
     public synchronized boolean getAnyDataEnabled() {
-        return (mInternalDataEnabled && (enabledCount != 0));
+        return (mInternalDataEnabled && mDataEnabled && (enabledCount != 0));
     }
 
     protected abstract void startNetStatPoll();
@@ -828,11 +847,6 @@
      * Prevent mobile data connections from being established, or once again
      * allow mobile data connections. If the state toggles, then either tear
      * down or set up data, as appropriate to match the new state.
-     * <p>
-     * This operation only affects the default APN, and if the same APN is
-     * currently being used for MMS traffic, the teardown will not happen even
-     * when {@code enable} is {@code false}.
-     * </p>
      *
      * @param enable indicates whether to enable ({@code true}) or disable (
      *            {@code false}) data
@@ -849,15 +863,41 @@
     }
 
     protected void onSetInternalDataEnabled(boolean enable) {
+        boolean prevEnabled = getAnyDataEnabled();
         if (mInternalDataEnabled != enable) {
             synchronized (this) {
                 mInternalDataEnabled = enable;
             }
-            if (enable) {
-                mRetryMgr.resetRetryCount();
-                onTrySetupData(Phone.REASON_DATA_ENABLED);
-            } else {
-                onCleanUpConnection(true, Phone.REASON_DATA_DISABLED);
+            if (prevEnabled != getAnyDataEnabled()) {
+                if (!prevEnabled) {
+                    mRetryMgr.resetRetryCount();
+                    onTrySetupData(Phone.REASON_DATA_ENABLED);
+                } else {
+                    onCleanUpConnection(true, Phone.REASON_DATA_DISABLED);
+                }
+            }
+        }
+    }
+
+    public synchronized boolean getDataEnabled() {
+        return mDataEnabled;
+    }
+
+    protected void onSetDataEnabled(boolean enable) {
+        boolean prevEnabled = getAnyDataEnabled();
+        if (mDataEnabled != enable) {
+            synchronized (this) {
+                mDataEnabled = enable;
+            }
+            Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
+                    Settings.Secure.MOBILE_DATA, enable ? 1 : 0);
+            if (prevEnabled != getAnyDataEnabled()) {
+                if (!prevEnabled) {
+                    mRetryMgr.resetRetryCount();
+                    onTrySetupData(Phone.REASON_DATA_ENABLED);
+                } else {
+                    onCleanUpConnection(true, Phone.REASON_DATA_DISABLED);
+                }
             }
         }
     }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index b005cd3..60df7df 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -113,6 +113,7 @@
         mDataConnectionTracker = this;
 
         createAllDataConnectionList();
+        broadcastMessenger();
     }
 
     @Override
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 4713c24..cd0d9e3 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -160,6 +160,7 @@
 
         /** Create the default connection */
         createDataConnection(Phone.APN_TYPE_DEFAULT);
+        broadcastMessenger();
     }
 
     @Override
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index 58a4cba..461f01d 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -386,7 +386,9 @@
         Connection dial(String originalNumber) throws SipException {
             String calleeSipUri = originalNumber;
             if (!calleeSipUri.contains("@")) {
-                calleeSipUri += "@" + getSipDomain(mProfile);
+                calleeSipUri = mProfile.getUriString().replaceFirst(
+                        mProfile.getUserName() + "@",
+                        calleeSipUri + "@");
             }
             try {
                 SipProfile callee =
diff --git a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
new file mode 100644
index 0000000..7d41d1c
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+package android.animation;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+
+/**
+ * Delegate implementing the native methods of android.animation.PropertyValuesHolder
+ *
+ * Through the layoutlib_create tool, the original native methods of PropertyValuesHolder have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
+ * around to map int to instance of the delegate.
+ *
+ * The main goal of this class' methods are to provide a native way to access setters and getters
+ * on some object. In this case we want to default to using Java reflection instead so the native
+ * methods do nothing.
+ *
+ */
+/*package*/ class PropertyValuesHolder_Delegate {
+
+    /*package*/ static int nGetIntMethod(Class<?> targetClass, String methodName) {
+        // return 0 to force PropertyValuesHolder to use Java reflection.
+        return 0;
+    }
+
+    /*package*/ static int nGetFloatMethod(Class<?> targetClass, String methodName) {
+        // return 0 to force PropertyValuesHolder to use Java reflection.
+        return 0;
+    }
+
+    /*package*/ static void nCallIntMethod(Object target, int methodID, int arg) {
+        // do nothing
+    }
+
+    /*package*/ static void nCallFloatMethod(Object target, int methodID, float arg) {
+        // do nothing
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
index d58cde8..0130970 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
@@ -458,16 +458,10 @@
                 mCanvas.setDensity(mParams.getDensity());
             }
 
-            long preDrawTime = System.currentTimeMillis();
-
             mViewRoot.draw(mCanvas);
 
-            long drawTime = System.currentTimeMillis();
-
             mViewInfo = visit(((ViewGroup)mViewRoot).getChildAt(0), mContext);
 
-            System.out.println(String.format("rendering (ms): %03d", drawTime - preDrawTime));
-
             // success!
             return SceneStatus.SUCCESS.createResult();
         } catch (Throwable e) {
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 4440685..1d40d33 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -105,6 +105,7 @@
      * The list of classes on which to delegate all native methods.
      */
     private final static String[] DELEGATE_CLASS_NATIVES = new String[] {
+        "android.animation.PropertyValuesHolder",
         "android.graphics.Bitmap",
         "android.graphics.Canvas",
         "android.graphics.DashPathEffect",
diff --git a/voip/java/android/net/sip/SipProfile.java b/voip/java/android/net/sip/SipProfile.java
index 6977e30..4029ed0 100644
--- a/voip/java/android/net/sip/SipProfile.java
+++ b/voip/java/android/net/sip/SipProfile.java
@@ -20,6 +20,7 @@
 import android.os.Parcelable;
 import android.text.TextUtils;
 
+import java.io.ObjectStreamException;
 import java.io.Serializable;
 import java.text.ParseException;
 import javax.sip.InvalidArgumentException;
@@ -40,12 +41,15 @@
 public class SipProfile implements Parcelable, Serializable, Cloneable {
     private static final long serialVersionUID = 1L;
     private static final int DEFAULT_PORT = 5060;
+    private static final String TCP = "TCP";
+    private static final String UDP = "UDP";
     private Address mAddress;
     private String mProxyAddress;
     private String mPassword;
     private String mDomain;
-    private String mProtocol = ListeningPoint.UDP;
+    private String mProtocol = UDP;
     private String mProfileName;
+    private int mPort = DEFAULT_PORT;
     private boolean mSendKeepAlive = false;
     private boolean mAutoRegistration = true;
     private transient int mCallingUid = 0;
@@ -95,6 +99,7 @@
             mUri.setUserPassword(profile.getPassword());
             mDisplayName = profile.getDisplayName();
             mProxyAddress = profile.getProxyAddress();
+            mProfile.mPort = profile.getPort();
         }
 
         /**
@@ -171,12 +176,11 @@
          * @throws IllegalArgumentException if the port number is out of range
          */
         public Builder setPort(int port) throws IllegalArgumentException {
-            try {
-                mUri.setPort(port);
-                return this;
-            } catch (InvalidArgumentException e) {
-                throw new IllegalArgumentException(e);
+            if ((port > 65535) || (port < 1000)) {
+                throw new IllegalArgumentException("incorrect port arugment");
             }
+            mProfile.mPort = port;
+            return this;
         }
 
         /**
@@ -193,7 +197,7 @@
                 throw new NullPointerException("protocol cannot be null");
             }
             protocol = protocol.toUpperCase();
-            if (!protocol.equals("UDP") && !protocol.equals("TCP")) {
+            if (!protocol.equals(UDP) && !protocol.equals(TCP)) {
                 throw new IllegalArgumentException(
                         "unsupported protocol: " + protocol);
             }
@@ -258,13 +262,22 @@
             mProfile.mPassword = mUri.getUserPassword();
             mUri.setUserPassword(null);
             try {
-                mProfile.mAddress = mAddressFactory.createAddress(
-                        mDisplayName, mUri);
                 if (!TextUtils.isEmpty(mProxyAddress)) {
                     SipURI uri = (SipURI)
                             mAddressFactory.createURI(fix(mProxyAddress));
                     mProfile.mProxyAddress = uri.getHost();
+                } else {
+                    if (!mProfile.mProtocol.equals(UDP)) {
+                        mUri.setTransportParam(mProfile.mProtocol);
+                    }
+                    if (mProfile.mPort != DEFAULT_PORT) {
+                        mUri.setPort(mProfile.mPort);
+                    }
                 }
+                mProfile.mAddress = mAddressFactory.createAddress(
+                        mDisplayName, mUri);
+            } catch (InvalidArgumentException e) {
+                throw new RuntimeException(e);
             } catch (ParseException e) {
                 // must not occur
                 throw new RuntimeException(e);
@@ -286,6 +299,7 @@
         mSendKeepAlive = (in.readInt() == 0) ? false : true;
         mAutoRegistration = (in.readInt() == 0) ? false : true;
         mCallingUid = in.readInt();
+        mPort = in.readInt();
     }
 
     @Override
@@ -299,6 +313,7 @@
         out.writeInt(mSendKeepAlive ? 1 : 0);
         out.writeInt(mAutoRegistration ? 1 : 0);
         out.writeInt(mCallingUid);
+        out.writeInt(mPort);
     }
 
     @Override
@@ -322,7 +337,13 @@
      * @return the SIP URI string of this profile
      */
     public String getUriString() {
-        return mAddress.getURI().toString();
+        // We need to return the sip uri domain instead of
+        // the SIP URI with transport, port information if
+        // the outbound proxy address exists.
+        if (!TextUtils.isEmpty(mProxyAddress)) {
+            return "sip:" + getUserName() + "@" + mDomain;
+        }
+        return getUri().toString();
     }
 
     /**
@@ -377,8 +398,7 @@
      * @return the port number of the SIP server
      */
     public int getPort() {
-        int port = getUri().getPort();
-        return (port == -1) ? DEFAULT_PORT : port;
+        return mPort;
     }
 
     /**
@@ -441,4 +461,10 @@
     public int getCallingUid() {
         return mCallingUid;
     }
+
+    private Object readResolve() throws ObjectStreamException {
+        // For compatibility.
+        if (mPort == 0) mPort = DEFAULT_PORT;
+        return this;
+    }
 }
diff --git a/voip/java/com/android/server/sip/SipHelper.java b/voip/java/com/android/server/sip/SipHelper.java
index 13e6f14..518543a 100644
--- a/voip/java/com/android/server/sip/SipHelper.java
+++ b/voip/java/com/android/server/sip/SipHelper.java
@@ -215,8 +215,9 @@
             String tag) throws ParseException, SipException {
         FromHeader fromHeader = createFromHeader(userProfile, tag);
         ToHeader toHeader = createToHeader(userProfile);
-        SipURI requestURI = mAddressFactory.createSipURI("sip:"
-                + userProfile.getSipDomain());
+        SipURI requestURI = mAddressFactory.createSipURI(
+                userProfile.getUriString().replaceFirst(
+                userProfile.getUserName() + "@", ""));
         List<ViaHeader> viaHeaders = createViaHeaders();
         CallIdHeader callIdHeader = createCallIdHeader();
         CSeqHeader cSeqHeader = createCSeqHeader(requestType);
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index d0231be..2aff7ec 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -170,6 +170,13 @@
     }
 
     /**
+     * @param enabled
+     */
+    public void setDataEnable(boolean enabled) {
+        android.util.Log.d(TAG, "setDataEnabled: IGNORING enabled=" + enabled);
+    }
+
+    /**
      * Check if private DNS route is set for the network
      */
     public boolean isPrivateDnsRouteSet() {