Merge "Ensure bitmaps aren't freed while referenced from a display list"
diff --git a/api/current.xml b/api/current.xml
index 9ab1dd0..0bbdc88 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -30028,6 +30028,19 @@
 <parameter name="args" type="java.lang.String[]">
 </parameter>
 </method>
+<method name="enableDebugLogging"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="enabled" type="boolean">
+</parameter>
+</method>
 <method name="executePendingTransactions"
  return="boolean"
  abstract="true"
@@ -32314,6 +32327,19 @@
 <parameter name="args" type="java.lang.String[]">
 </parameter>
 </method>
+<method name="enableDebugLogging"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="enabled" type="boolean">
+</parameter>
+</method>
 <method name="getLoader"
  return="android.content.Loader&lt;D&gt;"
  abstract="true"
@@ -42885,17 +42911,6 @@
  visibility="public"
 >
 </method>
-<method name="forceLoad"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="loadInBackground"
  return="D"
  abstract="true"
@@ -49578,28 +49593,6 @@
 <parameter name="uri" type="android.net.Uri">
 </parameter>
 </method>
-<method name="startLoading"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="stopLoading"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 </class>
 <interface name="DialogInterface"
  abstract="true"
@@ -54694,7 +54687,7 @@
 </class>
 <class name="Loader"
  extends="java.lang.Object"
- abstract="true"
+ abstract="false"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -54710,6 +54703,19 @@
 <parameter name="context" type="android.content.Context">
 </parameter>
 </constructor>
+<method name="dataToString"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="D">
+</parameter>
+</method>
 <method name="deliverResult"
  return="void"
  abstract="false"
@@ -54723,20 +54729,28 @@
 <parameter name="data" type="D">
 </parameter>
 </method>
-<method name="destroy"
+<method name="dump"
  return="void"
  abstract="false"
  native="false"
  synchronized="false"
  static="false"
  final="false"
- deprecated="deprecated"
+ deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="prefix" type="java.lang.String">
+</parameter>
+<parameter name="fd" type="java.io.FileDescriptor">
+</parameter>
+<parameter name="writer" type="java.io.PrintWriter">
+</parameter>
+<parameter name="args" type="java.lang.String[]">
+</parameter>
 </method>
 <method name="forceLoad"
  return="void"
- abstract="true"
+ abstract="false"
  native="false"
  synchronized="false"
  static="false"
@@ -54767,6 +54781,28 @@
  visibility="public"
 >
 </method>
+<method name="isReset"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isStarted"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="onContentChanged"
  return="void"
  abstract="false"
@@ -54778,6 +54814,50 @@
  visibility="public"
 >
 </method>
+<method name="onForceLoad"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
+<method name="onReset"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
+<method name="onStartLoading"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
+<method name="onStopLoading"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
 <method name="registerListener"
  return="void"
  abstract="false"
@@ -54806,7 +54886,7 @@
 </method>
 <method name="startLoading"
  return="void"
- abstract="true"
+ abstract="false"
  native="false"
  synchronized="false"
  static="false"
@@ -54817,7 +54897,7 @@
 </method>
 <method name="stopLoading"
  return="void"
- abstract="true"
+ abstract="false"
  native="false"
  synchronized="false"
  static="false"
@@ -143200,7 +143280,7 @@
  synchronized="false"
  static="true"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="data" type="byte[]">
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 348149e..f06f2cf 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -27,6 +27,7 @@
 import android.os.Parcelable;
 import android.util.AndroidRuntimeException;
 import android.util.AttributeSet;
+import android.util.DebugUtils;
 import android.util.SparseArray;
 import android.view.ContextMenu;
 import android.view.LayoutInflater;
