Merge "Some fixes to the new loader management."
diff --git a/api/current.xml b/api/current.xml
index a80a702..f915fad 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -3265,6 +3265,17 @@
  visibility="public"
 >
 </field>
+<field name="customTokens"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843593"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="cycles"
  type="int"
  transient="false"
@@ -18308,6 +18319,28 @@
  visibility="public"
 >
 </field>
+<field name="KEY_CALLER_PID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;callerPid&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="KEY_CALLER_UID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;callerUid&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="KEY_ERROR_CODE"
  type="java.lang.String"
  transient="false"
@@ -18555,6 +18588,28 @@
 </parameter>
 <parameter name="prefId" type="int">
 </parameter>
+<parameter name="customTokens" type="boolean">
+</parameter>
+</constructor>
+<constructor name="AuthenticatorDescription"
+ type="android.accounts.AuthenticatorDescription"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="type" type="java.lang.String">
+</parameter>
+<parameter name="packageName" type="java.lang.String">
+</parameter>
+<parameter name="labelId" type="int">
+</parameter>
+<parameter name="iconId" type="int">
+</parameter>
+<parameter name="smallIconId" type="int">
+</parameter>
+<parameter name="prefId" type="int">
+</parameter>
 </constructor>
 <method name="describeContents"
  return="int"
@@ -18615,6 +18670,16 @@
  visibility="public"
 >
 </field>
+<field name="customTokens"
+ type="boolean"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="iconId"
  type="int"
  transient="false"
@@ -223231,7 +223296,7 @@
  abstract="false"
  static="false"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <constructor name="CacheManager"
@@ -223322,7 +223387,7 @@
  abstract="false"
  static="true"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <constructor name="CacheManager.CacheResult"
diff --git a/core/java/android/accounts/AccountAuthenticatorCache.java b/core/java/android/accounts/AccountAuthenticatorCache.java
index 524d3f4..7214c50 100644
--- a/core/java/android/accounts/AccountAuthenticatorCache.java
+++ b/core/java/android/accounts/AccountAuthenticatorCache.java
@@ -38,7 +38,7 @@
  * @hide
  */
 /* package private */ class AccountAuthenticatorCache
-        extends RegisteredServicesCache<AuthenticatorDescription> 
+        extends RegisteredServicesCache<AuthenticatorDescription>
         implements IAccountAuthenticatorCache {
     private static final String TAG = "Account";
     private static final MySerializer sSerializer = new MySerializer();
@@ -64,11 +64,13 @@
                     com.android.internal.R.styleable.AccountAuthenticator_smallIcon, 0);
             final int prefId = sa.getResourceId(
                     com.android.internal.R.styleable.AccountAuthenticator_accountPreferences, 0);
+            final boolean customTokens = sa.getBoolean(
+                    com.android.internal.R.styleable.AccountAuthenticator_customTokens, false);
             if (TextUtils.isEmpty(accountType)) {
                 return null;
             }
-            return new AuthenticatorDescription(accountType, packageName, labelId, iconId, 
-                    smallIconId, prefId);
+            return new AuthenticatorDescription(accountType, packageName, labelId, iconId,
+                    smallIconId, prefId, customTokens);
         } finally {
             sa.recycle();
         }
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index fd3a0d0..6388dc5 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -188,6 +188,12 @@
     public static final String KEY_ERROR_CODE = "errorCode";
     public static final String KEY_ERROR_MESSAGE = "errorMessage";
     public static final String KEY_USERDATA = "userdata";
+    /**
+     * Authenticators using 'customTokens' option will also get the UID of the
+     * caller
+     */
+    public static final String KEY_CALLER_UID = "callerUid";
+    public static final String KEY_CALLER_PID = "callerPid";
 
     public static final String ACTION_AUTHENTICATOR_INTENT =
             "android.accounts.AccountAuthenticator";
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index a815b3a..72da2ce 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -82,8 +82,6 @@
         implements RegisteredServicesCacheListener<AuthenticatorDescription> {
     private static final String GOOGLE_ACCOUNT_TYPE = "com.google";
 
-    private static final String NO_BROADCAST_FLAG = "nobroadcast";
-
     private static final String TAG = "AccountManagerService";
 
     private static final int TIMEOUT_DELAY_MS = 1000 * 60;
@@ -375,14 +373,6 @@
         if (account == null) {
             return false;
         }
-        final boolean noBroadcast = account.type.equals(GOOGLE_ACCOUNT_TYPE)
-                && extras != null && extras.getBoolean(NO_BROADCAST_FLAG, false);
-        // Remove the 'nobroadcast' flag since we don't want it to persist in the db. It is instead
-        // used as a control signal to indicate whether or not this insertion should result in
-        // an accounts changed broadcast being sent.
-        if (extras != null) {
-            extras.remove(NO_BROADCAST_FLAG);
-        }
         db.beginTransaction();
         try {
             long numMatches = DatabaseUtils.longForQuery(db,
@@ -419,9 +409,7 @@
         } finally {
             db.endTransaction();
         }
-        if (!noBroadcast) {
-            sendAccountsChangedBroadcast();
-        }
+        sendAccountsChangedBroadcast();
         return true;
     }
 
@@ -776,10 +764,6 @@
         if (account == null) throw new IllegalArgumentException("account is null");
         checkAuthenticateAccountsPermission(account);
         long identityToken = clearCallingIdentity();
-        if (account.type.equals(GOOGLE_ACCOUNT_TYPE) && key.equals("broadcast")) {
-            sendAccountsChangedBroadcast();
-            return;
-        }
         try {
             writeUserdataIntoDatabase(account, key, value);
         } finally {
@@ -893,13 +877,29 @@
         if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
         checkBinderPermission(Manifest.permission.USE_CREDENTIALS);
         final int callerUid = Binder.getCallingUid();
-        final boolean permissionGranted = permissionIsGranted(account, authTokenType, callerUid);
+        final int callerPid = Binder.getCallingPid();
+
+        AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo =
+            mAuthenticatorCache.getServiceInfo(
+                    AuthenticatorDescription.newKey(account.type));
+        final boolean customTokens =
+            authenticatorInfo != null && authenticatorInfo.type.customTokens;
+
+        // skip the check if customTokens
+        final boolean permissionGranted = customTokens ||
+            permissionIsGranted(account, authTokenType, callerUid);
+
+        if (customTokens) {
+            // let authenticator know the identity of the caller
+            loginOptions.putInt(AccountManager.KEY_CALLER_UID, callerUid);
+            loginOptions.putInt(AccountManager.KEY_CALLER_PID, callerPid);
+        }
 
         long identityToken = clearCallingIdentity();
         try {
             // if the caller has permission, do the peek. otherwise go the more expensive
             // route of starting a Session
-            if (permissionGranted) {
+            if (!customTokens && permissionGranted) {
                 String authToken = readAuthTokenFromCache(account, authTokenType);
                 if (authToken != null) {
                     Bundle result = new Bundle();
@@ -953,8 +953,10 @@
                                         "the type and name should not be empty");
                                 return;
                             }
-                            saveAuthTokenToDatabase(new Account(name, type),
-                                    authTokenType, authToken);
+                            if (!customTokens) {
+                                saveAuthTokenToDatabase(new Account(name, type),
+                                        authTokenType, authToken);
+                            }
                         }
 
                         Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
diff --git a/core/java/android/accounts/AuthenticatorDescription.java b/core/java/android/accounts/AuthenticatorDescription.java
index c6515672..5d9abb0 100644
--- a/core/java/android/accounts/AuthenticatorDescription.java
+++ b/core/java/android/accounts/AuthenticatorDescription.java
@@ -44,9 +44,12 @@
     /** The package name that can be used to lookup the resources from above. */
     final public String packageName;
 
+    /** Authenticator handles its own token caching and permission screen */
+    final public boolean customTokens;
+
     /** A constructor for a full AuthenticatorDescription */
     public AuthenticatorDescription(String type, String packageName, int labelId, int iconId,
-            int smallIconId, int prefId) {
+            int smallIconId, int prefId, boolean customTokens) {
         if (type == null) throw new IllegalArgumentException("type cannot be null");
         if (packageName == null) throw new IllegalArgumentException("packageName cannot be null");
         this.type = type;
@@ -55,6 +58,12 @@
         this.iconId = iconId;
         this.smallIconId = smallIconId;
         this.accountPreferencesId = prefId;
+        this.customTokens = customTokens;
+    }
+
+    public AuthenticatorDescription(String type, String packageName, int labelId, int iconId,
+            int smallIconId, int prefId) {
+        this(type, packageName, labelId, iconId, smallIconId, prefId, false);
     }
 
     /**
@@ -74,6 +83,7 @@
         this.iconId = 0;
         this.smallIconId = 0;
         this.accountPreferencesId = 0;
+        this.customTokens = false;
     }
 
     private AuthenticatorDescription(Parcel source) {
@@ -83,6 +93,7 @@
         this.iconId = source.readInt();
         this.smallIconId = source.readInt();
         this.accountPreferencesId = source.readInt();
+        this.customTokens = source.readByte() == 1;
     }
 
     /** @inheritDoc */
@@ -115,6 +126,7 @@
         dest.writeInt(iconId);
         dest.writeInt(smallIconId);
         dest.writeInt(accountPreferencesId);
+        dest.writeByte((byte) (customTokens ? 1 : 0));
     }
 
     /** Used to create the object from a parcel. */
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index 5dc29a9..d9cafb6 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -24,7 +24,6 @@
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Message;
-import android.util.Log;
 import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
 import android.view.KeyEvent;
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index efe527f..448b3ef 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -71,10 +71,7 @@
             int year,
             int monthOfYear,
             int dayOfMonth) {
-        this(context, context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
-                        ? com.android.internal.R.style.Theme_Holo_Dialog_Alert
-                        : com.android.internal.R.style.Theme_Dialog_Alert,
-                callBack, year, monthOfYear, dayOfMonth);
+        this(context, 0, callBack, year, monthOfYear, dayOfMonth);
     }
 
     /**
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 26af4eb..f9920c7 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
-import android.os.Build;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -72,11 +71,7 @@
     public TimePickerDialog(Context context,
             OnTimeSetListener callBack,
             int hourOfDay, int minute, boolean is24HourView) {
-        this(context,
-                context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
-                        ? com.android.internal.R.style.Theme_Holo_Dialog_Alert
-                        : com.android.internal.R.style.Theme_Dialog_Alert,
-                callBack, hourOfDay, minute, is24HourView);
+        this(context, 0, callBack, hourOfDay, minute, is24HourView);
     }
 
     /**
diff --git a/core/java/android/content/SyncActivityTooManyDeletes.java b/core/java/android/content/SyncActivityTooManyDeletes.java
new file mode 100644
index 0000000..350f35e
--- /dev/null
+++ b/core/java/android/content/SyncActivityTooManyDeletes.java
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+package android.content;
+
+import com.android.internal.R;
+import android.accounts.Account;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+/**
+ * Presents multiple options for handling the case where a sync was aborted because there
+ * were too many pending deletes. One option is to force the delete, another is to rollback
+ * the deletes, the third is to do nothing.
+ * @hide
+ */
+public class SyncActivityTooManyDeletes extends Activity
+        implements AdapterView.OnItemClickListener {
+
+    private long mNumDeletes;
+    private Account mAccount;
+    private String mAuthority;
+    private String mProvider;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Bundle extras = getIntent().getExtras();
+        if (extras == null) {
+            finish();
+            return;
+        }
+
+        mNumDeletes = extras.getLong("numDeletes");
+        mAccount = (Account) extras.getParcelable("account");
+        mAuthority = extras.getString("authority");
+        mProvider = extras.getString("provider");
+
+        // the order of these must match up with the constants for position used in onItemClick
+        CharSequence[] options = new CharSequence[]{
+                getResources().getText(R.string.sync_really_delete),
+                getResources().getText(R.string.sync_undo_deletes),
+                getResources().getText(R.string.sync_do_nothing)
+        };
+
+        ListAdapter adapter = new ArrayAdapter<CharSequence>(this,
+                android.R.layout.simple_list_item_1,
+                android.R.id.text1,
+                options);
+
+        ListView listView = new ListView(this);
+        listView.setAdapter(adapter);
+        listView.setItemsCanFocus(true);
+        listView.setOnItemClickListener(this);
+
+        TextView textView = new TextView(this);
+        CharSequence tooManyDeletesDescFormat =
+                getResources().getText(R.string.sync_too_many_deletes_desc);
+        textView.setText(String.format(tooManyDeletesDescFormat.toString(),
+                mNumDeletes, mProvider, mAccount.name));
+
+        final LinearLayout ll = new LinearLayout(this);
+        ll.setOrientation(LinearLayout.VERTICAL);
+        final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 0);
+        ll.addView(textView, lp);
+        ll.addView(listView, lp);
+
+        // TODO: consider displaying the icon of the account type
+//        AuthenticatorDescription[] descs = AccountManager.get(this).getAuthenticatorTypes();
+//        for (AuthenticatorDescription desc : descs) {
+//            if (desc.type.equals(mAccount.type)) {
+//                try {
+//                    final Context authContext = createPackageContext(desc.packageName, 0);
+//                    ImageView imageView = new ImageView(this);
+//                    imageView.setImageDrawable(authContext.getResources().getDrawable(desc.iconId));
+//                    ll.addView(imageView, lp);
+//                } catch (PackageManager.NameNotFoundException e) {
+//                }
+//                break;
+//            }
+//        }
+
+        setContentView(ll);
+    }
+
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        // the constants for position correspond to the items options array in onCreate()
+        if (position == 0) startSyncReallyDelete();
+        else if (position == 1) startSyncUndoDeletes();
+        finish();
+    }
+
+    private void startSyncReallyDelete() {
+        Bundle extras = new Bundle();
+        extras.putBoolean(ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS, true);
+        extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+        extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+        extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
+        ContentResolver.requestSync(mAccount, mAuthority, extras);
+    }
+
+    private void startSyncUndoDeletes() {
+        Bundle extras = new Bundle();
+        extras.putBoolean(ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS, true);
+        extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+        extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+        extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
+        ContentResolver.requestSync(mAccount, mAuthority, extras);
+    }
+}
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 599429b..8b292c9 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -2157,9 +2157,7 @@
             }
             CharSequence authorityName = providerInfo.loadLabel(mContext.getPackageManager());
 
-            Intent clickIntent = new Intent();
-            clickIntent.setClassName("com.android.providers.subscribedfeeds",
-                    "com.android.settings.SyncActivityTooManyDeletes");
+            Intent clickIntent = new Intent(mContext, SyncActivityTooManyDeletes.class);
             clickIntent.putExtra("account", account);
             clickIntent.putExtra("authority", authority);
             clickIntent.putExtra("provider", authorityName.toString());
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d27e99d..75aebc9 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8206,8 +8206,9 @@
     /**
      * Manually render this view (and all of its children) to the given Canvas.
      * The view must have already done a full layout before this function is
-     * called.  When implementing a view, do not override this method; instead,
-     * you should implement {@link #onDraw}.
+     * called.  When implementing a view, implement {@link #onDraw} instead of
+     * overriding this method. If you do need to override this method, call
+     * the superclass version.
      *
      * @param canvas The Canvas to which the View is rendered.
      */
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 6309cac..0deb0a0 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -5184,6 +5184,8 @@
     public void onRemoteAdapterConnected() {
         if (mRemoteAdapter != mAdapter) {
             setAdapter(mRemoteAdapter);
+        } else if (mRemoteAdapter != null) {
+            mRemoteAdapter.superNotifyDataSetChanged();
         }
     }
 
@@ -5191,10 +5193,11 @@
      * Called back when the adapter disconnects from the RemoteViewsService.
      */
     public void onRemoteAdapterDisconnected() {
-        if (mRemoteAdapter == mAdapter) {
-            mRemoteAdapter = null;
-            setAdapter(null);
-        }
+        // If the remote adapter disconnects, we keep it around
+        // since the currently displayed items are still cached.
+        // Further, we want the service to eventually reconnect
+        // when necessary, as triggered by this view requesting
+        // items from the Adapter.
     }
 
     /**
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 162b030..ec8e93c 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -964,6 +964,8 @@
     public void onRemoteAdapterConnected() {
         if (mRemoteViewsAdapter != mAdapter) {
             setAdapter(mRemoteViewsAdapter);
+        } else if (mRemoteViewsAdapter != null) {
+            mRemoteViewsAdapter.superNotifyDataSetChanged();
         }
     }
 
@@ -971,10 +973,11 @@
      * Called back when the adapter disconnects from the RemoteViewsService.
      */
     public void onRemoteAdapterDisconnected() {
-        if (mRemoteViewsAdapter != mAdapter) {
-            mRemoteViewsAdapter = null;
-            setAdapter(mRemoteViewsAdapter);
-        }
+        // If the remote adapter disconnects, we keep it around
+        // since the currently displayed items are still cached.
+        // Further, we want the service to eventually reconnect
+        // when necessary, as triggered by this view requesting
+        // items from the Adapter.
     }
 
     public void advance() {
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 3703846..6894c99 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -103,7 +103,7 @@
 
     Drawable mDivider;
     int mDividerHeight;
-    
+
     Drawable mOverScrollHeader;
     Drawable mOverScrollFooter;
 
@@ -1535,7 +1535,6 @@
             // reset the focus restoration
             View focusLayoutRestoreDirectChild = null;
 
-
             // Don't put header or footer views into the Recycler. Those are
             // already cached in mHeaderViews;
             if (dataChanged) {
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 7b35b51..8c22f97 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -534,7 +534,7 @@
         });
 
         // create the fling and adjust scrollers
-        mFlingScroller = new Scroller(getContext());
+        mFlingScroller = new Scroller(getContext(), null, true);
         mAdjustScroller = new Scroller(getContext(), new OvershootInterpolator());
 
         updateInputTextView();
@@ -798,6 +798,7 @@
      */
     public void setFormatter(Formatter formatter) {
         mFormatter = formatter;
+        resetSelectorIndices();
     }
 
     /**
@@ -979,10 +980,7 @@
         // children
         // after we have completed drawing ourselves.
 
-        // Draw the selector wheel if needed
-        if (mDrawSelectorWheel) {
-            super.draw(canvas);
-        }
+        super.draw(canvas);
 
         // Draw our children if we are not showing the selector wheel of fading
         // it out
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 52d9c08..a7bff62 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -148,11 +148,6 @@
             adapter.mMainQueue.removeMessages(0);
             adapter.mWorkerQueue.removeMessages(0);
 
-            // Clear the cache (the meta data will be re-requested on service re-connection)
-            synchronized (adapter.mCache) {
-                adapter.mCache.reset();
-            }
-
             final RemoteAdapterConnectionCallback callback = adapter.mCallback.get();
             if (callback != null) {
                 callback.onRemoteAdapterDisconnected();
@@ -335,8 +330,8 @@
 
                     // Compose the loading view text
                     TextView loadingTextView = (TextView) mLayoutInflater.inflate(
-				com.android.internal.R.layout.remote_views_adapter_default_loading_view,
-				layout, false);
+                            com.android.internal.R.layout.remote_views_adapter_default_loading_view,
+                            layout, false);
                     loadingTextView.setHeight(mFirstViewHeight);
                     loadingTextView.setTag(new Integer(0));
 
@@ -880,7 +875,7 @@
         // a chance to update itself and return new meta data associated with the new data.
     }
 
-    private void superNotifyDataSetChanged() {
+    void superNotifyDataSetChanged() {
         super.notifyDataSetChanged();
     }
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 9a2cc89..4fdadab 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -864,6 +864,7 @@
             mInputType = EditorInfo.TYPE_NULL;
             mInput = null;
             bufferType = BufferType.SPANNABLE;
+            // Required to request focus while in touch mode.
             setFocusableInTouchMode(true);
             // So that selection can be changed using arrow keys and touch is handled.
             setMovementMethod(ArrowKeyMovementMethod.getInstance());
@@ -2748,7 +2749,10 @@
                  */
                 mText = text;
 
-                if (mLinksClickable) {
+                // Do not change the movement method for text that support text selection as it
+                // would prevent an arbitrary cursor displacement.
+                final boolean hasTextSelection = this instanceof EditText || mTextIsSelectable;
+                if (mLinksClickable && !hasTextSelection) {
                     setMovementMethod(LinkMovementMethod.getInstance());
                 }
             }
@@ -3876,7 +3880,7 @@
         // - ExtractEditText does not call onFocus when it is displayed. Fixing this issue would
         //   allow to test for hasSelection in onFocusChanged, which would trigger a
         //   startTextSelectionMode here. TODO