@@ -526,17 +527,7 @@
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder(128);
-        String simpleName = getClass().getSimpleName();
-        if (simpleName == null || simpleName.isEmpty()) {
-            simpleName = getClass().getName();
-            int end = simpleName.lastIndexOf('.');
-            if (end > 0) {
-                simpleName = simpleName.substring(end+1);
-            }
-        }
-        sb.append(simpleName);
-        sb.append("{");
-        sb.append(Integer.toHexString(System.identityHashCode(this)));
+        DebugUtils.buildShortClassTag(this, sb);
         if (mIndex >= 0) {
             sb.append(" #");
             sb.append(mIndex);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 488b673..fe2ebed 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -26,6 +26,7 @@
 import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.DebugUtils;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.Menu;
@@ -251,6 +252,15 @@
      * @param args Additional arguments to the dump request.
      */
     public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
+
+    /**
+     * Control whether the framework's internal fragment manager debugging
+     * logs are turned on.  If enabled, you will see output in logcat as
+     * the framework performs fragment operations.
+     */
+    public static void enableDebugLogging(boolean enabled) {
+        FragmentManagerImpl.DEBUG = enabled;
+    }
 }
 
 final class FragmentManagerState implements Parcelable {
@@ -293,7 +303,7 @@
  * Container for fragments associated with an activity.
  */
 final class FragmentManagerImpl extends FragmentManager {
-    static final boolean DEBUG = false;
+    static boolean DEBUG = true;
     static final String TAG = "FragmentManager";
     
     static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
@@ -451,6 +461,17 @@
     }
 
     @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(128);
+        sb.append("FragmentManager{");
+        sb.append(Integer.toHexString(System.identityHashCode(this)));
+        sb.append(" in ");
+        DebugUtils.buildShortClassTag(mActivity, sb);
+        sb.append("}}");
+        return sb.toString();
+    }
+
+    @Override
     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
         if (mActive == null || mActive.size() <= 0) {
             return;
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index 7125054..0e97abb 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -18,6 +18,7 @@
 
 import android.content.Loader;
 import android.os.Bundle;
+import android.util.DebugUtils;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -122,6 +123,8 @@
      * @param id A unique identifier for this loader.  Can be whatever you want.
      * Identifiers are scoped to a particular LoaderManager instance.
      * @param args Optional arguments to supply to the loader at construction.
+     * If a loader already exists (a new one does not need to be created), this
+     * parameter will be ignored and the last arguments continue to be used.
      * @param callback Interface the LoaderManager will call to report about
      * changes in the state of the loader.  Required.
      */
@@ -177,11 +180,20 @@
      * @param args Additional arguments to the dump request.
      */
     public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
+
+    /**
+     * Control whether the framework's internal loader manager debugging
+     * logs are turned on.  If enabled, you will see output in logcat as
+     * the framework performs loader operations.
+     */
+    public static void enableDebugLogging(boolean enabled) {
+        LoaderManagerImpl.DEBUG = enabled;
+    }
 }
 
 class LoaderManagerImpl extends LoaderManager {
-    static final String TAG = "LoaderManagerImpl";
-    static final boolean DEBUG = true;
+    static final String TAG = "LoaderManager";
+    static boolean DEBUG = true;
 
     // These are the currently active loaders.  A loader is here
     // from the time its load is started until it has been explicitly
@@ -237,6 +249,11 @@
                mLoader = mCallbacks.onCreateLoader(mId, mArgs);
             }
             if (mLoader != null) {
+                if (mLoader.getClass().isMemberClass()) {
+                    throw new IllegalArgumentException(
+                            "Object returned from onCreateLoader must not be a member class: "
+                            + mLoader);
+                }
                 if (!mListenerRegistered) {
                     mLoader.registerListener(mId, this);
                     mListenerRegistered = true;
@@ -295,7 +312,10 @@
         void destroy() {
             if (DEBUG) Log.v(TAG, "  Destroying: " + this);
             mDestroyed = true;
-            if (mCallbacks != null && mLoader != null && mData != null && mNeedReset) {
+            boolean needReset = mNeedReset;
+            mNeedReset = false;
+            if (mCallbacks != null && mLoader != null && mData != null && needReset) {
+                if (DEBUG) Log.v(TAG, "  Reseting: " + this);
                 String lastBecause = null;
                 if (mActivity != null) {
                     lastBecause = mActivity.mFragments.mNoTransactionsBecause;
@@ -309,7 +329,6 @@
                     }
                 }
             }
-            mNeedReset = false;
             mCallbacks = null;
             mData = null;
             if (mLoader != null) {
@@ -322,9 +341,10 @@
         }
         
         @Override public void onLoadComplete(Loader<Object> loader, Object data) {
-            if (DEBUG) Log.v(TAG, "onLoadComplete: " + this + " mDestroyed=" + mDestroyed);
+            if (DEBUG) Log.v(TAG, "onLoadComplete: " + this);
 
             if (mDestroyed) {
+                if (DEBUG) Log.v(TAG, "  Ignoring load complete -- destroyed");
                 return;
             }
             
@@ -335,7 +355,7 @@
                 callOnLoadFinished(loader, data);
             }
 
-            if (DEBUG) Log.v(TAG, "onLoadFinished returned: " + this);
+            //if (DEBUG) Log.v(TAG, "  onLoadFinished returned: " + this);
 
             // We have now given the application the new loader with its
             // loaded data, so it should have stopped using the previous
@@ -357,6 +377,8 @@
                     mActivity.mFragments.mNoTransactionsBecause = "onLoadFinished";
                 }
                 try {
+                    if (DEBUG) Log.v(TAG, "  onLoadFinished in " + loader + ": "
+                            + loader.dataToString(data));
                     mCallbacks.onLoadFinished(loader, data);
                 } finally {
                     if (mActivity != null) {
@@ -374,21 +396,9 @@
             sb.append(Integer.toHexString(System.identityHashCode(this)));
             sb.append(" #");
             sb.append(mId);
-            if (mArgs != null) {
-                sb.append(" ");
-                sb.append(mArgs.toString());
-            }
-            sb.append("}");
-            return sb.toString();
-        }
-
-        public String toBasicString() {
-            StringBuilder sb = new StringBuilder(64);
-            sb.append("LoaderInfo{");
-            sb.append(Integer.toHexString(System.identityHashCode(this)));
-            sb.append(" #");
-            sb.append(mId);
-            sb.append("}");
+            sb.append(" : ");
+            DebugUtils.buildShortClassTag(mLoader, sb);
+            sb.append("}}");
             return sb.toString();
         }
 
@@ -397,6 +407,9 @@
                     writer.print(" mArgs="); writer.println(mArgs);
             writer.print(prefix); writer.print("mCallbacks="); writer.println(mCallbacks);
             writer.print(prefix); writer.print("mLoader="); writer.println(mLoader);
+            if (mLoader != null) {
+                mLoader.dump(prefix + "  ", fd, writer, args);
+            }
             writer.print(prefix); writer.print("mData="); writer.println(mData);
             writer.print(prefix); writer.print("mStarted="); writer.print(mStarted);
                     writer.print(" mRetaining="); writer.print(mRetaining);
@@ -434,12 +447,14 @@
     public <D> Loader<D> initLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<D> callback) {
         LoaderInfo info = mLoaders.get(id);
         
-        if (DEBUG) Log.v(TAG, "initLoader in " + this + ": cur=" + info);
+        if (DEBUG) Log.v(TAG, "initLoader in " + this + ": args=" + args);
 
         if (info == null) {
             // Loader doesn't already exist; create.
             info = createLoader(id, args,  (LoaderManager.LoaderCallbacks<Object>)callback);
+            if (DEBUG) Log.v(TAG, "  Created new loader " + info);
         } else {
+            if (DEBUG) Log.v(TAG, "  Re-using existing loader " + info);
             info.mCallbacks = (LoaderManager.LoaderCallbacks<Object>)callback;
         }
         
@@ -454,7 +469,7 @@
     @SuppressWarnings("unchecked")
     public <D> Loader<D> restartLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<D> callback) {
         LoaderInfo info = mLoaders.get(id);
-        if (DEBUG) Log.v(TAG, "restartLoader in " + this + ": cur=" + info);
+        if (DEBUG) Log.v(TAG, "restartLoader in " + this + ": args=" + args);
         if (info != null) {
             LoaderInfo inactive = mInactiveLoaders.get(id);
             if (inactive != null) {
@@ -463,7 +478,7 @@
                     // called from within onLoadComplete, where we haven't
                     // yet destroyed the last inactive loader.  So just do
                     // that now.
-                    if (DEBUG) Log.v(TAG, "  Removing last inactive loader in " + this);
+                    if (DEBUG) Log.v(TAG, "  Removing last inactive loader: " + info);
                     inactive.mNeedReset = false;
                     inactive.destroy();
                     mInactiveLoaders.put(id, info);
@@ -472,13 +487,13 @@
                     // waiting for!  Now we have three active loaders... let's just
                     // drop the one in the middle, since we are still waiting for
                     // its result but that result is already out of date.
-                    if (DEBUG) Log.v(TAG, "  Removing intermediate loader in " + this);
+                    if (DEBUG) Log.v(TAG, "  Removing intermediate loader: " + info);
                     info.destroy();
                 }
             } else {
                 // Keep track of the previous instance of this loader so we can destroy
                 // it when the new one completes.
-                if (DEBUG) Log.v(TAG, "  Making inactive: " + info);
+                if (DEBUG) Log.v(TAG, "  Making last loader inactive: " + info);
                 mInactiveLoaders.put(id, info);
             }
         }
@@ -488,7 +503,7 @@
     }
     
     public void destroyLoader(int id) {
-        if (DEBUG) Log.v(TAG, "stopLoader in " + this + " of " + id);
+        if (DEBUG) Log.v(TAG, "destroyLoader in " + this + " of " + id);
         int idx = mLoaders.indexOfKey(id);
         if (idx >= 0) {
             LoaderInfo info = mLoaders.valueAt(idx);
@@ -513,7 +528,7 @@
     }
  
     void doStart() {
-        if (DEBUG) Log.v(TAG, "Starting: " + this);
+        if (DEBUG) Log.v(TAG, "Starting in " + this);
         if (mStarted) {
             RuntimeException e = new RuntimeException("here");
             e.fillInStackTrace();
@@ -531,7 +546,7 @@
     }
     
     void doStop() {
-        if (DEBUG) Log.v(TAG, "Stopping: " + this);
+        if (DEBUG) Log.v(TAG, "Stopping in " + this);
         if (!mStarted) {
             RuntimeException e = new RuntimeException("here");
             e.fillInStackTrace();
@@ -546,7 +561,7 @@
     }
     
     void doRetain() {
-        if (DEBUG) Log.v(TAG, "Retaining: " + this);
+        if (DEBUG) Log.v(TAG, "Retaining in " + this);
         if (!mStarted) {
             RuntimeException e = new RuntimeException("here");
             e.fillInStackTrace();
@@ -562,23 +577,25 @@
     }
     
     void finishRetain() {
-        if (DEBUG) Log.v(TAG, "Finished Retaining: " + this);
+        if (mRetaining) {
+            if (DEBUG) Log.v(TAG, "Finished Retaining in " + this);
 
-        mRetaining = false;
-        for (int i = mLoaders.size()-1; i >= 0; i--) {
-            mLoaders.valueAt(i).finishRetain();
+            mRetaining = false;
+            for (int i = mLoaders.size()-1; i >= 0; i--) {
+                mLoaders.valueAt(i).finishRetain();
+            }
         }
     }
     
     void doDestroy() {
         if (!mRetaining) {
-            if (DEBUG) Log.v(TAG, "Destroying Active: " + this);
+            if (DEBUG) Log.v(TAG, "Destroying Active in " + this);
             for (int i = mLoaders.size()-1; i >= 0; i--) {
                 mLoaders.valueAt(i).destroy();
             }
         }
         
-        if (DEBUG) Log.v(TAG, "Destroying Inactive: " + this);
+        if (DEBUG) Log.v(TAG, "Destroying Inactive in " + this);
         for (int i = mInactiveLoaders.size()-1; i >= 0; i--) {
             mInactiveLoaders.valueAt(i).destroy();
         }
@@ -586,6 +603,17 @@
     }
 
     @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(128);
+        sb.append("LoaderManager{");
+        sb.append(Integer.toHexString(System.identityHashCode(this)));
+        sb.append(" in ");
+        DebugUtils.buildShortClassTag(mActivity, sb);
+        sb.append("}}");
+        return sb.toString();
+    }
+
+    @Override
     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
         if (mLoaders.size() > 0) {
             writer.print(prefix); writer.println("Active Loaders:");
@@ -593,7 +621,7 @@
             for (int i=0; i < mLoaders.size(); i++) {
                 LoaderInfo li = mLoaders.valueAt(i);
                 writer.print(prefix); writer.print("  #"); writer.print(mLoaders.keyAt(i));
-                        writer.print(": "); writer.println(li.toBasicString());
+                        writer.print(": "); writer.println(li.toString());
                 li.dump(innerPrefix, fd, writer, args);
             }
         }
@@ -603,7 +631,7 @@
             for (int i=0; i < mInactiveLoaders.size(); i++) {
                 LoaderInfo li = mInactiveLoaders.valueAt(i);
                 writer.print(prefix); writer.print("  #"); writer.print(mInactiveLoaders.keyAt(i));
-                        writer.print(": "); writer.println(li.toBasicString());
+                        writer.print(": "); writer.println(li.toString());
                 li.dump(innerPrefix, fd, writer, args);
             }
         }
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java
index b19c072..30f8ffc 100644
--- a/core/java/android/content/AsyncTaskLoader.java
+++ b/core/java/android/content/AsyncTaskLoader.java
@@ -53,12 +53,8 @@
         super(context);
     }
 
-    /**
-     * Force an asynchronous load. Unlike {@link #startLoading()} this will ignore a previously
-     * loaded data set and load a new one.
-     */
     @Override
-    public void forceLoad() {
+    protected void onForceLoad() {
         cancelLoad();
         mTask = new LoadTask();
         mTask.execute((Void[]) null);
diff --git a/core/java/android/content/CursorLoader.java b/core/java/android/content/CursorLoader.java
index 9e03c25..91dd23b 100644
--- a/core/java/android/content/CursorLoader.java
+++ b/core/java/android/content/CursorLoader.java
@@ -20,21 +20,25 @@
 import android.database.Cursor;
 import android.net.Uri;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Arrays;
+
 /**
  * A loader that queries the {@link ContentResolver} and returns a {@link Cursor}.
  */
 public class CursorLoader extends AsyncTaskLoader<Cursor> {
-    Cursor mCursor;
-    ForceLoadContentObserver mObserver;
-    boolean mStopped;
-    boolean mContentChanged;
-    boolean mReset;
+    final ForceLoadContentObserver mObserver;
+
     Uri mUri;
     String[] mProjection;
     String mSelection;
     String[] mSelectionArgs;
     String mSortOrder;
 
+    Cursor mCursor;
+    boolean mContentChanged;
+
     /* Runs on a worker thread */
     @Override
     public Cursor loadInBackground() {
@@ -69,7 +73,7 @@
         Cursor oldCursor = mCursor;
         mCursor = cursor;
 
-        if (!mStopped) {
+        if (isStarted()) {
             super.deliverResult(cursor);
         }
 
@@ -97,10 +101,7 @@
      * Must be called from the UI thread
      */
     @Override
-    public void startLoading() {
-        mStopped = false;
-        mReset = false;
-
+    protected void onStartLoading() {
         if (mCursor != null) {
             deliverResult(mCursor);
         }
@@ -114,17 +115,14 @@
      * Must be called from the UI thread
      */
     @Override
-    public void stopLoading() {
+    protected void onStopLoading() {
         // Attempt to cancel the current load task if possible.
         cancelLoad();
-
-        // Make sure that any outstanding loads clean themselves up properly
-        mStopped = true;
     }
 
     @Override
     public void onContentChanged() {
-        if (mStopped) {
+        if (!isStarted()) {
             // This loader has been stopped, so we don't want to load
             // new data right now...  but keep track of it changing to
             // refresh later if we start again.
@@ -142,7 +140,7 @@
     }
 
     @Override
-    public void reset() {
+    protected void onReset() {
         mReset = true;
 
         // Ensure the loader is stopped
@@ -193,4 +191,18 @@
     public void setSortOrder(String sortOrder) {
         mSortOrder = sortOrder;
     }
+
+    @Override
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        super.dump(prefix, fd, writer, args);
+        writer.print(prefix); writer.print("mUri="); writer.println(mUri);
+        writer.print(prefix); writer.print("mProjection=");
+                writer.println(Arrays.toString(mProjection));
+        writer.print(prefix); writer.print("mSelection="); writer.println(mSelection);
+        writer.print(prefix); writer.print("mSelectionArgs=");
+                writer.println(Arrays.toString(mSelectionArgs));
+        writer.print(prefix); writer.print("mSortOrder="); writer.println(mSortOrder);
+        writer.print(prefix); writer.print("mCursor="); writer.println(mCursor);
+        writer.print(prefix); writer.print("mContentChanged="); writer.println(mContentChanged);
+    }
 }
diff --git a/core/java/android/content/Loader.java b/core/java/android/content/Loader.java
index 73d7103..f425b29 100644
--- a/core/java/android/content/Loader.java
+++ b/core/java/android/content/Loader.java
@@ -18,18 +18,27 @@
 
 import android.database.ContentObserver;
 import android.os.Handler;
+import android.util.DebugUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 
 /**
  * An abstract class that performs asynchronous loading of data. While Loaders are active
  * they should monitor the source of their data and deliver new results when the contents
  * change.
  *
+ * <p>Subclasses generally must implement at least {@link #onStartLoading()},
+ * {@link #onStopLoading()}, {@link #onForceLoad()}, and {@link #onReset()}.
+ *
  * @param <D> The result returned when the load is complete
  */
-public abstract class Loader<D> {
+public class Loader<D> {
     int mId;
     OnLoadCompleteListener<D> mListener;
     Context mContext;
+    boolean mStarted = false;
+    boolean mReset = true;
 
     public final class ForceLoadContentObserver extends ContentObserver {
         public ForceLoadContentObserver() {
@@ -122,28 +131,88 @@
     }
 
     /**
+     * Return whether this load has been started.  That is, its {@link #startLoading()}
+     * has been called and no calls to {@link #stopLoading()} or
+     * {@link #reset()} have yet been made.
+     */
+    public boolean isStarted() {
+        return mStarted;
+    }
+
+    /**
+     * Return whether this load has been reset.  That is, either the loader
+     * has not yet been started for the first time, or its {@link #reset()}
+     * has been called.
+     */
+    public boolean isReset() {
+        return mReset;
+    }
+
+    /**
      * Starts an asynchronous load of the contacts list data. When the result is ready the callbacks
      * will be called on the UI thread. If a previous load has been completed and is still valid
      * the result may be passed to the callbacks immediately. The loader will monitor the source of
      * the data set and may deliver future callbacks if the source changes. Calling
      * {@link #stopLoading} will stop the delivery of callbacks.
      *
-     * <p>Must be called from the UI thread
+     * <p>This updates the Loader's internal state so that
+     * {@link #isStarted()} and {@link #isReset()} will return the correct
+     * values, and then calls the implementation's {@link #onStartLoading()}.
+     *
+     * <p>Must be called from the UI thread.
      */
-    public abstract void startLoading();
+    public void startLoading() {
+        mStarted = true;
+        mReset = false;
+        onStartLoading();
+    }
+
+    /**
+     * Subclasses must implement this to take care of loading their data,
+     * as per {@link #startLoading()}.  This is not called by clients directly,
+     * but as a result of a call to {@link #startLoading()}.
+     */
+    protected void onStartLoading() {
+    }
 
     /**
      * Force an asynchronous load. Unlike {@link #startLoading()} this will ignore a previously
-     * loaded data set and load a new one.
+     * loaded data set and load a new one.  This simply calls through to the
+     * implementation's {@link #onForceLoad()}.
+     *
+     * <p>Must be called from the UI thread.
      */
-    public abstract void forceLoad();
+    public void forceLoad() {
+        onForceLoad();
+    }
 
     /**
-     * Stops delivery of updates until the next time {@link #startLoading()} is called
-     *
-     * <p>Must be called from the UI thread
+     * Subclasses must implement this to take care of requests to {@link #forceLoad()}.
      */
-    public abstract void stopLoading();
+    protected void onForceLoad() {
+    }
+
+    /**
+     * Stops delivery of updates until the next time {@link #startLoading()} is called.
+     *
+     * <p>This updates the Loader's internal state so that
+     * {@link #isStarted()} will return the correct
+     * value, and then calls the implementation's {@link #onStopLoading()}.
+     *
+     * <p>Must be called from the UI thread.
+     */
+    public void stopLoading() {
+        mStarted = false;
+        onStopLoading();
+    }
+
+    /**
+     * Subclasses must implement this to take care of stopping their loader,
+     * as per {@link #stopLoading()}.  This is not called by clients directly,
+     * but as a result of a call to {@link #stopLoading()}.
+     */
+    protected void onStopLoading() {
+    }
 
     /**
      * Resets the state of the Loader.  The Loader should at this point free
@@ -151,17 +220,24 @@
      * {@link #startLoading()} may later be called at which point it must be
      * able to start running again.
      *
-     * <p>Must be called from the UI thread
+     * <p>This updates the Loader's internal state so that
+     * {@link #isStarted()} and {@link #isReset()} will return the correct
+     * values, and then calls the implementation's {@link #onReset()}.
+     *
+     * <p>Must be called from the UI thread.
      */
     public void reset() {
-        destroy();
+        onReset();
+        mReset = true;
+        mStarted = false;
     }
 
     /**
-     * @deprecated Old API, implement reset() now.
+     * Subclasses must implement this to take care of resetting their loader,
+     * as per {@link #reset()}.  This is not called by clients directly,
+     * but as a result of a call to {@link #reset()}.
      */
-    @Deprecated
-    public void destroy() {
+    protected void onReset() {
     }
 
     /**
@@ -173,4 +249,40 @@
     public void onContentChanged() {
         forceLoad();
     }
+
+    /**
+     * For debugging, converts an instance of the Loader's data class to
+     * a string that can be printed.  Must handle a null data.
+     */
+    public String dataToString(D data) {
+        StringBuilder sb = new StringBuilder(64);
+        DebugUtils.buildShortClassTag(data, sb);
+        sb.append("}");
+        return sb.toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(64);
+        DebugUtils.buildShortClassTag(this, sb);
+        sb.append(" id=");
+        sb.append(mId);
+        sb.append("}");
+        return sb.toString();
+    }
+
+    /**
+     * Print the Loader's state into the given stream.
+     *
+     * @param prefix Text to print at the front of each line.
+     * @param fd The raw file descriptor that the dump is being sent to.
+     * @param writer A PrintWriter to which the dump is to be set.
+     * @param args Additional arguments to the dump request.
+     */
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        writer.print(prefix); writer.print("mId="); writer.print(mId);
+                writer.print(" mListener="); writer.println(mListener);
+        writer.print(prefix); writer.print("mStarted="); writer.print(mStarted);
+                writer.print(" mReset="); writer.println(mReset);
+    }
 }
\ No newline at end of file
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index f0309d6..9d5d742 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -281,7 +281,7 @@
     /**
      * Runs on the UI thread after {@link #doInBackground}. The
      * specified result is the value returned by {@link #doInBackground}
-     * or null if the task was cancelled or an exception occured.
+     * or null if the task was cancelled or an exception occurred.
      *
      * @param result The result of the operation computed by {@link #doInBackground}.
      *
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 5f6c4f0..b6c2ed6 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -153,6 +153,7 @@
     private static native int createPipeNative(FileDescriptor[] outFds);
 
     /**
+     * @deprecated Please use createPipe() or ContentProvider.openPipeHelper().
      * Gets a file descriptor for a read-only copy of the given data.
      *
      * @param data Data to copy.
@@ -161,6 +162,7 @@
      * @return A ParcelFileDescriptor.
      * @throws IOException if there is an error while creating the shared memory area.
      */
+    @Deprecated
     public static ParcelFileDescriptor fromData(byte[] data, String name) throws IOException {
         if (data == null) return null;
         MemoryFile file = new MemoryFile(name, data.length);
diff --git a/core/java/android/util/DebugUtils.java b/core/java/android/util/DebugUtils.java
index 56f389c..65fc35c 100644
--- a/core/java/android/util/DebugUtils.java
+++ b/core/java/android/util/DebugUtils.java
@@ -101,4 +101,23 @@
         return match;
     }
 
+    /** @hide */
+    public static void buildShortClassTag(Object cls, StringBuilder out) {
+        if (cls == null) {
+            out.append("null");
+        } else {
+            String simpleName = cls.getClass().getSimpleName();
+            if (simpleName == null || simpleName.isEmpty()) {
+                simpleName = cls.getClass().getName();
+                int end = simpleName.lastIndexOf('.');
+                if (end > 0) {
+                    simpleName = simpleName.substring(end+1);
+                }
+            }
+            out.append(simpleName);
+            out.append('{');
+            out.append(Integer.toHexString(System.identityHashCode(cls)));
+        }
+    }
+
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 71d07c6..55d3b16 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7430,6 +7430,7 @@
             initialAwakenScrollBars();
             mPrivateFlags &= ~AWAKEN_SCROLL_BARS_ON_ATTACH;
         }
+        jumpDrawablesToCurrentState();
     }
 
     /**
diff --git a/core/java/android/webkit/JWebCoreJavaBridge.java b/core/java/android/webkit/JWebCoreJavaBridge.java
index 976e786..908526f 100644
--- a/core/java/android/webkit/JWebCoreJavaBridge.java
+++ b/core/java/android/webkit/JWebCoreJavaBridge.java
@@ -307,5 +307,4 @@
     public native void addPackageNames(Set<String> packageNames);
     public native void addPackageName(String packageName);
     public native void removePackageName(String packageName);
-    public native void updateProxy(String newProxy);
 }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9718443..885bada 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -48,8 +48,6 @@
 import android.graphics.Region;
 import android.graphics.Shader;
 import android.graphics.drawable.Drawable;
-import android.net.Proxy;
-import android.net.ProxyProperties;
 import android.net.Uri;
 import android.net.http.SslCertificate;
 import android.os.AsyncTask;
@@ -983,7 +981,6 @@
          */
         init();
         setupPackageListener(context);
-        setupProxyListener(context);
         updateMultiTouchSupport(context);
 
         if (privateBrowsing) {
@@ -993,42 +990,6 @@
         mAutoFillData = new WebViewCore.AutoFillData();
     }
 
-    private static class ProxyReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) {
-                handleProxyBroadcast(intent);
-            }
-        }
-    }
-
-    private static void setupProxyListener(Context context) {
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Proxy.PROXY_CHANGE_ACTION);
-        Intent currentProxy = context.registerReceiver(new ProxyReceiver(), filter);
-        if (currentProxy != null) {
-            handleProxyBroadcast(currentProxy);
-        }
-    }
-
-    private static void handleProxyBroadcast(Intent intent) {
-        ProxyProperties proxyProperties = (ProxyProperties)intent.getExtra(Proxy.EXTRA_PROXY_INFO);
-        if (proxyProperties == null) {
-            WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, "");
-            return;
-        }
-
-        String host = proxyProperties.getHost();
-        int port = proxyProperties.getPort();
-        host += ": " + port;
-
-        // TODO: Handle exclusion list
-        // The plan is to make an AndroidProxyResolver, and handle the blacklist
-        // there
-        String exclusionList = proxyProperties.getExclusionList();
-        WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, host);
-    }
-
     /*
      * A variable to track if there is a receiver added for ACTION_PACKAGE_ADDED
      * or ACTION_PACKAGE_REMOVED.
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 45927f9..f45fad9 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -684,14 +684,6 @@
                                 }
                                 BrowserFrame.sJavaBridge.removePackageName((String) msg.obj);
                                 break;
-
-                            case EventHub.PROXY_CHANGED:
-                                if (BrowserFrame.sJavaBridge == null) {
-                                    throw new IllegalStateException(
-                                            "No WebView has been created in this process!");
-                                }
-                                BrowserFrame.sJavaBridge.updateProxy((String) msg.obj);
-                                break;
                         }
                     }
                 };
@@ -991,8 +983,6 @@
 
         static final int AUTOFILL_FORM = 192;
 
-        static final int PROXY_CHANGED = 193;
-
         // private message ids
         private static final int DESTROY =     200;
 
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 3ff483d..0dbc204 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -102,12 +102,6 @@
         mRS.nAllocationSyncAll(getID(), srcLocation);
     }
 
-    public void uploadToBufferObject() {
-        mRS.validate();
-        mRS.nAllocationUploadToBufferObject(getID());
-    }
-
-
     public void copyFrom(BaseObj[] d) {
         mRS.validate();
         if (d.length != mType.getCount()) {
@@ -516,19 +510,6 @@
                                         USAGE_GRAPHICS_TEXTURE);
     }
 
-/*
-    static public Allocation createFromBitmapResource(RenderScript rs,
-                                                      Resources res,
-                                                      int id,
-                                                      Element dstFmt,
-                                                      boolean genMips) {
-        MipmapControl mc = MipmapControl.MIPMAP_NONE;
-        if (genMips) {
-            mc = MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE;
-        }
-        return createFromBitmapResource(rs, res, id, mc, USAGE_GRAPHICS_TEXTURE);
-    }
-*/
     static public Allocation createFromString(RenderScript rs,
                                               String str,
                                               int usage) {
diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java
index b103af4..950a91a 100644
--- a/graphics/java/android/renderscript/Mesh.java
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -93,20 +93,23 @@
 
     public static class Builder {
         RenderScript mRS;
+        int mUsage;
 
         class Entry {
             Type t;
             Element e;
             int size;
             Primitive prim;
+            int usage;
         }
 
         int mVertexTypeCount;
         Entry[] mVertexTypes;
         Vector mIndexTypes;
 
-        public Builder(RenderScript rs) {
+        public Builder(RenderScript rs, int usage) {
             mRS = rs;
+            mUsage = usage;
             mVertexTypeCount = 0;
             mVertexTypes = new Entry[16];
             mIndexTypes = new Vector();
@@ -190,10 +193,10 @@
                 Allocation alloc = null;
                 Entry entry = (Entry)b.mIndexTypes.elementAt(ct);
                 if (entry.t != null) {
-                    alloc = Allocation.createTyped(rs, entry.t);
+                    alloc = Allocation.createTyped(rs, entry.t, b.mUsage);
                 }
                 else if(entry.e != null) {
-                    alloc = Allocation.createSized(rs, entry.e, entry.size);
+                    alloc = Allocation.createSized(rs, entry.e, entry.size, b.mUsage);
                 }
                 int allocID = (alloc == null) ? 0 : alloc.getID();
                 rs.nMeshBindIndex(id, allocID, entry.prim.mID, ct);
@@ -205,9 +208,9 @@
                 Allocation alloc = null;
                 Entry entry = b.mVertexTypes[ct];
                 if (entry.t != null) {
-                    alloc = Allocation.createTyped(rs, entry.t);
+                    alloc = Allocation.createTyped(rs, entry.t, b.mUsage);
                 } else if(entry.e != null) {
-                    alloc = Allocation.createSized(rs, entry.e, entry.size);
+                    alloc = Allocation.createSized(rs, entry.e, entry.size, b.mUsage);
                 }
                 rs.nMeshBindVertex(id, alloc.getID(), ct);
                 newMesh.mVertexBuffers[ct] = alloc;
@@ -460,7 +463,12 @@
             }
             mElement = b.create();
 
-            Builder smb = new Builder(mRS);
+            int usage = Allocation.USAGE_SCRIPT;
+            if (uploadToBufferObject) {
+                usage |= Allocation.USAGE_GRAPHICS_VERTEX;
+            }
+
+            Builder smb = new Builder(mRS, usage);
             smb.addVertexType(mElement, mVtxCount / floatCount);
             smb.addIndexType(Element.U16(mRS), mIndexCount, Primitive.TRIANGLE);
 
@@ -468,11 +476,15 @@
 
             sm.getVertexAllocation(0).copyFrom(mVtxData);
             if(uploadToBufferObject) {
-                sm.getVertexAllocation(0).uploadToBufferObject();
+                if (uploadToBufferObject) {
+                    sm.getVertexAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
+                }
             }
 
             sm.getIndexAllocation(0).copyFrom(mIndexData);
-            sm.getIndexAllocation(0).uploadToBufferObject();
+            if (uploadToBufferObject) {
+                sm.getIndexAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
+            }
 
             return sm;
         }
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index fb5980a..48a0969 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -287,24 +287,6 @@
     static_cast<Allocation *>(va)->syncAll(rsc, source);
 }
 
-static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel) {
-    CHECK_OBJ(va);
-    GET_TLS();
-    rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
-}
-
-static void SC_uploadToTexture(RsAllocation va) {
-    CHECK_OBJ(va);
-    GET_TLS();
-    rsi_AllocationUploadToTexture(rsc, va, false, 0);
-}
-
-static void SC_uploadToBufferObject(RsAllocation va) {
-    CHECK_OBJ(va);
-    GET_TLS();
-    rsi_AllocationUploadToBufferObject(rsc, va);
-}
-
 static void SC_ClearColor(float r, float g, float b, float a) {
     GET_TLS();
     rsc->setupProgramStore();
@@ -439,10 +421,6 @@
 
     { "_Z20rsgAllocationSyncAll13rs_allocation", (void *)&SC_allocationSyncAll, false },
 
-    { "_Z18rsgUploadToTexture13rs_allocationj", (void *)&SC_uploadToTexture2, false },
-    { "_Z18rsgUploadToTexture13rs_allocation", (void *)&SC_uploadToTexture, false },
-    { "_Z23rsgUploadToBufferObject13rs_allocation", (void *)&SC_uploadToBufferObject, false },
-
     { "_Z11rsgDrawRectfffff", (void *)&SC_drawRect, false },
     { "_Z11rsgDrawQuadffffffffffff", (void *)&SC_drawQuad, false },
     { "_Z20rsgDrawQuadTexCoordsffffffffffffffffffff", (void *)&SC_drawQuadTexCoords, false },
diff --git a/libs/rs/scriptc/rs_graphics.rsh b/libs/rs/scriptc/rs_graphics.rsh
index 3e708aa..3868f24 100644
--- a/libs/rs/scriptc/rs_graphics.rsh
+++ b/libs/rs/scriptc/rs_graphics.rsh
@@ -38,13 +38,6 @@
     rsgAllocationSyncAll(rs_allocation);
 
 extern void __attribute__((overloadable))
-    rsgUploadToTexture(rs_allocation);
-extern void __attribute__((overloadable))
-    rsgUploadToTexture(rs_allocation, uint mipLevel);
-extern void __attribute__((overloadable))
-    rsgUploadToBufferObject(rs_allocation);
-
-extern void __attribute__((overloadable))
     rsgDrawRect(float x1, float y1, float x2, float y2, float z);
 extern void __attribute__((overloadable))
     rsgDrawQuad(float x1, float y1, float z1,