-        if (this instanceof ExtractEditText && hasSelection() && hasSelectionController()) {
+        if (this instanceof ExtractEditText && hasSelection() && canSelectText()) {
             startSelectionActionMode();
         }
 
@@ -4073,7 +4077,7 @@
      *
      * Use {@link #setTextIsSelectable(boolean)} or the
      * {@link android.R.styleable#TextView_textIsSelectable} XML attribute to make this TextView
-     * selectable (the text is not selectable by default). 
+     * selectable (text is not selectable by default).
      *
      * Note that the content of an EditText is always selectable.
      *
@@ -4088,8 +4092,8 @@
     /**
      * Sets whether or not (default) the content of this view is selectable by the user.
      * 
-     * Note that this methods affect the {@link #setFocusableInTouchMode(boolean)},
-     * {@link #setFocusable(boolean)}, {@link #setClickable(boolean)} and
+     * Note that this methods affect the {@link #setFocusable(boolean)},
+     * {@link #setFocusableInTouchMode(boolean)} {@link #setClickable(boolean)} and
      * {@link #setLongClickable(boolean)} states and you may want to restore these if they were
      * customized.
      *
@@ -7519,10 +7523,21 @@
         return super.onKeyShortcut(keyCode, event);
     }
 
+    /**
+     * Unlike {@link #textCanBeSelected()}, this method is based on the <i>current</i> state of the
+     * TextView. {@link #textCanBeSelected()} has to be true (this is one of the conditions to have
+     * a selection controller (see {@link #prepareCursorControllers()}), but this is not sufficient.
+     */
     private boolean canSelectText() {
         return hasSelectionController() && mText.length() != 0;
     }
 
+    /**
+     * Test based on the <i>intrinsic</i> charateristics of the TextView.
+     * The text must be spannable and the movement method must allow for arbitary selection.
+     * 
+     * See also {@link #canSelectText()}.
+     */
     private boolean textCanBeSelected() {
         // prepareCursorController() relies on this method.
         // If you change this condition, make sure prepareCursorController is called anywhere
@@ -7753,11 +7768,12 @@
         boolean added = false;
         mContextMenuTriggeredByKey = mDPadCenterIsDown || mEnterKeyIsDown;
         // Problem with context menu on long press: the menu appears while the key in down and when
-        // the key is released, the view does not receive the key_up event. This ensures that the
-        // state is reset whenever the context menu action is displayed.
-        // mContextMenuTriggeredByKey saved that state so that it is available in
-        // onTextContextMenuItem. We cannot simply clear these flags in onTextContextMenuItem since
+        // the key is released, the view does not receive the key_up event.
+        // We need two layers of flags: mDPadCenterIsDown and mEnterKeyIsDown are set in key down/up
+        // events. We cannot simply clear these flags in onTextContextMenuItem since
         // it may not be called (if the user/ discards the context menu with the back key).
+        // We clear these flags here and mContextMenuTriggeredByKey saves that state so that it is
+        // available in onTextContextMenuItem.
         mDPadCenterIsDown = mEnterKeyIsDown = false;
 
         MenuHandler handler = new MenuHandler();
@@ -7769,12 +7785,10 @@
             int min = Math.min(selStart, selEnd);
             int max = Math.max(selStart, selEnd);
 
-            URLSpan[] urls = ((Spanned) mText).getSpans(min, max,
-                                                        URLSpan.class);
-            if (urls.length == 1) {
-                menu.add(0, ID_COPY_URL, 0,
-                         com.android.internal.R.string.copyUrl).
-                            setOnMenuItemClickListener(handler);
+            URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class);
+            if (urls.length > 0) {
+                menu.add(0, ID_COPY_URL, 0, com.android.internal.R.string.copyUrl).
+                        setOnMenuItemClickListener(handler);
 
                 added = true;
             }
@@ -7786,7 +7800,7 @@
         // populates the menu AFTER this call.
         if (menu.size() > 0) {
             menu.add(0, ID_SELECTION_MODE, 0, com.android.internal.R.string.selectTextMode).
-            setOnMenuItemClickListener(handler);
+                    setOnMenuItemClickListener(handler);
             added = true;
         }
 
@@ -8063,6 +8077,11 @@
             return false;
         }
 
+        if (!canSelectText() || !requestFocus()) {
+            Log.w(LOG_TAG, "TextView does not support text selection. Action mode cancelled.");
+            return false;
+        }
+
         selectCurrentWord();
         final InputMethodManager imm = (InputMethodManager)
                 getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -8139,26 +8158,15 @@
 
         @Override
         public boolean onCreateActionMode(ActionMode mode, Menu menu) {
-            if (!hasSelectionController()) {
-                Log.w(LOG_TAG, "TextView has no selection controller. Action mode cancelled.");
-                return false;
-            }
-
-            if (!requestFocus()) {
-                return false;
-            }
-
             TypedArray styledAttributes = mContext.obtainStyledAttributes(R.styleable.Theme);
 
             mode.setTitle(mContext.getString(com.android.internal.R.string.textSelectionCABTitle));
             mode.setSubtitle(null);
 
-            if (canSelectText()) {
-                menu.add(0, ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
+            menu.add(0, ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
                     setAlphabeticShortcut('a').
                     setShowAsAction(
                             MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-            }
 
             if (canCut()) {
                 menu.add(0, ID_CUT, 0, com.android.internal.R.string.cut).
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 3a58867..633bdd3 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -505,12 +505,13 @@
         }
         mContainerView.setVisibility(View.VISIBLE);
         mContainerView.setAlpha(0);
-        mContainerView.setTranslationY(-mContainerView.getHeight());
         AnimatorSet anim = new AnimatorSet();
-        AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "translationY", 0))
-            .with(ObjectAnimator.ofFloat(mContainerView, "alpha", 1));
+        AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 1));
         if (mContentView != null) {
-            b.with(ObjectAnimator.ofFloat(mContentView, "translationY", -mContainerView.getHeight(), 0));
+            b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
+                    -mContainerView.getHeight(), 0));
+            mContainerView.setTranslationY(-mContainerView.getHeight());
+            b.with(ObjectAnimator.ofFloat(mContainerView, "translationY", 0));
         }
         anim.addListener(mShowListener);
         mCurrentAnim = anim;
@@ -527,11 +528,12 @@
         }
         mContainerView.setAlpha(1);
         AnimatorSet anim = new AnimatorSet();
-        AnimatorSet.Builder b = anim.play(
-                ObjectAnimator.ofFloat(mContainerView, "translationY", -mContainerView.getHeight()))
-            .with(ObjectAnimator.ofFloat(mContainerView, "alpha", 0));
+        AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 0));
         if (mContentView != null) {
-            b.with(ObjectAnimator.ofFloat(mContentView, "translationY", 0, -mContainerView.getHeight()));
+            b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
+                    0, -mContainerView.getHeight()));
+            b.with(ObjectAnimator.ofFloat(mContainerView, "translationY",
+                    -mContainerView.getHeight()));
         }
         anim.addListener(mHideListener);
         mCurrentAnim = anim;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 92b50c7..981661a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1335,6 +1335,11 @@
                 android:exported="true">
         </activity>
 
+        <activity android:name="android.content.SyncActivityTooManyDeletes"
+               android:theme="@android:style/Theme.Holo.Dialog"
+               android:label="@string/sync_too_many_deletes">
+        </activity>
+
         <activity android:name="com.android.server.ShutdownActivity"
             android:permission="android.permission.SHUTDOWN"
             android:excludeFromRecents="true">
diff --git a/core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo_dark.9.png b/core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo_dark.9.png
rename to core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo_light.9.png b/core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo_light.9.png
deleted file mode 100644
index 2edae8f..0000000
--- a/core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_dark.png
index 6fbd7d2..f43f9ad 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_light.png
index 3a4cdec..2ada3ef 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_dark.png
index b1c3991..5ed7040 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_light.png b/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_light.png
index 6fbce8c..d4a01cf 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_focused_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_down_focused_holo_dark.png
index 3bb4c29..ada6251 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_focused_holo_light.png b/core/res/res/drawable-hdpi/timepicker_down_focused_holo_light.png
index 8f02162..1247c7a 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_dark.png
index 8f57d2c..3d13454 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_light.png b/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_light.png
index df6f76b..4898244 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_normal_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_down_normal_holo_dark.png
index a47bf31..bb1074c 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_normal_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_normal_holo_light.png b/core/res/res/drawable-hdpi/timepicker_down_normal_holo_light.png
index 04046aa..e6e5a0f 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_normal_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_dark.png
index b6021e0..b54e603 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_light.png b/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_light.png
index 0f38d6b..70ee54c 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_dark.png
index 14a4e31..a55c96a 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_light.png
index 21a2ac1..4e31c72 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_dark.png
index 1a1da57..8158596 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_light.png b/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_light.png
index a242c80..37e5c0d 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_focused_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_up_focused_holo_dark.png
index 50045e4..7ec94e6 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_focused_holo_light.png b/core/res/res/drawable-hdpi/timepicker_up_focused_holo_light.png
index 659b3c7..780fff1 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_dark.png
index 9112530..73c8dd9 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_light.png b/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_light.png
index 21aa7f7..3b96480 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_normal_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_up_normal_holo_dark.png
index d145975..21f0871 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_normal_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_normal_holo_light.png b/core/res/res/drawable-hdpi/timepicker_up_normal_holo_light.png
index 167bab7..49e3c15 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_normal_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_dark.png
index 2844c3f..a15a5f5 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_light.png b/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_light.png
index 9d83038..7441361 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo_dark.9.png b/core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo_dark.9.png
rename to core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo_light.9.png b/core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo_light.9.png
deleted file mode 100644
index a8cfd77..0000000
--- a/core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_dark.png
index d86534c..113b369 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_light.png
index 6ae5d4b..e3c416e 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_dark.png
index fd578b6..e123db9 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_light.png b/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_light.png
index a0caaa9..f93d082 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_focused_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_down_focused_holo_dark.png
index f6f4ed2..d8bd34f 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_focused_holo_light.png b/core/res/res/drawable-mdpi/timepicker_down_focused_holo_light.png
index 2591adb..0747f82 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_dark.png
index efee099..1c7abf8 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_light.png b/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_light.png
index f7b09de..ec9d1f2 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_normal_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_down_normal_holo_dark.png
index 76f13a6..d6259e2 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_normal_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_normal_holo_light.png b/core/res/res/drawable-mdpi/timepicker_down_normal_holo_light.png
index cb8e764..aac5f31 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_normal_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_dark.png
index 7c0d0bc..fd8076f 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_light.png b/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_light.png
index 9d7ff6b..c06ff40 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_dark.png
index cfdfd174..d69615d 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_light.png
index 43bdf1d..eb7a283 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_dark.png
index 2ffe46b..1ee5510 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_light.png b/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_light.png
index 51bb2d0..2269577 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_focused_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_up_focused_holo_dark.png
index dece157..9954130 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_focused_holo_light.png b/core/res/res/drawable-mdpi/timepicker_up_focused_holo_light.png
index 384cb32..8553d1c 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_dark.png
index 84ec4f7..b4ed2c5 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_light.png b/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_light.png
index 318befc..2496fb8 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_normal_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_up_normal_holo_dark.png
index d97a832..3bcdd71 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_normal_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_normal_holo_light.png b/core/res/res/drawable-mdpi/timepicker_up_normal_holo_light.png
index 19d75e5..1113de7 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_normal_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_dark.png
index 1189e5c..7303a19 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_light.png b/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_light.png
index 9f283ab..7abdbfc 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index e7783da..a5f87d3 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -34,7 +34,7 @@
             android:orientation="vertical"
             android:layout_width="0px"
             android:layout_height="match_parent"
-            android:layout_marginRight="0dp"
+            android:layout_marginRight="@dimen/preference_screen_side_margin_negative"
             android:layout_marginLeft="@dimen/preference_screen_side_margin"
             android:layout_marginTop="32dp"
             android:layout_marginBottom="32dp"
@@ -61,7 +61,7 @@
                 android:layout_width="0px"
                 android:layout_height="match_parent"
                 android:layout_weight="20"
-                android:layout_marginLeft="-4dp"
+                android:layout_marginLeft="@dimen/preference_screen_side_margin"
                 android:layout_marginRight="@dimen/preference_screen_side_margin"
                 android:layout_marginTop="16dp"
                 android:layout_marginBottom="16dp"
diff --git a/core/res/res/values-land/dimens.xml b/core/res/res/values-land/dimens.xml
index b1f12b5..fbfc3bf 100644
--- a/core/res/res/values-land/dimens.xml
+++ b/core/res/res/values-land/dimens.xml
@@ -22,5 +22,6 @@
     <dimen name="password_keyboard_key_height">47dip</dimen>
     <dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
     <dimen name="preference_screen_side_margin">96dp</dimen>
+    <dimen name="preference_screen_side_margin_negative">-100dp</dimen>
     <dimen name="preference_widget_width">72dp</dimen>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 98c9270..873f539 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -48,6 +48,7 @@
              theme does not set this value, meaning it is based on whether the
              window is floating. -->
         <attr name="backgroundDimEnabled" format="boolean" />
+
         <!-- =========== -->
         <!-- Text styles -->
         <!-- =========== -->
@@ -261,7 +262,7 @@
         <!-- Flag indicating whether this is a translucent window. -->
         <attr name="windowIsTranslucent" format="boolean" />
         <!-- Flag indicating that this window's background should be the
-        	 user's current wallpaper. -->
+           user's current wallpaper. -->
         <attr name="windowShowWallpaper" format="boolean" />
         <!-- This Drawable is overlaid over the foreground of the Window's content area, usually
              to place a shadow below the title.  -->
@@ -4310,7 +4311,7 @@
              If not supplied, then no activity will be launched. -->
         <attr name="configure" format="string" />
         <!-- A preview of what the AppWidget will look like after it's configured.
-       	     If not supplied, the AppWidget's icon will be used. -->
+              If not supplied, the AppWidget's icon will be used. -->
         <attr name="previewImage" format="reference" />
         <!-- The view id of the AppWidget subview which should be auto-advanced.
              by the widget's host. -->
@@ -4421,6 +4422,10 @@
         <attr name="smallIcon" format="reference"/>
         <!-- A preferences.xml file for authenticator-specific settings. -->
         <attr name="accountPreferences" format="reference"/>
+        <!-- Account handles its own token storage and permissions.
+             Default to false
+          -->
+        <attr name="customTokens" format="boolean"/>
     </declare-styleable>
 
     <!-- =============================== -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5d03638..0d2d42f 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -497,6 +497,17 @@
          to handle queries on each database. -->
     <integer name="db_connection_pool_size">1</integer>
 
+    <!-- Max space (in MB) allocated to DownloadManager to store the downloaded
+         files if they are to be stored in DownloadManager's data dir,
+         which typically is /data/data/com.android.providers.downloads/files -->
+    <integer name="config_downloadDataDirSize">100</integer>
+
+    <!-- When the free space available in DownloadManager's data dir falls
+         below the percentage value specified by this param, DownloadManager
+         starts removing files to try to make percentage of available
+         free space above this threshold value. -->
+    <integer name="config_downloadDataDirLowSpaceThreshold">10</integer>
+
     <!-- The URL that should be sent in an x-wap-profile header with an HTTP request,
          as defined in the Open Mobile Alliance User Agent Profile specification
          OMA-TS-UAProf-V2_0-20060206-A Section 8.1.1.1. If the URL contains a '%s'
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 2f0dfc1..53d4e42 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -54,6 +54,8 @@
     <dimen name="password_keyboard_spacebar_vertical_correction">4dip</dimen>
     <!-- Preference activity side margins -->
     <dimen name="preference_screen_side_margin">0dp</dimen>
+    <!-- Preference activity side margins negative-->
+    <dimen name="preference_screen_side_margin_negative">0dp</dimen>
     <!-- Preference widget area width (to the left of the text) -->
     <dimen name="preference_widget_width">56dp</dimen>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 3a5b238..7e06c86 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1407,6 +1407,7 @@
   <public type="attr" name="fastScrollPreviewBackgroundRight" />
   <public type="attr" name="fastScrollTrackDrawable" />
   <public type="attr" name="fastScrollOverlayPosition" />
+  <public type="attr" name="customTokens" />
 
   <public type="anim" name="animator_fade_in" />
   <public type="anim" name="animator_fade_out" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e48321c..92f3593 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -298,12 +298,12 @@
     <string name="shutdown_confirm_question">Would you like to shut down?</string>
 
     <!-- Recent Tasks dialog: title
-     TODO: this should move to SystemUI.apk, but the code for the old 
+     TODO: this should move to SystemUI.apk, but the code for the old
             recent dialog is still in the framework
      -->
     <string name="recent_tasks_title">Recent</string>
     <!-- Recent Tasks dialog: message when there are no recent applications
-     TODO: this should move to SystemUI.apk, but the code for the old 
+     TODO: this should move to SystemUI.apk, but the code for the old
             recent dialog is still in the framework
      -->
     <string name="no_recent_tasks">No recent applications.</string>
@@ -1363,17 +1363,17 @@
     <!-- Title of policy access to limiting the user's password choices -->
     <string name="policylab_limitPassword">Set password rules</string>
     <!-- Description of policy access to limiting the user's password choices -->
-    <string name="policydesc_limitPassword">Control the length and the characters 
+    <string name="policydesc_limitPassword">Control the length and the characters
     allowed in screen-unlock passwords</string>
     <!-- Title of policy access to watch user login attempts -->
     <string name="policylab_watchLogin">Monitor screen-unlock attempts</string>
     <!-- Description of policy access to watch user login attempts -->
-    <string name="policydesc_watchLogin" product="tablet">Monitor the number of incorrect passwords 
-    entered when unlocking the screen, and lock the tablet or erase all the tablet\'s 
+    <string name="policydesc_watchLogin" product="tablet">Monitor the number of incorrect passwords
+    entered when unlocking the screen, and lock the tablet or erase all the tablet\'s
     data if too many incorrect passwords are entered</string>
     <!-- Description of policy access to watch user login attempts -->
-    <string name="policydesc_watchLogin" product="default">Monitor the number of incorrect passwords 
-    entered when unlocking the screen, and lock the phone or erase all the phone\'s 
+    <string name="policydesc_watchLogin" product="default">Monitor the number of incorrect passwords
+    entered when unlocking the screen, and lock the phone or erase all the phone\'s
     data if too many incorrect passwords are entered</string>
     <!-- Title of policy access to reset user's password -->
     <string name="policylab_resetPassword">Change the screen-unlock password</string>
@@ -1386,10 +1386,10 @@
     <!-- Title of policy access to wipe the user's data -->
     <string name="policylab_wipeData">Erase all data</string>
     <!-- Description of policy access to wipe the user's data -->
-    <string name="policydesc_wipeData" product="tablet">Erase the tablet\'s data without warning, 
+    <string name="policydesc_wipeData" product="tablet">Erase the tablet\'s data without warning,
     by performing a factory data reset</string>
     <!-- Description of policy access to wipe the user's data -->
-    <string name="policydesc_wipeData" product="default">Erase the phone\'s data without warning, 
+    <string name="policydesc_wipeData" product="default">Erase the phone\'s data without warning,
     by performing a factory data reset</string>
     <string name="policylab_setGlobalProxy">Set the device global proxy</string>
     <!-- Description of policy access to wipe the user's data -->
@@ -1602,7 +1602,7 @@
     <string name="relationTypeSister">Sister</string>
     <!-- Spouse relationship type [CHAR LIMIT=20] -->
     <string name="relationTypeSpouse">Spouse</string>
-    
+
     <!-- Custom SIP address type -->
     <string name="sipAddressTypeCustom">Custom</string>
     <!-- Home SIP address type -->
@@ -2640,4 +2640,15 @@
     <!-- Network positioning verification No. Button to push to deny sharing of location
          information. -->
     <string name="gpsVerifNo">No</string>
+
+    <!-- Error message when the sync tried to delete too many things -->
+    <string name="sync_too_many_deletes">Delete limit exceeded</string>
+    <!-- Dialog message for when there are too many deletes that would take place and we want user confirmation -->
+    <string name="sync_too_many_deletes_desc">There are <xliff:g id="number_of_deleted_items">%1$d</xliff:g> deleted items for <xliff:g id="type_of_sync">%2$s</xliff:g>, account <xliff:g id="account_name">%3$s</xliff:g>. What would you like to do?</string>
+    <!-- Dialog action for when there are too many deletes that would take place and we want user confirmation, and the user wants to delete the items -->
+    <string name="sync_really_delete">Delete the items.</string>
+    <!-- Dialog action for when there are too many deletes that would take place and we want user confirmation, and the user wants to undo the deletions -->
+    <string name="sync_undo_deletes">Undo the deletes.</string>
+    <!-- Dialog action for when there are too many deletes that would take place and we want user confirmation, and the user wants to do nothing for now -->
+    <string name="sync_do_nothing">Do nothing for now.</string>
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 3e75261..920a59e 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -488,7 +488,7 @@
         <item name="android:otherMonthDateColor">#66FFFFFF</item>
         <item name="android:weekNumberColor">#33FFFFFF</item>
         <item name="android:gridLinesColor">#19FFFFFF</item>
-        <item name="selectedDayLine">@android:drawable/day_picker_week_view_dayline_holo_dark</item>
+        <item name="selectedDayLine">@android:drawable/day_picker_week_view_dayline_holo</item>
     </style>
 
     <!-- @hide -->
@@ -1450,7 +1450,7 @@
         <item name="android:otherMonthDateColor">#66FFFFFF</item>
         <item name="android:weekNumberColor">#33FFFFFF</item>
         <item name="android:gridLinesColor">#19FFFFFF</item>
-        <item name="selectedDayLine">@android:drawable/day_picker_week_view_dayline_holo_dark</item>
+        <item name="selectedDayLine">@android:drawable/day_picker_week_view_dayline_holo</item>
     </style>
 
     <style name="Widget.Holo.ImageButton" parent="Widget.ImageButton">
@@ -1819,12 +1819,12 @@
 
     <!-- @hide -->
     <style name="Widget.Holo.Light.DayPickerWeekView" parent="Widget.DayPickerWeekView">
-        <item name="android:selectionBackgroundColor">#7F080030</item>
+        <item name="android:selectionBackgroundColor">#330066ff</item> 
         <item name="android:focusedMonthDateColor">#FF000000</item>
         <item name="android:otherMonthDateColor">#7F08002B</item>
         <item name="android:weekNumberColor">#7F080021</item>
         <item name="android:gridLinesColor">#7F08002A</item>
-        <item name="selectedDayLine">@android:drawable/day_picker_week_view_dayline_holo_light</item>
+        <item name="selectedDayLine">@android:drawable/day_picker_week_view_dayline_holo</item>
     </style>
 
     <!-- @hide -->
diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java
index ff3e22b..ed16451 100644
--- a/graphics/java/android/renderscript/FieldPacker.java
+++ b/graphics/java/android/renderscript/FieldPacker.java
@@ -248,24 +248,45 @@
         addU32(v.w);
     }
 
+    // to be removed on cleanup
     public void addObj(Matrix4f v) {
         for (int i=0; i < v.mMat.length; i++) {
             addF32(v.mMat[i]);
         }
     }
 
+    // to be removed on cleanup
     public void addObj(Matrix3f v) {
         for (int i=0; i < v.mMat.length; i++) {
             addF32(v.mMat[i]);
         }
     }
 
+    // to be removed on cleanup
     public void addObj(Matrix2f v) {
         for (int i=0; i < v.mMat.length; i++) {
             addF32(v.mMat[i]);
         }
     }
 
+    public void addMatrix(Matrix4f v) {
+        for (int i=0; i < v.mMat.length; i++) {
+            addF32(v.mMat[i]);
+        }
+    }
+
+    public void addMatrix(Matrix3f v) {
+        for (int i=0; i < v.mMat.length; i++) {
+            addF32(v.mMat[i]);
+        }
+    }
+
+    public void addMatrix(Matrix2f v) {
+        for (int i=0; i < v.mMat.length; i++) {
+            addF32(v.mMat[i]);
+        }
+    }
+
     public void addBoolean(boolean v) {
         addI8((byte)(v ? 1 : 0));
     }
diff --git a/graphics/java/android/renderscript/FileA3D.java b/graphics/java/android/renderscript/FileA3D.java
index af85d8e..c3e5faf 100644
--- a/graphics/java/android/renderscript/FileA3D.java
+++ b/graphics/java/android/renderscript/FileA3D.java
@@ -16,11 +16,12 @@
 
 package android.renderscript;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 
-import android.content.res.Resources;
 import android.content.res.AssetManager;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.util.Log;
@@ -32,28 +33,33 @@
  **/
 public class FileA3D extends BaseObj {
 
+    // This will go away in the clean up pass,
+    // trying to avoid multiproject submits
     public enum ClassID {
 
         UNKNOWN,
-        MESH,
-        TYPE,
-        ELEMENT,
-        ALLOCATION,
-        PROGRAM_VERTEX,
-        PROGRAM_RASTER,
-        PROGRAM_FRAGMENT,
-        PROGRAM_STORE,
-        SAMPLER,
-        ANIMATION,
-        ADAPTER_1D,
-        ADAPTER_2D,
-        SCRIPT_C;
+        MESH;
 
         public static ClassID toClassID(int intID) {
             return ClassID.values()[intID];
         }
     }
 
+    public enum EntryType {
+
+        UNKNOWN (0),
+        MESH (1);
+
+        int mID;
+        EntryType(int id) {
+            mID = id;
+        }
+
+        static EntryType toEntryType(int intID) {
+            return EntryType.values()[intID];
+        }
+    }
+
     // Read only class with index entries
     public static class IndexEntry {
         RenderScript mRS;
@@ -61,6 +67,7 @@
         int mID;
         String mName;
         ClassID mClassID;
+        EntryType mEntryType;
         BaseObj mLoadedObj;
 
         public String getName() {
@@ -71,18 +78,27 @@
             return mClassID;
         }
 
+        public EntryType getEntryType() {
+            return mEntryType;
+        }
+
         public BaseObj getObject() {
             mRS.validate();
             BaseObj obj = internalCreate(mRS, this);
             return obj;
         }
 
+        public Mesh getMesh() {
+            return (Mesh)getObject();
+        }
+
         static synchronized BaseObj internalCreate(RenderScript rs, IndexEntry entry) {
             if(entry.mLoadedObj != null) {
                 return entry.mLoadedObj;
             }
 
-            if(entry.mClassID == ClassID.UNKNOWN) {
+            // to be purged on cleanup
+            if(entry.mEntryType == EntryType.UNKNOWN) {
                 return null;
             }
 
@@ -91,51 +107,23 @@
                 return null;
             }
 
-            switch (entry.mClassID) {
+            switch (entry.mEntryType) {
             case MESH:
                 entry.mLoadedObj = new Mesh(objectID, rs);
                 break;
-            case TYPE:
-                entry.mLoadedObj = new Type(objectID, rs);
-                break;
-            case ELEMENT:
-                entry.mLoadedObj = null;
-                break;
-            case ALLOCATION:
-                entry.mLoadedObj = null;
-                break;
-            case PROGRAM_VERTEX:
-                entry.mLoadedObj = new ProgramVertex(objectID, rs);
-                break;
-            case PROGRAM_RASTER:
-                break;
-            case PROGRAM_FRAGMENT:
-                break;
-            case PROGRAM_STORE:
-                break;
-            case SAMPLER:
-                break;
-            case ANIMATION:
-                break;
-            case ADAPTER_1D:
-                break;
-            case ADAPTER_2D:
-                break;
-            case SCRIPT_C:
-                break;
             }
 
             entry.mLoadedObj.updateFromNative();
-
             return entry.mLoadedObj;
         }
 
-        IndexEntry(RenderScript rs, int index, int id, String name, ClassID classID) {
+        IndexEntry(RenderScript rs, int index, int id, String name, EntryType type) {
             mRS = rs;
             mIndex = index;
             mID = id;
             mName = name;
-            mClassID = classID;
+            mEntryType = type;
+            mClassID = mEntryType == EntryType.MESH ? ClassID.MESH : ClassID.UNKNOWN;
             mLoadedObj = null;
         }
     }
@@ -161,11 +149,11 @@
         mRS.nFileA3DGetIndexEntries(getID(), numFileEntries, ids, names);
 
         for(int i = 0; i < numFileEntries; i ++) {
-            mFileEntries[i] = new IndexEntry(mRS, i, getID(), names[i], ClassID.toClassID(ids[i]));
+            mFileEntries[i] = new IndexEntry(mRS, i, getID(), names[i], EntryType.toEntryType(ids[i]));
         }
     }
 
-    public int getNumIndexEntries() {
+    public int getIndexEntryCount() {
         if(mFileEntries == null) {
             return 0;
         }
@@ -173,12 +161,29 @@
     }
 
     public IndexEntry getIndexEntry(int index) {
-        if(getNumIndexEntries() == 0 || index < 0 || index >= mFileEntries.length) {
+        if(getIndexEntryCount() == 0 || index < 0 || index >= mFileEntries.length) {
             return null;
         }
         return mFileEntries[index];
     }
 
+    // API cleanup stand-ins
+    // TODO: implement ermaining loading mechanisms
+    static public FileA3D createFromAsset(RenderScript rs, AssetManager mgr, String path)
+        throws IllegalArgumentException {
+        return null;
+    }
+
+    static public FileA3D createFromFile(RenderScript rs, String path)
+        throws IllegalArgumentException {
+        return null;
+    }
+
+    static public FileA3D createFromFile(RenderScript rs, File path)
+        throws IllegalArgumentException {
+        return createFromFile(rs, path.getAbsolutePath());
+    }
+
     static public FileA3D createFromResource(RenderScript rs, Resources res, int id)
         throws IllegalArgumentException {
 
diff --git a/graphics/java/android/renderscript/Font.java b/graphics/java/android/renderscript/Font.java
index de25014..0f7c24d 100644
--- a/graphics/java/android/renderscript/Font.java
+++ b/graphics/java/android/renderscript/Font.java
@@ -16,13 +16,16 @@
 
 package android.renderscript;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Map;
 import java.util.HashMap;
+import java.util.Map;
 
-import android.content.res.Resources;
+import android.os.Environment;
+
 import android.content.res.AssetManager;
+import android.content.res.Resources;
 import android.util.Log;
 import android.util.TypedValue;
 
@@ -126,13 +129,13 @@
     /**
      * Takes a specific file name as an argument
      */
-    static public Font create(RenderScript rs, Resources res, String fileName, int size)
+    static public Font createFromFile(RenderScript rs, Resources res, String path, float pointSize)
         throws IllegalArgumentException {
 
         rs.validate();
         try {
             int dpi = res.getDisplayMetrics().densityDpi;
-            int fontId = rs.nFontCreateFromFile(fileName, size, dpi);
+            int fontId = rs.nFontCreateFromFile(path, pointSize, dpi);
 
             if(fontId == 0) {
                 throw new IllegalStateException("Failed loading a font");
@@ -148,6 +151,21 @@
         return null;
     }
 
+    static public Font createFromFile(RenderScript rs, Resources res, File path, float pointSize)
+        throws IllegalArgumentException {
+        return createFromFile(rs, res, path.getAbsolutePath(), pointSize);
+    }
+
+    static public Font createFromAsset(RenderScript rs, Resources res, AssetManager mgr, String path, float pointSize)
+        throws IllegalArgumentException {
+        return null;
+    }
+
+    static public Font createFromResource(RenderScript rs, Resources res, int id, float pointSize)
+        throws IllegalArgumentException {
+        return null;
+    }
+
     /**
      * Accepts one of the following family names as an argument
      * and will attemp to produce the best match with a system font
@@ -157,9 +175,12 @@
      * "monospace" "courier" "courier new" "monaco"
      * Returns default font if no match could be found
      */
-    static public Font createFromFamily(RenderScript rs, Resources res, String familyName, Style fontStyle, int size)
+    static public Font create(RenderScript rs, Resources res, String familyName, Style fontStyle, float pointSize)
     throws IllegalArgumentException {
         String fileName = getFontFileName(familyName, fontStyle);
-        return create(rs, res, fileName, size);
+        String fontPath = Environment.getRootDirectory().getAbsolutePath();
+        fontPath += "/fonts/" + fileName;
+        return createFromFile(rs, res, fontPath, pointSize);
     }
+
 }
diff --git a/graphics/java/android/renderscript/Matrix2f.java b/graphics/java/android/renderscript/Matrix2f.java
index 99d23db..4654c48 100644
--- a/graphics/java/android/renderscript/Matrix2f.java
+++ b/graphics/java/android/renderscript/Matrix2f.java
@@ -31,6 +31,15 @@
         loadIdentity();
     }
 
+    public Matrix2f(float[] dataArray) {
+        mMat = new float[2];
+        System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
+    }
+
+    public float[] getArray() {
+        return mMat;
+    }
+
     public float get(int i, int j) {
         return mMat[i*2 + j];
     }
diff --git a/graphics/java/android/renderscript/Matrix3f.java b/graphics/java/android/renderscript/Matrix3f.java
index 961bc5d..15e5ce6 100644
--- a/graphics/java/android/renderscript/Matrix3f.java
+++ b/graphics/java/android/renderscript/Matrix3f.java
@@ -31,6 +31,15 @@
         loadIdentity();
     }
 
+    public Matrix3f(float[] dataArray) {
+        mMat = new float[9];
+        System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
+    }
+
+    public float[] getArray() {
+        return mMat;
+    }
+
     public float get(int i, int j) {
         return mMat[i*3 + j];
     }
diff --git a/graphics/java/android/renderscript/Matrix4f.java b/graphics/java/android/renderscript/Matrix4f.java
index 5ffc21a..ea97509 100644
--- a/graphics/java/android/renderscript/Matrix4f.java
+++ b/graphics/java/android/renderscript/Matrix4f.java
@@ -31,6 +31,15 @@
         loadIdentity();
     }
 
+    public Matrix4f(float[] dataArray) {
+        mMat = new float[16];
+        System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
+    }
+
+    public float[] getArray() {
+        return mMat;
+    }
+
     public float get(int i, int j) {
         return mMat[i*4 + j];
     }
@@ -147,6 +156,10 @@
         mMat[14]= -(f + n) / (f - n);
     }
 
+    public void loadOrthoWindow(int w, int h) {
+        loadOrtho(0,w, h,0, -1,1);
+    }
+
     public void loadFrustum(float l, float r, float b, float t, float n, float f) {
         loadIdentity();
         mMat[0] = 2 * n / (r - l);
@@ -159,6 +172,14 @@
         mMat[15]= 0;
     }
 
+    public void loadPerspective(float fovy, float aspect, float near, float far) {
+        float top = near * (float)Math.tan((float) (fovy * Math.PI / 360.0f));
+        float bottom = -top;
+        float left = bottom * aspect;
+        float right = top * aspect;
+        loadFrustum(left, right, bottom, top, near, far);
+    }
+
     public void multiply(Matrix4f rhs) {
         Matrix4f tmp = new Matrix4f();
         tmp.loadMultiply(this, rhs);
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 5f93f5b..0b7262b 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -305,8 +305,8 @@
         return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index);
     }
 
-    native int  rsnFontCreateFromFile(int con, String fileName, int size, int dpi);
-    synchronized int nFontCreateFromFile(String fileName, int size, int dpi) {
+    native int  rsnFontCreateFromFile(int con, String fileName, float size, int dpi);
+    synchronized int nFontCreateFromFile(String fileName, float size, int dpi) {
         return rsnFontCreateFromFile(mContext, fileName, size, dpi);
     }
 
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index a8343b3..493653a 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -623,7 +623,7 @@
 // -----------------------------------
 
 static int
-nFontCreateFromFile(JNIEnv *_env, jobject _this, RsContext con, jstring fileName, jint fontSize, jint dpi)
+nFontCreateFromFile(JNIEnv *_env, jobject _this, RsContext con, jstring fileName, jfloat fontSize, jint dpi)
 {
     const char* fileNameUTF = _env->GetStringUTFChars(fileName, NULL);
 
@@ -1239,7 +1239,7 @@
 {"rsnFileA3DGetIndexEntries",        "(III[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
 {"rsnFileA3DGetEntryByIndex",        "(III)I",                                (void*)nFileA3DGetEntryByIndex },
 
-{"rsnFontCreateFromFile",            "(ILjava/lang/String;II)I",              (void*)nFontCreateFromFile },
+{"rsnFontCreateFromFile",            "(ILjava/lang/String;FI)I",              (void*)nFontCreateFromFile },
 
 {"rsnElementCreate",                 "(IIIZI)I",                              (void*)nElementCreate },
 {"rsnElementCreate2",                "(I[I[Ljava/lang/String;[I)I",           (void*)nElementCreate2 },
diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h
index 74c9d5d..df5be32 100644
--- a/include/media/mediascanner.h
+++ b/include/media/mediascanner.h
@@ -71,7 +71,8 @@
     bool addStringTag(const char* name, const char* value);
     void endFile();
 
-    virtual bool scanFile(const char* path, long long lastModified, long long fileSize) = 0;
+    virtual bool scanFile(const char* path, long long lastModified,
+            long long fileSize, bool isDirectory) = 0;
     virtual bool handleStringTag(const char* name, const char* value) = 0;
     virtual bool setMimeType(const char* mimeType) = 0;
     virtual bool addNoMediaFolder(const char* path) = 0;
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
index 6cb50b8..7d99686 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
@@ -23,6 +23,7 @@
 import android.content.res.Resources;
 import android.renderscript.*;
 import android.renderscript.Element.Builder;
+import android.renderscript.Font.Style;
 import android.renderscript.ProgramStore.DepthFunc;
 import android.util.Log;
 
@@ -186,22 +187,20 @@
 
         FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
         FileA3D.IndexEntry entry = model.getIndexEntry(0);
-        if (entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+        if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
             Log.e("rs", "could not load model");
         } else {
             mMesh = (Mesh)entry.getObject();
             mScript.set_gTestMesh(mMesh);
         }
 
-        mItalic = Font.create(mRS, mRes, "DroidSerif-Italic.ttf", 8);
+        mItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
         mScript.set_gItalic(mItalic);
 
         initTextAllocation();
 
         initTransformHierarchy();
 
-        Log.v("========SceneGraph========", "transform hierarchy initialized");
-
         mScript.bind_gRootNode(mRootTransform.getField());
 
         mScript.bind_gGroup(mGroup1.mParent.mChildField);
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
index 747463a..5451ca1 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
@@ -148,14 +148,14 @@
 
         FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
         FileA3D.IndexEntry entry = model.getIndexEntry(0);
-        if (entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+        if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
             Log.e("rs", "could not load model");
         } else {
             mMesh = (Mesh)entry.getObject();
             mScript.set_gTestMesh(mMesh);
         }
 
-        mItalic = Font.create(mRS, mRes, "DroidSerif-Italic.ttf", 8);
+        mItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
         mScript.set_gItalic(mItalic);
 
         initTextAllocation();
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java b/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java
index ddb05b3..b3e8026 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java
+++ b/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java
@@ -315,22 +315,15 @@
 
     private void initFonts() {
         // Sans font by family name
-        mFontSans = Font.createFromFamily(mRS, mRes, "sans-serif",
-                                          Font.Style.NORMAL, 8);
-        // Create font by file name
-        mFontSerif = Font.create(mRS, mRes, "DroidSerif-Regular.ttf", 8);
+        mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
+        mFontSerif = Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8);
         // Create fonts by family and style
-        mFontSerifBold = Font.createFromFamily(mRS, mRes, "serif",
-                                               Font.Style.BOLD, 8);
-        mFontSerifItalic = Font.createFromFamily(mRS, mRes, "serif",
-                                                 Font.Style.ITALIC, 8);
-        mFontSerifBoldItalic = Font.createFromFamily(mRS, mRes, "serif",
-                                                     Font.Style.BOLD_ITALIC, 8);
-        mFontMono = Font.createFromFamily(mRS, mRes, "mono",
-                                          Font.Style.NORMAL, 8);
+        mFontSerifBold = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
+        mFontSerifItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
+        mFontSerifBoldItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
+        mFontMono = Font.create(mRS, mRes, "mono", Font.Style.NORMAL, 8);
 
-        mTextAlloc = Allocation.createFromString(mRS, "String from allocation",
-                                                 Allocation.USAGE_SCRIPT);
+        mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
 
         mScript.set_gFontSans(mFontSans);
         mScript.set_gFontSerif(mFontSerif);
@@ -351,7 +344,7 @@
 
         FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus);
         FileA3D.IndexEntry entry = model.getIndexEntry(0);
-        if (entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+        if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
             Log.e("rs", "could not load model");
         } else {
             mTorus = (Mesh)entry.getObject();
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsListRS.java b/libs/rs/java/Samples/src/com/android/samples/RsListRS.java
index 223f552..8e2d51f 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsListRS.java
+++ b/libs/rs/java/Samples/src/com/android/samples/RsListRS.java
@@ -134,7 +134,7 @@
 
         mScript.bind_gList(mListAllocs);
 
-        mItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
+        mItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
         mScript.set_gItalic(mItalic);
 
         mRS.bindRootScript(mScript);
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
index 75e8d99..636a486 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
+++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
@@ -23,6 +23,7 @@
 import android.graphics.BitmapFactory;
 import android.renderscript.*;
 import android.renderscript.Allocation.CubemapLayout;
+import android.renderscript.Font.Style;
 import android.renderscript.Program.TextureType;
 import android.renderscript.ProgramStore.DepthFunc;
 import android.renderscript.Sampler.Value;
@@ -304,14 +305,13 @@
 
     private void initFonts() {
         // Sans font by family name
-        mFontSans = Font.createFromFamily(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
-        // Create font by file name
-        mFontSerif = Font.create(mRS, mRes, "DroidSerif-Regular.ttf", 8);
+        mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
+        mFontSerif = Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8);
         // Create fonts by family and style
-        mFontSerifBold = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD, 8);
-        mFontSerifItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.ITALIC, 8);
-        mFontSerifBoldItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
-        mFontMono = Font.createFromFamily(mRS, mRes, "mono", Font.Style.NORMAL, 8);
+        mFontSerifBold = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
+        mFontSerifItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
+        mFontSerifBoldItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
+        mFontMono = Font.create(mRS, mRes, "mono", Font.Style.NORMAL, 8);
 
         mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
 
@@ -330,7 +330,7 @@
 
         FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus);
         FileA3D.IndexEntry entry = model.getIndexEntry(0);
-        if (entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+        if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
             Log.e("rs", "could not load model");
         } else {
             mTorus = (Mesh)entry.getObject();
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
index 265e1d6..a50321e 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
@@ -94,7 +94,7 @@
 
         mScript.bind_gList(mListAllocs);
 
-        mFont = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD, 8);
+        mFont = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
         mScript.set_gFont(mFont);
 
         mRS.bindRootScript(mScript);
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 5daba08..cf94060 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -420,7 +420,7 @@
 
 FontCreateFromFile {
 	param const char *name
-	param uint32_t fontSize
+	param float fontSize
 	param uint32_t dpi
 	ret RsFont
 	}
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 2fa1f0a..80bca43 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -40,20 +40,15 @@
     mFace = NULL;
 }
 
-bool Font::init(const char *name, uint32_t fontSize, uint32_t dpi) {
+bool Font::init(const char *name, float fontSize, uint32_t dpi) {
     if (mInitialized) {
         LOGE("Reinitialization of fonts not supported");
         return false;
     }
 
-    String8 fontsDir("/fonts/");
-    String8 fullPath(getenv("ANDROID_ROOT"));
-    fullPath += fontsDir;
-    fullPath += name;
-
-    FT_Error error = FT_New_Face(mRSC->mStateFont.getLib(), fullPath.string(), 0, &mFace);
+    FT_Error error = FT_New_Face(mRSC->mStateFont.getLib(), name, 0, &mFace);
     if (error) {
-        LOGE("Unable to initialize font %s", fullPath.string());
+        LOGE("Unable to initialize font %s", name);
         return false;
     }
 
@@ -61,9 +56,9 @@
     mFontSize = fontSize;
     mDpi = dpi;
 
-    error = FT_Set_Char_Size(mFace, fontSize * 64, 0, dpi, 0);
+    error = FT_Set_Char_Size(mFace, (FT_F26Dot6)(fontSize * 64.0f), 0, dpi, 0);
     if (error) {
-        LOGE("Unable to set font size on %s", fullPath.string());
+        LOGE("Unable to set font size on %s", name);
         return false;
     }
 
@@ -278,7 +273,7 @@
     return newGlyph;
 }
 
-Font * Font::create(Context *rsc, const char *name, uint32_t fontSize, uint32_t dpi) {
+Font * Font::create(Context *rsc, const char *name, float fontSize, uint32_t dpi) {
     rsc->mStateFont.checkInit();
     Vector<Font*> &activeFonts = rsc->mStateFont.mActiveFonts;
 
@@ -332,31 +327,20 @@
     // Get the gamma
     float gamma = DEFAULT_TEXT_GAMMA;
     if (property_get(PROPERTY_TEXT_GAMMA, property, NULL) > 0) {
-        LOGD("  Setting text gamma to %s", property);
         gamma = atof(property);
-    } else {
-        LOGD("  Using default text gamma of %.2f", DEFAULT_TEXT_GAMMA);
     }
 
     // Get the black gamma threshold
     int32_t blackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD;
     if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, NULL) > 0) {
-        LOGD("  Setting text black gamma threshold to %s", property);
         blackThreshold = atoi(property);
-    } else {
-        LOGD("  Using default text black gamma threshold of %d",
-                DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD);
     }
     mBlackThreshold = (float)(blackThreshold) / 255.0f;
 
     // Get the white gamma threshold
     int32_t whiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD;
     if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, NULL) > 0) {
-        LOGD("  Setting text white gamma threshold to %s", property);
         whiteThreshold = atoi(property);
-    } else {
-        LOGD("  Using default white black gamma threshold of %d",
-                DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD);
     }
     mWhiteThreshold = (float)(whiteThreshold) / 255.0f;
 
@@ -735,7 +719,11 @@
     Font *currentFont = mRSC->getFont();
     if (!currentFont) {
         if (!mDefault.get()) {
-            mDefault.set(Font::create(mRSC, "DroidSans.ttf", 16, 96));
+            String8 fontsDir("/fonts/DroidSans.ttf");
+            String8 fullPath(getenv("ANDROID_ROOT"));
+            fullPath += fontsDir;
+
+            mDefault.set(Font::create(mRSC, fullPath.string(), 16, 96));
         }
         currentFont = mDefault.get();
     }
@@ -815,7 +803,7 @@
 namespace android {
 namespace renderscript {
 
-RsFont rsi_FontCreateFromFile(Context *rsc, char const *name, uint32_t fontSize, uint32_t dpi) {
+RsFont rsi_FontCreateFromFile(Context *rsc, char const *name, float fontSize, uint32_t dpi) {
     Font *newFont = Font::create(rsc, name, fontSize, dpi);
     if (newFont) {
         newFont->incUserRef();
diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h
index 0f6815d..c24c9f1 100644
--- a/libs/rs/rsFont.h
+++ b/libs/rs/rsFont.h
@@ -73,7 +73,7 @@
         return RS_A3D_CLASS_ID_UNKNOWN;
     }
 
-    static Font * create(Context *rsc, const char *name, uint32_t fontSize, uint32_t dpi);
+    static Font * create(Context *rsc, const char *name, float fontSize, uint32_t dpi);
 
 protected:
 
@@ -112,11 +112,11 @@
     };
 
     String8 mFontName;
-    uint32_t mFontSize;
+    float mFontSize;
     uint32_t mDpi;
 
     Font(Context *rsc);
-    bool init(const char *name, uint32_t fontSize, uint32_t dpi);
+    bool init(const char *name, float fontSize, uint32_t dpi);
 
     FT_Face mFace;
     bool mInitialized;
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 63ec6b2..ae6dd61 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -388,7 +388,14 @@
         String prop = SystemProperties.get("drm.service.enabled");
         return prop != null && prop.equals("true");
     }
-    
+
+    private final String mediaToExternalPath(String path) {
+        if (mMediaStoragePath != null && path.startsWith(mMediaStoragePath)) {
+            path = mExternalStoragePath + path.substring(mMediaStoragePath.length());
+        }
+        return path;
+    }
+
     private class MyMediaScannerClient implements MediaScannerClient {
 
         private String mArtist;
@@ -407,70 +414,74 @@
         private long mFileSize;
         private String mWriter;
 
-        public FileCacheEntry beginFile(String path, String mimeType, long lastModified, long fileSize) {
-
-            // special case certain file names
-            // I use regionMatches() instead of substring() below
-            // to avoid memory allocation
-            int lastSlash = path.lastIndexOf('/');
-            if (lastSlash >= 0 && lastSlash + 2 < path.length()) {
-                // ignore those ._* files created by MacOS
-                if (path.regionMatches(lastSlash + 1, "._", 0, 2)) {
-                    return null;
-                }
-
-                // ignore album art files created by Windows Media Player:
-                // Folder.jpg, AlbumArtSmall.jpg, AlbumArt_{...}_Large.jpg and AlbumArt_{...}_Small.jpg
-                if (path.regionMatches(true, path.length() - 4, ".jpg", 0, 4)) {
-                    if (path.regionMatches(true, lastSlash + 1, "AlbumArt_{", 0, 10) ||
-                            path.regionMatches(true, lastSlash + 1, "AlbumArt.", 0, 9)) {
-                        return null;
-                    }
-                    int length = path.length() - lastSlash - 1;
-                    if ((length == 17 && path.regionMatches(true, lastSlash + 1, "AlbumArtSmall", 0, 13)) ||
-                            (length == 10 && path.regionMatches(true, lastSlash + 1, "Folder", 0, 6))) {
-                        return null;
-                    }
-                }
-            }
-
+        public FileCacheEntry beginFile(String path, String mimeType, long lastModified,
+                long fileSize, boolean isDirectory) {
             mMimeType = mimeType;
             mFileType = 0;
             mFileSize = fileSize;
 
-            // try mimeType first, if it is specified
-            if (mimeType != null) {
-                mFileType = MediaFile.getFileTypeForMimeType(mimeType);
-            }
-
-            // if mimeType was not specified, compute file type based on file extension.
-            if (mFileType == 0) {
-                MediaFile.MediaFileType mediaFileType = MediaFile.getFileType(path);
-                if (mediaFileType != null) {
-                    mFileType = mediaFileType.fileType;
-                    if (mMimeType == null) {
-                        mMimeType = mediaFileType.mimeType;
+            if (!isDirectory) {
+                // special case certain file names
+                // I use regionMatches() instead of substring() below
+                // to avoid memory allocation
+                int lastSlash = path.lastIndexOf('/');
+                if (lastSlash >= 0 && lastSlash + 2 < path.length()) {
+                    // ignore those ._* files created by MacOS
+                    if (path.regionMatches(lastSlash + 1, "._", 0, 2)) {
+                        return null;
                     }
+
+                    // ignore album art files created by Windows Media Player:
+                    // Folder.jpg, AlbumArtSmall.jpg, AlbumArt_{...}_Large.jpg
+                    // and AlbumArt_{...}_Small.jpg
+                    if (path.regionMatches(true, path.length() - 4, ".jpg", 0, 4)) {
+                        if (path.regionMatches(true, lastSlash + 1, "AlbumArt_{", 0, 10) ||
+                                path.regionMatches(true, lastSlash + 1, "AlbumArt.", 0, 9)) {
+                            return null;
+                        }
+                        int length = path.length() - lastSlash - 1;
+                        if ((length == 17 && path.regionMatches(
+                                true, lastSlash + 1, "AlbumArtSmall", 0, 13)) ||
+                                (length == 10
+                                 && path.regionMatches(true, lastSlash + 1, "Folder", 0, 6))) {
+                            return null;
+                        }
+                    }
+                }
+
+                // try mimeType first, if it is specified
+                if (mimeType != null) {
+                    mFileType = MediaFile.getFileTypeForMimeType(mimeType);
+                }
+
+                // if mimeType was not specified, compute file type based on file extension.
+                if (mFileType == 0) {
+                    MediaFile.MediaFileType mediaFileType = MediaFile.getFileType(path);
+                    if (mediaFileType != null) {
+                        mFileType = mediaFileType.fileType;
+                        if (mMimeType == null) {
+                            mMimeType = mediaFileType.mimeType;
+                        }
+                    }
+                }
+
+                if (isDrmEnabled() && MediaFile.isDrmFileType(mFileType)) {
+                    mFileType = getFileTypeFromDrm(path);
                 }
             }
 
-            if (isDrmEnabled() && MediaFile.isDrmFileType(mFileType)) {
-                mFileType = getFileTypeFromDrm(path);
-            }
-
-            String key = path;
-            if (mMediaStoragePath != null && key.startsWith(mMediaStoragePath)) {
-                // MediaProvider uses external variant of path for _data, so we need to match
-                // against that path instead.
-                key = mExternalStoragePath + key.substring(mMediaStoragePath.length());
-            }
+            // MediaProvider uses external variant of path for _data, so we need to match
+            // against that path instead.
+            String key = mediaToExternalPath(path);
             if (mCaseInsensitivePaths) {
                 key = path.toLowerCase();
             }
             FileCacheEntry entry = mFileCache.get(key);
             if (entry == null) {
                 Uri tableUri;
-                if (MediaFile.isVideoFileType(mFileType)) {
+                if (isDirectory) {
+                    tableUri = mFilesUri;
+                } else if (MediaFile.isVideoFileType(mFileType)) {
                     tableUri = mVideoUri;
                 } else if (MediaFile.isImageFileType(mFileType)) {
                     tableUri = mImagesUri;
@@ -479,7 +490,8 @@
                 } else {
                     tableUri = mFilesUri;
                 }
-                entry = new FileCacheEntry(tableUri, 0, path, 0, 0);
+                entry = new FileCacheEntry(tableUri, 0, path, 0,
+                        (isDirectory ? MtpConstants.FORMAT_ASSOCIATION : 0));
                 mFileCache.put(key, entry);
             }
             entry.mSeenInFileSystem = true;
@@ -514,22 +526,19 @@
             return entry;
         }
 
-        public void scanFile(String path, long lastModified, long fileSize) {
+        public void scanFile(String path, long lastModified, long fileSize, boolean isDirectory) {
             // This is the callback funtion from native codes.
             // Log.v(TAG, "scanFile: "+path);
-            doScanFile(path, null, lastModified, fileSize, false);
-        }
-
-        public void scanFile(String path, String mimeType, long lastModified, long fileSize) {
-            doScanFile(path, mimeType, lastModified, fileSize, false);
+            doScanFile(path, null, lastModified, fileSize, isDirectory, false);
         }
 
         public Uri doScanFile(String path, String mimeType, long lastModified,
-                long fileSize, boolean scanAlways) {
+                long fileSize, boolean isDirectory, boolean scanAlways) {
             Uri result = null;
 //            long t1 = System.currentTimeMillis();
             try {
-                FileCacheEntry entry = beginFile(path, mimeType, lastModified, fileSize);
+                FileCacheEntry entry = beginFile(path, mimeType, lastModified,
+                        fileSize, isDirectory);
                 // rescan for metadata if file was modified since last scan
                 if (entry != null && (entry.mLastModifiedChanged || scanAlways)) {
                     String lowpath = path.toLowerCase();
@@ -775,7 +784,11 @@
                     values.put(MediaStore.MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, mMtpObjectHandle);
                 }
                 if (tableUri == mFilesUri) {
-                    values.put(Files.FileColumns.FORMAT, MediaFile.getFormatCode(entry.mPath, mMimeType));
+                    int format = entry.mFormat;
+                    if (format == 0) {
+                        format = MediaFile.getFormatCode(entry.mPath, mMimeType);
+                    }
+                    values.put(Files.FileColumns.FORMAT, format);
                 }
                 // new file, insert it
                 result = mMediaProvider.insert(tableUri, values);
@@ -872,6 +885,8 @@
         }
 
         public void addNoMediaFolder(String path) {
+            path = mediaToExternalPath(path);
+
             ContentValues values = new ContentValues();
             values.put(MediaStore.Images.ImageColumns.DATA, "");
             String [] pathSpec = new String[] {path + '%'};
@@ -930,11 +945,9 @@
         }
 
         if (filePath != null) {
-            if (mMediaStoragePath != null && filePath.startsWith(mMediaStoragePath)) {
-                // MediaProvider uses external variant of path for _data, so we need to query
-                // using that path instead.
-                filePath = mExternalStoragePath + filePath.substring(mMediaStoragePath.length());
-            }
+            // MediaProvider uses external variant of path for _data, so we need to query
+            // using that path instead.
+            filePath = mediaToExternalPath(filePath);
 
             // query for only one file
             where = Files.FileColumns.DATA + "=?";
@@ -1060,8 +1073,7 @@
             boolean fileMissing = false;
 
             if (!entry.mSeenInFileSystem && !MtpConstants.isAbstractObject(entry.mFormat)) {
-                if (entry.mFormat != MtpConstants.FORMAT_ASSOCIATION &&
-                        inScanDirectory(path, directories)) {
+                if (inScanDirectory(path, directories)) {
                     // we didn't see this file in the scan directory.
                     fileMissing = true;
                 } else {
@@ -1180,7 +1192,7 @@
             long lastModifiedSeconds = file.lastModified() / 1000;
 
             // always scan the file, so we can return the content://media Uri for existing files
-            return mClient.doScanFile(path, mimeType, lastModifiedSeconds, file.length(), true);
+            return mClient.doScanFile(path, mimeType, lastModifiedSeconds, file.length(),false, true);
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e);
             return null;
@@ -1204,12 +1216,9 @@
                 // build file cache so we can look up tracks in the playlist
                 prescan(null, true);
 
-                String key = path;
-                if (mMediaStoragePath != null && key.startsWith(mMediaStoragePath)) {
-                    // MediaProvider uses external variant of path for _data, so we need to match
-                    // against that path instead.
-                    key = mExternalStoragePath + key.substring(mMediaStoragePath.length());
-                }
+                // MediaProvider uses external variant of path for _data, so we need to match
+                // against that path instead.
+                String key = mediaToExternalPath(path);
                 if (mCaseInsensitivePaths) {
                     key = path.toLowerCase();
                 }
@@ -1227,7 +1236,8 @@
                 long lastModifiedSeconds = file.lastModified() / 1000;
 
                 // always scan the file, so we can return the content://media Uri for existing files
-                mClient.doScanFile(path, mediaFileType.mimeType, lastModifiedSeconds, file.length(), true);
+                mClient.doScanFile(path, mediaFileType.mimeType, lastModifiedSeconds, file.length(),
+                    (format == MtpConstants.FORMAT_ASSOCIATION), true);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e);
diff --git a/media/java/android/media/MediaScannerClient.java b/media/java/android/media/MediaScannerClient.java
index 258c3b4..ac326ef 100644
--- a/media/java/android/media/MediaScannerClient.java
+++ b/media/java/android/media/MediaScannerClient.java
@@ -21,9 +21,7 @@
  */
 public interface MediaScannerClient
 {    
-    public void scanFile(String path, long lastModified, long fileSize);
-    
-    public void scanFile(String path, String mimeType, long lastModified, long fileSize);
+    public void scanFile(String path, long lastModified, long fileSize, boolean isDirectory);
 
     public void addNoMediaFolder(String path);
 
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index fd0b233..a5176fa 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -62,7 +62,7 @@
         }
         else {
             mScanFileMethodID = env->GetMethodID(mediaScannerClientInterface, "scanFile",
-                                                     "(Ljava/lang/String;JJ)V");
+                                                     "(Ljava/lang/String;JJZ)V");
             mHandleStringTagMethodID = env->GetMethodID(mediaScannerClientInterface, "handleStringTag",
                                                      "(Ljava/lang/String;Ljava/lang/String;)V");
             mSetMimeTypeMethodID = env->GetMethodID(mediaScannerClientInterface, "setMimeType",
@@ -78,12 +78,14 @@
     }
     
     // returns true if it succeeded, false if an exception occured in the Java code
-    virtual bool scanFile(const char* path, long long lastModified, long long fileSize)
+    virtual bool scanFile(const char* path, long long lastModified,
+            long long fileSize, bool isDirectory)
     {
         jstring pathStr;
         if ((pathStr = mEnv->NewStringUTF(path)) == NULL) return false;
 
-        mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified, fileSize);
+        mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified,
+                fileSize, isDirectory);
 
         mEnv->DeleteLocalRef(pathStr);
         return (!mEnv->ExceptionCheck());
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index c31b622..5ec573e 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -84,6 +84,7 @@
     // place to copy file or directory name
     char* fileSpot = path + strlen(path);
     struct dirent* entry;
+    struct stat statbuf;
 
     // ignore directories that contain a  ".nomedia" file
     if (pathRemaining >= 8 /* strlen(".nomedia") */ ) {
@@ -125,7 +126,6 @@
             // If the type is unknown, stat() the file instead.
             // This is sometimes necessary when accessing NFS mounted filesystems, but
             // could be needed in other cases well.
-            struct stat statbuf;
             if (stat(path, &statbuf) == 0) {
                 if (S_ISREG(statbuf.st_mode)) {
                     type = DT_REG;
@@ -142,8 +142,15 @@
                 // for example, the Mac ".Trashes" directory
                 if (name[0] == '.') continue;
 
+                // report the directory to the client
+                if (stat(path, &statbuf) == 0) {
+                    client.scanFile(path, statbuf.st_mtime, 0, true);
+                }
+
+                // and now process its contents
                 strcat(fileSpot, "/");
-                int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client, exceptionCheck, exceptionEnv);
+                int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client,
+                        exceptionCheck, exceptionEnv);
                 if (err) {
                     // pass exceptions up - ignore other errors
                     if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure;
@@ -151,11 +158,8 @@
                     continue;
                 }
             } else {
-                struct stat statbuf;
                 stat(path, &statbuf);
-                if (statbuf.st_size > 0) {
-                    client.scanFile(path, statbuf.st_mtime, statbuf.st_size);
-                }
+                client.scanFile(path, statbuf.st_mtime, statbuf.st_size, false);
                 if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index c9fd9a9..759c17c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -39,7 +39,8 @@
 
 public class NotificationPanel extends LinearLayout implements StatusBarPanel,
         View.OnClickListener {
-    static final String TAG = "NotificationPanel";
+    static final String TAG = "Tablet/NotificationPanel";
+    static final boolean DEBUG = false;
 
     boolean mShowing;
     View mTitleArea;
@@ -248,6 +249,7 @@
         }
 
         void startAnimation(boolean visible) {
+            if (DEBUG) Slog.d(TAG, "startAnimation(visible=" + visible + ")");
             if (mBgAnim != null && mVisible != visible) {
                 mBgAnim.reverse();
                 mPositionAnim.reverse();
@@ -303,18 +305,22 @@
             if (mPanelBottom == 0) {
                 // fully closed, no animation necessary
                 setPanelBottom(0);
-            } else {
-                // a little bit visible, schedule an animation
+            } else if (mVisible) {
+                if (DEBUG) {
+                    Slog.d(TAG, "panelHeight not zero but trying to open; scheduling an anim to open fully");
+                }
                 startAnimation(true);
             }
         }
 
         public void onAnimationCancel(Animator animation) {
-            //Slog.d(TAG, "onAnimationCancel mBgAlpha=" + mBgAlpha);
+            if (DEBUG) Slog.d(TAG, "onAnimationCancel mBgAlpha=" + mBgAlpha);
+            // force this to zero so we close the window
+            mBgAlpha = 0;
         }
 
         public void onAnimationEnd(Animator animation) {
-            //Slog.d(TAG, "onAnimationEnd mBgAlpha=" + mBgAlpha);
+            if (DEBUG) Slog.d(TAG, "onAnimationEnd mBgAlpha=" + mBgAlpha);
             if (mBgAlpha == 0) {
                 setVisibility(View.GONE);
             }
diff --git a/services/audioflinger/A2dpAudioInterface.cpp b/services/audioflinger/A2dpAudioInterface.cpp
index aee01ab..d926cb1 100644
--- a/services/audioflinger/A2dpAudioInterface.cpp
+++ b/services/audioflinger/A2dpAudioInterface.cpp
@@ -260,6 +260,7 @@
     if (pRate) *pRate = lRate;
 
     mDevice = device;
+    mBufferDurationUs = ((bufferSize() * 1000 )/ frameSize() / sampleRate()) * 1000;
     return NO_ERROR;
 }
 
@@ -288,6 +289,7 @@
         if (mStandby) {
             acquire_wake_lock (PARTIAL_WAKE_LOCK, sA2dpWakeLock);
             mStandby = false;
+            mLastWriteTime = systemTime();
         }
 
         status = init();
@@ -308,6 +310,15 @@
             buffer = (char *)buffer + status;
         }
 
+        // if A2DP sink runs abnormally fast, sleep a little so that audioflinger mixer thread
+        // does no spin and starve other threads.
+        // NOTE: It is likely that the A2DP headset is being disconnected
+        nsecs_t now = systemTime();
+        if ((uint32_t)ns2us(now - mLastWriteTime) < (mBufferDurationUs >> 2)) {
+            LOGV("A2DP sink runs too fast");
+            usleep(mBufferDurationUs - (uint32_t)ns2us(now - mLastWriteTime));
+        }
+        mLastWriteTime = now;
         return bytes;
 
     }
@@ -316,7 +327,7 @@
     standby();
 
     // Simulate audio output timing in case of error
-    usleep(((bytes * 1000 )/ frameSize() / sampleRate()) * 1000);
+    usleep(mBufferDurationUs);
 
     return status;
 }
diff --git a/services/audioflinger/A2dpAudioInterface.h b/services/audioflinger/A2dpAudioInterface.h
index cef1926..dbe2c6a 100644
--- a/services/audioflinger/A2dpAudioInterface.h
+++ b/services/audioflinger/A2dpAudioInterface.h
@@ -117,6 +117,8 @@
                 uint32_t    mDevice;
                 bool        mClosing;
                 bool        mSuspended;
+                nsecs_t     mLastWriteTime;
+                uint32_t    mBufferDurationUs;
     };
 
     friend class A2dpAudioStreamOut;