Merge "fix an issue where the screen could stay off"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 9381437..fb334fc 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -116,6 +116,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/DroidSans*)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/DroidSans*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d2facdc..8afe9bf 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -490,6 +490,15 @@
         // Formatting for checkin service - update version if row format changes
         private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
 
+        private void updatePendingConfiguration(Configuration config) {
+            synchronized (mPackages) {
+                if (mPendingConfiguration == null ||
+                        mPendingConfiguration.isOtherSeqNewer(config)) {
+                    mPendingConfiguration = config;
+                }
+            }
+        }
+
         public final void schedulePauseActivity(IBinder token, boolean finished,
                 boolean userLeaving, int configChanges) {
             queueOrSendMessage(
@@ -530,8 +539,8 @@
         // we use token to identify this activity without having to send the
         // activity itself back to the activity manager. (matters more with ipc)
         public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
-                ActivityInfo info, CompatibilityInfo compatInfo, Bundle state,
-                List<ResultInfo> pendingResults,
+                ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
+                Bundle state, List<ResultInfo> pendingResults,
                 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
                 String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
             ActivityClientRecord r = new ActivityClientRecord();
@@ -553,6 +562,8 @@
             r.profileFd = profileFd;
             r.autoStopProfiler = autoStopProfiler;
 
+            updatePendingConfiguration(curConfig);
+
             queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
         }
 
@@ -697,12 +708,7 @@
         }
 
         public void scheduleConfigurationChanged(Configuration config) {
-            synchronized (mPackages) {
-                if (mPendingConfiguration == null ||
-                        mPendingConfiguration.isOtherSeqNewer(config)) {
-                    mPendingConfiguration = config;
-                }
-            }
+            updatePendingConfiguration(config);
             queueOrSendMessage(H.CONFIGURATION_CHANGED, config);
         }
 
@@ -1966,6 +1972,9 @@
             mProfiler.autoStopProfiler = r.autoStopProfiler;
         }
 
+        // Make sure we are running with the most recent config.
+        handleConfigurationChanged(null, null);
+
         if (localLOGV) Slog.v(
             TAG, "Handling launch of " + r);
         Activity a = performLaunchActivity(r, customIntent);
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index cde06cd..c4a4fea 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -132,6 +132,7 @@
             IBinder b = data.readStrongBinder();
             int ident = data.readInt();
             ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
+            Configuration curConfig = Configuration.CREATOR.createFromParcel(data);
             CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
             Bundle state = data.readBundle();
             List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
@@ -142,7 +143,7 @@
             ParcelFileDescriptor profileFd = data.readInt() != 0
                     ? data.readFileDescriptor() : null;
             boolean autoStopProfiler = data.readInt() != 0;
-            scheduleLaunchActivity(intent, b, ident, info, compatInfo, state, ri, pi,
+            scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, state, ri, pi,
                     notResumed, isForward, profileName, profileFd, autoStopProfiler);
             return true;
         }
@@ -630,10 +631,10 @@
     }
 
     public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
-            ActivityInfo info, CompatibilityInfo compatInfo, Bundle state,
-            List<ResultInfo> pendingResults,
-		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
-		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
+            ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
+            Bundle state, List<ResultInfo> pendingResults,
+    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+    		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
     		throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
@@ -641,6 +642,7 @@
         data.writeStrongBinder(token);
         data.writeInt(ident);
         info.writeToParcel(data, 0);
+        curConfig.writeToParcel(data, 0);
         compatInfo.writeToParcel(data, 0);
         data.writeBundle(state);
         data.writeTypedList(pendingResults);
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 5d200b4..1253fe7 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -53,10 +53,10 @@
     void scheduleResumeActivity(IBinder token, boolean isForward) throws RemoteException;
     void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
     void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
-            ActivityInfo info, CompatibilityInfo compatInfo, Bundle state,
-            List<ResultInfo> pendingResults,
-		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
-		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
+            ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
+            Bundle state, List<ResultInfo> pendingResults,
+    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+    		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
     		throws RemoteException;
     void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
             List<Intent> pendingNewIntents, int configChanges,
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 8aee65c..615e8ce 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -29,6 +29,7 @@
 
 import org.xmlpull.v1.XmlPullParserException;
 
+import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -107,7 +108,8 @@
         FileStatus stat = new FileStatus();
         if (FileUtils.getFileStatus(mFile.getPath(), stat) && mFile.canRead()) {
             try {
-                FileInputStream str = new FileInputStream(mFile);
+                BufferedInputStream str = new BufferedInputStream(
+                        new FileInputStream(mFile), 16*1024);
                 map = XmlUtils.readMapXml(str);
                 str.close();
             } catch (XmlPullParserException e) {
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 8057d4b..e452f1f 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -22,10 +22,6 @@
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Configuration;
 import android.database.Cursor;
-import android.database.CursorToBulkCursorAdaptor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
 import android.database.SQLException;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -168,22 +164,9 @@
             return ContentProvider.this;
         }
 
-        /**
-         * Remote version of a query, which returns an IBulkCursor. The bulk
-         * cursor should be wrapped with BulkCursorToCursorAdaptor before use.
-         */
-        public IBulkCursor bulkQuery(Uri uri, String[] projection,
-                String selection, String[] selectionArgs, String sortOrder,
-                IContentObserver observer, CursorWindow window) {
-            enforceReadPermission(uri);
-            Cursor cursor = ContentProvider.this.query(uri, projection,
-                    selection, selectionArgs, sortOrder);
-            if (cursor == null) {
-                return null;
-            }
-            return new CursorToBulkCursorAdaptor(cursor, observer,
-                    ContentProvider.this.getClass().getName(),
-                    hasWritePermission(uri), window);
+        @Override
+        public String getProviderName() {
+            return getContentProvider().getClass().getName();
         }
 
         public Cursor query(Uri uri, String[] projection,
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index 9a20951..064755e 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -20,6 +20,7 @@
 import android.database.BulkCursorNative;
 import android.database.BulkCursorToCursorAdaptor;
 import android.database.Cursor;
+import android.database.CursorToBulkCursorAdaptor;
 import android.database.CursorWindow;
 import android.database.DatabaseUtils;
 import android.database.IBulkCursor;
@@ -65,6 +66,13 @@
         return new ContentProviderProxy(obj);
     }
 
+    /**
+     * Gets the name of the content provider.
+     * Should probably be part of the {@link IContentProvider} interface.
+     * @return The content provider name.
+     */
+    public abstract String getProviderName();
+
     @Override
     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
             throws RemoteException {
@@ -98,33 +106,23 @@
                     }
 
                     String sortOrder = data.readString();
-                    IContentObserver observer = IContentObserver.Stub.
-                        asInterface(data.readStrongBinder());
+                    IContentObserver observer = IContentObserver.Stub.asInterface(
+                            data.readStrongBinder());
                     CursorWindow window = CursorWindow.CREATOR.createFromParcel(data);
 
-                    // Flag for whether caller wants the number of
-                    // rows in the cursor and the position of the
-                    // "_id" column index (or -1 if non-existent)
-                    // Only to be returned if binder != null.
-                    boolean wantsCursorMetadata = data.readInt() != 0;
+                    Cursor cursor = query(url, projection, selection, selectionArgs, sortOrder);
+                    if (cursor != null) {
+                        CursorToBulkCursorAdaptor adaptor = new CursorToBulkCursorAdaptor(
+                                cursor, observer, getProviderName(), window);
+                        final IBinder binder = adaptor.asBinder();
+                        final int count = adaptor.count();
+                        final int index = BulkCursorToCursorAdaptor.findRowIdColumnIndex(
+                                adaptor.getColumnNames());
 
-                    IBulkCursor bulkCursor = bulkQuery(url, projection, selection,
-                            selectionArgs, sortOrder, observer, window);
-                    if (bulkCursor != null) {
-                        final IBinder binder = bulkCursor.asBinder();
-                        if (wantsCursorMetadata) {
-                            final int count = bulkCursor.count();
-                            final int index = BulkCursorToCursorAdaptor.findRowIdColumnIndex(
-                                    bulkCursor.getColumnNames());
-
-                            reply.writeNoException();
-                            reply.writeStrongBinder(binder);
-                            reply.writeInt(count);
-                            reply.writeInt(index);
-                        } else {
-                            reply.writeNoException();
-                            reply.writeStrongBinder(binder);
-                        }
+                        reply.writeNoException();
+                        reply.writeStrongBinder(binder);
+                        reply.writeInt(count);
+                        reply.writeInt(index);
                     } else {
                         reply.writeNoException();
                         reply.writeStrongBinder(null);
@@ -324,92 +322,70 @@
         return mRemote;
     }
 
-    // Like bulkQuery() but sets up provided 'adaptor' if not null.
-    private IBulkCursor bulkQueryInternal(
-        Uri url, String[] projection,
-        String selection, String[] selectionArgs, String sortOrder,
-        IContentObserver observer, CursorWindow window,
-        BulkCursorToCursorAdaptor adaptor) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        try {
-            data.writeInterfaceToken(IContentProvider.descriptor);
-
-            url.writeToParcel(data, 0);
-            int length = 0;
-            if (projection != null) {
-                length = projection.length;
-            }
-            data.writeInt(length);
-            for (int i = 0; i < length; i++) {
-                data.writeString(projection[i]);
-            }
-            data.writeString(selection);
-            if (selectionArgs != null) {
-                length = selectionArgs.length;
-            } else {
-                length = 0;
-            }
-            data.writeInt(length);
-            for (int i = 0; i < length; i++) {
-                data.writeString(selectionArgs[i]);
-            }
-            data.writeString(sortOrder);
-            data.writeStrongBinder(observer.asBinder());
-            window.writeToParcel(data, 0);
-
-            // Flag for whether or not we want the number of rows in the
-            // cursor and the position of the "_id" column index (or -1 if
-            // non-existent).  Only to be returned if binder != null.
-            final boolean wantsCursorMetadata = (adaptor != null);
-            data.writeInt(wantsCursorMetadata ? 1 : 0);
-
-            mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);
-
-            DatabaseUtils.readExceptionFromParcel(reply);
-
-            IBulkCursor bulkCursor = null;
-            IBinder bulkCursorBinder = reply.readStrongBinder();
-            if (bulkCursorBinder != null) {
-                bulkCursor = BulkCursorNative.asInterface(bulkCursorBinder);
-
-                if (wantsCursorMetadata) {
-                    int rowCount = reply.readInt();
-                    int idColumnPosition = reply.readInt();
-                    if (bulkCursor != null) {
-                        adaptor.set(bulkCursor, rowCount, idColumnPosition);
-                    }
-                }
-            }
-            return bulkCursor;
-        } finally {
-            data.recycle();
-            reply.recycle();
-        }
-    }
-
-    public IBulkCursor bulkQuery(Uri url, String[] projection,
-            String selection, String[] selectionArgs, String sortOrder, IContentObserver observer,
-            CursorWindow window) throws RemoteException {
-        return bulkQueryInternal(
-            url, projection, selection, selectionArgs, sortOrder,
-            observer, window,
-            null /* BulkCursorToCursorAdaptor */);
-    }
-
     public Cursor query(Uri url, String[] projection, String selection,
             String[] selectionArgs, String sortOrder) throws RemoteException {
-        //TODO make a pool of windows so we can reuse memory dealers
         CursorWindow window = new CursorWindow(false /* window will be used remotely */);
-        BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor();
-        IBulkCursor bulkCursor = bulkQueryInternal(
-            url, projection, selection, selectionArgs, sortOrder,
-            adaptor.getObserver(), window,
-            adaptor);
-        if (bulkCursor == null) {
-            return null;
+        try {
+            BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor();
+            Parcel data = Parcel.obtain();
+            Parcel reply = Parcel.obtain();
+            try {
+                data.writeInterfaceToken(IContentProvider.descriptor);
+
+                url.writeToParcel(data, 0);
+                int length = 0;
+                if (projection != null) {
+                    length = projection.length;
+                }
+                data.writeInt(length);
+                for (int i = 0; i < length; i++) {
+                    data.writeString(projection[i]);
+                }
+                data.writeString(selection);
+                if (selectionArgs != null) {
+                    length = selectionArgs.length;
+                } else {
+                    length = 0;
+                }
+                data.writeInt(length);
+                for (int i = 0; i < length; i++) {
+                    data.writeString(selectionArgs[i]);
+                }
+                data.writeString(sortOrder);
+                data.writeStrongBinder(adaptor.getObserver().asBinder());
+                window.writeToParcel(data, 0);
+
+                mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);
+
+                DatabaseUtils.readExceptionFromParcel(reply);
+
+                IBulkCursor bulkCursor = BulkCursorNative.asInterface(reply.readStrongBinder());
+                if (bulkCursor != null) {
+                    int rowCount = reply.readInt();
+                    int idColumnPosition = reply.readInt();
+                    adaptor.initialize(bulkCursor, rowCount, idColumnPosition);
+                } else {
+                    adaptor.close();
+                    adaptor = null;
+                }
+                return adaptor;
+            } catch (RemoteException ex) {
+                adaptor.close();
+                throw ex;
+            } catch (RuntimeException ex) {
+                adaptor.close();
+                throw ex;
+            } finally {
+                data.recycle();
+                reply.recycle();
+            }
+        } finally {
+            // We close the window now because the cursor adaptor does not
+            // take ownership of the window until the first call to onMove.
+            // The adaptor will obtain a fresh reference to the window when
+            // it is filled.
+            window.close();
         }
-        return adaptor;
     }
 
     public String getType(Uri url) throws RemoteException
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index 72bc9c2..2a67ff8 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -18,9 +18,6 @@
 
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -36,13 +33,6 @@
  * @hide
  */
 public interface IContentProvider extends IInterface {
-    /**
-     * @hide - hide this because return type IBulkCursor and parameter
-     * IContentObserver are system private classes.
-     */
-    public IBulkCursor bulkQuery(Uri url, String[] projection,
-            String selection, String[] selectionArgs, String sortOrder, IContentObserver observer,
-            CursorWindow window) throws RemoteException;
     public Cursor query(Uri url, String[] projection, String selection,
             String[] selectionArgs, String sortOrder) throws RemoteException;
     public String getType(Uri url) throws RemoteException;
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index a3bcc28..decb974 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -362,4 +362,6 @@
     void verifyPendingInstall(int id, int verificationCode);
 
     VerifierDeviceIdentity getVerifierDeviceIdentity();
+
+    boolean isFirstBoot();
 }
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index 3f23b89..ee6aec6 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -78,13 +78,11 @@
     }
 
     public void deactivate() {
-        deactivateInternal();
+        onDeactivateOrClose();
     }
 
-    /**
-     * @hide
-     */
-    public void deactivateInternal() {
+    /** @hide */
+    protected void onDeactivateOrClose() {
         if (mSelfObserver != null) {
             mContentResolver.unregisterContentObserver(mSelfObserver);
             mSelfObserverRegistered = false;
@@ -108,7 +106,7 @@
     public void close() {
         mClosed = true;
         mContentObservable.unregisterAll();
-        deactivateInternal();
+        onDeactivateOrClose();
     }
 
     /**
diff --git a/core/java/android/database/AbstractWindowedCursor.java b/core/java/android/database/AbstractWindowedCursor.java
index bfc8123..5836265 100644
--- a/core/java/android/database/AbstractWindowedCursor.java
+++ b/core/java/android/database/AbstractWindowedCursor.java
@@ -19,6 +19,11 @@
 /**
  * A base class for Cursors that store their data in {@link CursorWindow}s.
  * <p>
+ * The cursor owns the cursor window it uses.  When the cursor is closed,
+ * its window is also closed.  Likewise, when the window used by the cursor is
+ * changed, its old window is closed.  This policy of strict ownership ensures
+ * that cursor windows are not leaked.
+ * </p><p>
  * Subclasses are responsible for filling the cursor window with data during
  * {@link #onMove(int, int)}, allocating a new cursor window if necessary.
  * During {@link #requery()}, the existing cursor window should be cleared and
@@ -180,4 +185,25 @@
             mWindow = null;
         }
     }
+
+    /**
+     * If there is a window, clear it.
+     * Otherwise, creates a local window.
+     * @hide
+     */
+    protected void clearOrCreateLocalWindow() {
+        if (mWindow == null) {
+            // If there isn't a window set already it will only be accessed locally
+            mWindow = new CursorWindow(true /* the window is local only */);
+        } else {
+            mWindow.clear();
+        }
+    }
+
+    /** @hide */
+    @Override
+    protected void onDeactivateOrClose() {
+        super.onDeactivateOrClose();
+        closeWindow();
+    }
 }
diff --git a/core/java/android/database/BulkCursorNative.java b/core/java/android/database/BulkCursorNative.java
index 9925a9a..4fada8c 100644
--- a/core/java/android/database/BulkCursorNative.java
+++ b/core/java/android/database/BulkCursorNative.java
@@ -62,13 +62,13 @@
                     data.enforceInterface(IBulkCursor.descriptor);
                     int startPos = data.readInt();
                     CursorWindow window = getWindow(startPos);
+                    reply.writeNoException();
                     if (window == null) {
                         reply.writeInt(0);
-                        return true;
+                    } else {
+                        reply.writeInt(1);
+                        window.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                     }
-                    reply.writeNoException();
-                    reply.writeInt(1);
-                    window.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                     return true;
                 }
 
diff --git a/core/java/android/database/BulkCursorToCursorAdaptor.java b/core/java/android/database/BulkCursorToCursorAdaptor.java
index 9c1b26d..cbdd07fb 100644
--- a/core/java/android/database/BulkCursorToCursorAdaptor.java
+++ b/core/java/android/database/BulkCursorToCursorAdaptor.java
@@ -21,40 +21,24 @@
 import android.util.Log;
 
 /**
- * Adapts an {@link IBulkCursor} to a {@link Cursor} for use in the local
- * process.
+ * Adapts an {@link IBulkCursor} to a {@link Cursor} for use in the local process.
  *
  * {@hide}
  */
 public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor {
     private static final String TAG = "BulkCursor";
 
-    private SelfContentObserver mObserverBridge;
+    private SelfContentObserver mObserverBridge = new SelfContentObserver(this);
     private IBulkCursor mBulkCursor;
     private int mCount;
     private String[] mColumns;
     private boolean mWantsAllOnMoveCalls;
 
-    public void set(IBulkCursor bulkCursor) {
-        mBulkCursor = bulkCursor;
-
-        try {
-            mCount = mBulkCursor.count();
-            mWantsAllOnMoveCalls = mBulkCursor.getWantsAllOnMoveCalls();
-
-            // Search for the rowID column index and set it for our parent
-            mColumns = mBulkCursor.getColumnNames();
-            mRowIdColumnIndex = findRowIdColumnIndex(mColumns);
-        } catch (RemoteException ex) {
-            Log.e(TAG, "Setup failed because the remote process is dead");
-        }
-    }
-
     /**
-     * Version of set() that does fewer Binder calls if the caller
-     * already knows BulkCursorToCursorAdaptor's properties.
+     * Initializes the adaptor.
+     * Must be called before first use.
      */
-    public void set(IBulkCursor bulkCursor, int count, int idIndex) {
+    public void initialize(IBulkCursor bulkCursor, int count, int idIndex) {
         mBulkCursor = bulkCursor;
         mColumns = null;  // lazily retrieved
         mCount = count;
@@ -80,31 +64,37 @@
      *
      * @return A SelfContentObserver hooked up to this Cursor
      */
-    public synchronized IContentObserver getObserver() {
-        if (mObserverBridge == null) {
-            mObserverBridge = new SelfContentObserver(this);
-        }
+    public IContentObserver getObserver() {
         return mObserverBridge.getContentObserver();
     }
 
+    private void throwIfCursorIsClosed() {
+        if (mBulkCursor == null) {
+            throw new StaleDataException("Attempted to access a cursor after it has been closed.");
+        }
+    }
+
     @Override
     public int getCount() {
+        throwIfCursorIsClosed();
         return mCount;
     }
 
     @Override
     public boolean onMove(int oldPosition, int newPosition) {
+        throwIfCursorIsClosed();
+
         try {
             // Make sure we have the proper window
             if (mWindow != null) {
                 if (newPosition < mWindow.getStartPosition() ||
                         newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) {
-                    mWindow = mBulkCursor.getWindow(newPosition);
+                    setWindow(mBulkCursor.getWindow(newPosition));
                 } else if (mWantsAllOnMoveCalls) {
                     mBulkCursor.onMove(newPosition);
                 }
             } else {
-                mWindow = mBulkCursor.getWindow(newPosition);
+                setWindow(mBulkCursor.getWindow(newPosition));
             }
         } catch (RemoteException ex) {
             // We tried to get a window and failed
@@ -126,44 +116,54 @@
         // which is what actually makes the data set invalid.
         super.deactivate();
 
-        try {
-            mBulkCursor.deactivate();
-        } catch (RemoteException ex) {
-            Log.w(TAG, "Remote process exception when deactivating");
+        if (mBulkCursor != null) {
+            try {
+                mBulkCursor.deactivate();
+            } catch (RemoteException ex) {
+                Log.w(TAG, "Remote process exception when deactivating");
+            }
         }
-        mWindow = null;
     }
     
     @Override
     public void close() {
         super.close();
-        try {
-            mBulkCursor.close();
-        } catch (RemoteException ex) {
-            Log.w(TAG, "Remote process exception when closing");
+
+        if (mBulkCursor != null) {
+            try {
+                mBulkCursor.close();
+            } catch (RemoteException ex) {
+                Log.w(TAG, "Remote process exception when closing");
+            } finally {
+                mBulkCursor = null;
+            }
         }
-        mWindow = null;        
     }
 
     @Override
     public boolean requery() {
-        try {
-            int oldCount = mCount;
-            //TODO get the window from a pool somewhere to avoid creating the memory dealer
-            mCount = mBulkCursor.requery(getObserver(), new CursorWindow(
-                    false /* the window will be accessed across processes */));
-            if (mCount != -1) {
-                mPos = -1;
-                closeWindow();
+        throwIfCursorIsClosed();
 
-                // super.requery() will call onChanged. Do it here instead of relying on the
-                // observer from the far side so that observers can see a correct value for mCount
-                // when responding to onChanged.
-                super.requery();
-                return true;
-            } else {
-                deactivate();
-                return false;
+        try {
+            CursorWindow newWindow = new CursorWindow(false /* create a remote window */);
+            try {
+                mCount = mBulkCursor.requery(getObserver(), newWindow);
+                if (mCount != -1) {
+                    mPos = -1;
+                    closeWindow();
+
+                    // super.requery() will call onChanged. Do it here instead of relying on the
+                    // observer from the far side so that observers can see a correct value for mCount
+                    // when responding to onChanged.
+                    super.requery();
+                    return true;
+                } else {
+                    deactivate();
+                    return false;
+                }
+            } finally {
+                // Don't take ownership of the window until the next call to onMove.
+                newWindow.close();
             }
         } catch (Exception ex) {
             Log.e(TAG, "Unable to requery because the remote process exception " + ex.getMessage());
@@ -174,6 +174,8 @@
 
     @Override
     public String[] getColumnNames() {
+        throwIfCursorIsClosed();
+
         if (mColumns == null) {
             try {
                 mColumns = mBulkCursor.getColumnNames();
@@ -187,6 +189,8 @@
 
     @Override
     public Bundle getExtras() {
+        throwIfCursorIsClosed();
+
         try {
             return mBulkCursor.getExtras();
         } catch (RemoteException e) {
@@ -198,6 +202,8 @@
 
     @Override
     public Bundle respond(Bundle extras) {
+        throwIfCursorIsClosed();
+
         try {
             return mBulkCursor.respond(extras);
         } catch (RemoteException e) {
diff --git a/core/java/android/database/CrossProcessCursor.java b/core/java/android/database/CrossProcessCursor.java
index 77ba3a5..8e6a5aa 100644
--- a/core/java/android/database/CrossProcessCursor.java
+++ b/core/java/android/database/CrossProcessCursor.java
@@ -16,7 +16,7 @@
 
 package android.database;
 
-public interface CrossProcessCursor extends Cursor{
+public interface CrossProcessCursor extends Cursor {
     /**
      * returns a pre-filled window, return NULL if no such window
      */
diff --git a/core/java/android/database/CursorToBulkCursorAdaptor.java b/core/java/android/database/CursorToBulkCursorAdaptor.java
index 8fa4d3b..a65b3b3 100644
--- a/core/java/android/database/CursorToBulkCursorAdaptor.java
+++ b/core/java/android/database/CursorToBulkCursorAdaptor.java
@@ -24,19 +24,37 @@
 
 /**
  * Wraps a BulkCursor around an existing Cursor making it remotable.
+ * <p>
+ * If the wrapped cursor is a {@link AbstractWindowedCursor} then it owns
+ * the cursor window.  Otherwise, the adaptor takes ownership of the
+ * cursor itself and ensures it gets closed as needed during deactivation
+ * and requeries.
+ * </p>
  *
  * {@hide}
  */
 public final class CursorToBulkCursorAdaptor extends BulkCursorNative 
         implements IBinder.DeathRecipient {
     private static final String TAG = "Cursor";
-    private final CrossProcessCursor mCursor;
-    private CursorWindow mWindow;
+
+    private final Object mLock = new Object();
     private final String mProviderName;
     private ContentObserverProxy mObserver;
 
-    private static final class ContentObserverProxy extends ContentObserver 
-            {
+    /**
+     * The cursor that is being adapted.
+     * This field is set to null when the cursor is closed.
+     */
+    private CrossProcessCursor mCursor;
+
+    /**
+     * The cursor window used by the cross process cursor.
+     * This field is always null for abstract windowed cursors since they are responsible
+     * for managing the lifetime of their window.
+     */
+    private CursorWindow mWindowForNonWindowedCursor;
+
+    private static final class ContentObserverProxy extends ContentObserver {
         protected IContentObserver mRemote;
 
         public ContentObserverProxy(IContentObserver remoteObserver, DeathRecipient recipient) {
@@ -70,7 +88,7 @@
     }
 
     public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName,
-            boolean allowWrite, CursorWindow window) {
+            CursorWindow window) {
         try {
             mCursor = (CrossProcessCursor) cursor;
             if (mCursor instanceof AbstractWindowedCursor) {
@@ -81,90 +99,167 @@
                                 + providerName, new RuntimeException());
                     }
                 }
-                windowedCursor.setWindow(window);
+                windowedCursor.setWindow(window); // cursor takes ownership of window
             } else {
-                mWindow = window;
+                mWindowForNonWindowedCursor = window; // we own the window
                 mCursor.fillWindow(0, window);
             }
         } catch (ClassCastException e) {
             // TODO Implement this case.
+            window.close();
             throw new UnsupportedOperationException(
                     "Only CrossProcessCursor cursors are supported across process for now", e);
         }
         mProviderName = providerName;
 
-        createAndRegisterObserverProxy(observer);
+        synchronized (mLock) {
+            createAndRegisterObserverProxyLocked(observer);
+        }
     }
-    
+
+    private void closeCursorAndWindowLocked() {
+        if (mCursor != null) {
+            unregisterObserverProxyLocked();
+            mCursor.close();
+            mCursor = null;
+        }
+
+        if (mWindowForNonWindowedCursor != null) {
+            mWindowForNonWindowedCursor.close();
+            mWindowForNonWindowedCursor = null;
+        }
+    }
+
+    private void throwIfCursorIsClosed() {
+        if (mCursor == null) {
+            throw new StaleDataException("Attempted to access a cursor after it has been closed.");
+        }
+    }
+
+    @Override
     public void binderDied() {
-        mCursor.close();
-        if (mWindow != null) {
-            mWindow.close();
+        synchronized (mLock) {
+            closeCursorAndWindowLocked();
         }
     }
-    
+
+    @Override
     public CursorWindow getWindow(int startPos) {
-        mCursor.moveToPosition(startPos);
-        
-        if (mWindow != null) {
-            if (startPos < mWindow.getStartPosition() ||
-                    startPos >= (mWindow.getStartPosition() + mWindow.getNumRows())) {
-                mCursor.fillWindow(startPos, mWindow);
-            }            
-            return mWindow;
-        } else {
-            return ((AbstractWindowedCursor)mCursor).getWindow();
-        }
-    }
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
 
-    public void onMove(int position) {
-        mCursor.onMove(mCursor.getPosition(), position);
-    }
+            mCursor.moveToPosition(startPos);
 
-    public int count() {
-        return mCursor.getCount();
-    }
-
-    public String[] getColumnNames() {
-        return mCursor.getColumnNames();
-    }
-
-    public void deactivate() {
-        maybeUnregisterObserverProxy();
-        mCursor.deactivate();
-    }
-
-    public void close() {
-        maybeUnregisterObserverProxy();
-        mCursor.close();
-    }
-
-    public int requery(IContentObserver observer, CursorWindow window) {
-        if (mWindow == null) {
-            ((AbstractWindowedCursor)mCursor).setWindow(window);
-        }
-        try {
-            if (!mCursor.requery()) {
-                return -1;
+            final CursorWindow window;
+            if (mCursor instanceof AbstractWindowedCursor) {
+                window = ((AbstractWindowedCursor)mCursor).getWindow();
+            } else {
+                window = mWindowForNonWindowedCursor;
+                if (window != null
+                        && (startPos < window.getStartPosition() ||
+                                startPos >= (window.getStartPosition() + window.getNumRows()))) {
+                    mCursor.fillWindow(startPos, window);
+                }
             }
-        } catch (IllegalStateException e) {
-            IllegalStateException leakProgram = new IllegalStateException(
-                    mProviderName + " Requery misuse db, mCursor isClosed:" +
-                    mCursor.isClosed(), e);
-            throw leakProgram;
+
+            // Acquire a reference before returning from this RPC.
+            // The Binder proxy will decrement the reference count again as part of writing
+            // the CursorWindow to the reply parcel as a return value.
+            if (window != null) {
+                window.acquireReference();
+            }
+            return window;
         }
-        
-        if (mWindow != null) {
-            mCursor.fillWindow(0, window);
-            mWindow = window;
-        }
-        maybeUnregisterObserverProxy();
-        createAndRegisterObserverProxy(observer);
-        return mCursor.getCount();
     }
 
+    @Override
+    public void onMove(int position) {
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            mCursor.onMove(mCursor.getPosition(), position);
+        }
+    }
+
+    @Override
+    public int count() {
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            return mCursor.getCount();
+        }
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            return mCursor.getColumnNames();
+        }
+    }
+
+    @Override
+    public void deactivate() {
+        synchronized (mLock) {
+            if (mCursor != null) {
+                unregisterObserverProxyLocked();
+                mCursor.deactivate();
+            }
+        }
+    }
+
+    @Override
+    public void close() {
+        synchronized (mLock) {
+            closeCursorAndWindowLocked();
+        }
+    }
+
+    @Override
+    public int requery(IContentObserver observer, CursorWindow window) {
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            if (mCursor instanceof AbstractWindowedCursor) {
+                ((AbstractWindowedCursor) mCursor).setWindow(window);
+            } else {
+                if (mWindowForNonWindowedCursor != null) {
+                    mWindowForNonWindowedCursor.close();
+                }
+                mWindowForNonWindowedCursor = window;
+            }
+
+            try {
+                if (!mCursor.requery()) {
+                    return -1;
+                }
+            } catch (IllegalStateException e) {
+                IllegalStateException leakProgram = new IllegalStateException(
+                        mProviderName + " Requery misuse db, mCursor isClosed:" +
+                        mCursor.isClosed(), e);
+                throw leakProgram;
+            }
+
+            if (!(mCursor instanceof AbstractWindowedCursor)) {
+                if (window != null) {
+                    mCursor.fillWindow(0, window);
+                }
+            }
+
+            unregisterObserverProxyLocked();
+            createAndRegisterObserverProxyLocked(observer);
+            return mCursor.getCount();
+        }
+    }
+
+    @Override
     public boolean getWantsAllOnMoveCalls() {
-        return mCursor.getWantsAllOnMoveCalls();
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            return mCursor.getWantsAllOnMoveCalls();
+        }
     }
 
     /**
@@ -173,7 +268,7 @@
      * @param observer the IContentObserver that wants to monitor the cursor
      * @throws IllegalStateException if an observer is already registered
      */
-    private void createAndRegisterObserverProxy(IContentObserver observer) {
+    private void createAndRegisterObserverProxyLocked(IContentObserver observer) {
         if (mObserver != null) {
             throw new IllegalStateException("an observer is already registered");
         }
@@ -182,7 +277,7 @@
     }
 
     /** Unregister the observer if it is already registered. */
-    private void maybeUnregisterObserverProxy() {
+    private void unregisterObserverProxyLocked() {
         if (mObserver != null) {
             mCursor.unregisterContentObserver(mObserver);
             mObserver.unlinkToDeath(this);
@@ -190,11 +285,21 @@
         }
     }
 
+    @Override
     public Bundle getExtras() {
-        return mCursor.getExtras();
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            return mCursor.getExtras();
+        }
     }
 
+    @Override
     public Bundle respond(Bundle extras) {
-        return mCursor.respond(extras);
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            return mCursor.respond(extras);
+        }
     }
 }
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index 2e3ef28..5a91b80 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -16,6 +16,8 @@
 
 package android.database;
 
+import dalvik.system.CloseGuard;
+
 import android.content.res.Resources;
 import android.database.sqlite.SQLiteClosable;
 import android.database.sqlite.SQLiteException;
@@ -48,6 +50,8 @@
 
     private int mStartPos;
 
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
     private static native int nativeInitializeEmpty(int cursorWindowSize, boolean localOnly);
     private static native int nativeInitializeFromBinder(IBinder nativeBinder);
     private static native void nativeDispose(int windowPtr);
@@ -91,6 +95,7 @@
             throw new CursorWindowAllocationException("Cursor window allocation of " +
                     (sCursorWindowSize / 1024) + " kb failed. " + printStats());
         }
+        mCloseGuard.open("close");
         recordNewWindow(Binder.getCallingPid(), mWindowPtr);
     }
 
@@ -102,11 +107,15 @@
             throw new CursorWindowAllocationException("Cursor window could not be "
                     + "created from binder.");
         }
+        mCloseGuard.open("close");
     }
 
     @Override
     protected void finalize() throws Throwable {
         try {
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
             dispose();
         } finally {
             super.finalize();
@@ -114,6 +123,9 @@
     }
 
     private void dispose() {
+        if (mCloseGuard != null) {
+            mCloseGuard.close();
+        }
         if (mWindowPtr != 0) {
             recordClosingOfWindow(mWindowPtr);
             nativeDispose(mWindowPtr);
@@ -677,6 +689,10 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeStrongBinder(nativeGetBinder(mWindowPtr));
         dest.writeInt(mStartPos);
+
+        if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
+            releaseReference();
+        }
     }
 
     @Override
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java
index 81fe824..9d7e152 100644
--- a/core/java/android/database/sqlite/SQLiteCursor.java
+++ b/core/java/android/database/sqlite/SQLiteCursor.java
@@ -89,8 +89,6 @@
      * @param query the {@link SQLiteQuery} object associated with this cursor object.
      */
     public SQLiteCursor(SQLiteCursorDriver driver, String editTable, SQLiteQuery query) {
-        // The AbstractCursor constructor needs to do some setup.
-        super();
         if (query == null) {
             throw new IllegalArgumentException("query object cannot be null");
         }
@@ -157,12 +155,7 @@
     }
 
     private void fillWindow(int startPos) {
-        if (mWindow == null) {
-            // If there isn't a window set already it will only be accessed locally
-            mWindow = new CursorWindow(true /* the window is local only */);
-        } else {
-            mWindow.clear();
-        }
+        clearOrCreateLocalWindow();
         mWindow.setStartPosition(startPos);
         int count = getQuery().fillWindow(mWindow);
         if (startPos == 0) { // fillWindow returns count(*) only for startPos = 0
@@ -214,16 +207,9 @@
         return mColumns;
     }
 
-    private void deactivateCommon() {
-        if (false) Log.v(TAG, "<<< Releasing cursor " + this);
-        closeWindow();
-        if (false) Log.v("DatabaseWindow", "closing window in release()");
-    }
-
     @Override
     public void deactivate() {
         super.deactivate();
-        deactivateCommon();
         mDriver.cursorDeactivated();
     }
 
@@ -231,7 +217,6 @@
     public void close() {
         super.close();
         synchronized (this) {
-            deactivateCommon();
             mQuery.close();
             mDriver.cursorClosed();
         }
diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java
index aaad8a1..1b24f0c 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -40,6 +40,8 @@
     public long limitBytes;
     public long lastSnooze;
 
+    private static final long DEFAULT_MTU = 1500;
+
     public NetworkPolicy(NetworkTemplate template, int cycleDay, long warningBytes, long limitBytes,
             long lastSnooze) {
         this.template = checkNotNull(template, "missing NetworkTemplate");
@@ -71,6 +73,17 @@
         return 0;
     }
 
+    /**
+     * Test if given measurement is near enough to {@link #limitBytes} to be
+     * considered over-limit.
+     */
+    public boolean isOverLimit(long totalBytes) {
+        // over-estimate, since kernel will trigger limit once first packet
+        // trips over limit.
+        totalBytes += 2 * DEFAULT_MTU;
+        return limitBytes != LIMIT_DISABLED && totalBytes >= limitBytes;
+    }
+
     /** {@inheritDoc} */
     public int compareTo(NetworkPolicy another) {
         if (another == null || another.limitBytes == LIMIT_DISABLED) {
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index d57132a..1697382 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -502,9 +502,23 @@
      * @see #isAvailable() 
      * @see #getBitmap(int, int)  
      * @see #getBitmap() 
+     * 
+     * @throws IllegalStateException if the hardware rendering context cannot be
+     *         acquired to capture the bitmap
      */
     public Bitmap getBitmap(Bitmap bitmap) {
         if (bitmap != null && isAvailable()) {
+            AttachInfo info = mAttachInfo;
+            if (info != null && info.mHardwareRenderer != null &&
+                    info.mHardwareRenderer.isEnabled()) {
+                if (!info.mHardwareRenderer.validate()) {
+                    throw new IllegalStateException("Could not acquire hardware rendering context");
+                }
+            }
+
+            applyUpdate();
+            applyTransformMatrix();
+
             mLayer.copyInto(bitmap);
         }
         return bitmap;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 15544cc..86be28a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1486,7 +1486,8 @@
             | AccessibilityEvent.TYPE_VIEW_FOCUSED
             | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
             | AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
-            | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT;
+            | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT
+            | AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED;
 
     /**
      * Temporary Rect currently for use in setBackground().  This will probably
@@ -10125,6 +10126,14 @@
         return mHardwareLayer;
     }
 
+    /**
+     * Destroys this View's hardware layer if possible.
+     * 
+     * @return True if the layer was destroyed, false otherwise.
+     * 
+     * @see #setLayerType(int, android.graphics.Paint) 
+     * @see #LAYER_TYPE_HARDWARE
+     */
     boolean destroyLayer() {
         if (mHardwareLayer != null) {
             mHardwareLayer.destroy();
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 25bc559..86dd9df 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -200,15 +200,6 @@
  *   <li>{@link #getBeforeText()} - The text of the source before the change.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
  * </ul>
- * <em>Note:</em> This event type is not dispatched to descendants though
- * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
- * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
- * source {@link android.view.View} and the sub-tree rooted at it will not receive
- * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
- * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
- * text content to such events is by setting the
- * {@link android.R.styleable#View_contentDescription contentDescription} of the source
- * view.</br>
  * </p>
  * <p>
  * <b>View text selection changed</b> - represents the event of changing the text
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index f46af51..6d19c23 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2074,7 +2074,8 @@
      * If the value of the encoding parameter is 'base64', then the data must
      * be encoded as base64. Otherwise, the data must use ASCII encoding for
      * octets inside the range of safe URL characters and use the standard %xx
-     * hex encoding of URLs for octets outside that range.
+     * hex encoding of URLs for octets outside that range. For example,
+     * '#', '%', '\', '?' should be replaced by %23, %25, %27, %3f respectively.
      * <p>
      * The 'data' scheme URL formed by this method uses the default US-ASCII
      * charset. If you need need to set a different charset, you should form a
@@ -7415,6 +7416,10 @@
         }
     }
 
+    void sendPluginDrawMsg() {
+        mWebViewCore.sendMessage(EventHub.PLUGIN_SURFACE_READY);
+    }
+
     /**
      * Returns plugin bounds if x/y in content coordinates corresponds to a
      * plugin. Otherwise a NULL rectangle is returned.
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 44688b8..1294a28 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1032,6 +1032,8 @@
 
         static final int EXECUTE_JS = 194;
 
+        static final int PLUGIN_SURFACE_READY = 195;
+
         // private message ids
         private static final int DESTROY =     200;
 
@@ -1587,6 +1589,10 @@
                             nativeFullScreenPluginHidden(msg.arg1);
                             break;
 
+                        case PLUGIN_SURFACE_READY:
+                            nativePluginSurfaceReady();
+                            break;
+
                         case ADD_PACKAGE_NAMES:
                             if (BrowserFrame.sJavaBridge == null) {
                                 throw new IllegalStateException("No WebView " +
@@ -2826,6 +2832,7 @@
     private native void nativeResume();
     private native void nativeFreeMemory();
     private native void nativeFullScreenPluginHidden(int npp);
+    private native void nativePluginSurfaceReady();
     private native boolean nativeValidNodeAndBounds(int frame, int node,
             Rect bounds);
 
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index 62b078f..510e2d4 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -44,7 +44,6 @@
     private final static int MAX_SPELL_BATCH_SIZE = 50;
 
     private final TextView mTextView;
-    private final Editable mText;
 
     final SpellCheckerSession mSpellCheckerSession;
     final int mCookie;
@@ -64,7 +63,6 @@
 
     public SpellChecker(TextView textView) {
         mTextView = textView;
-        mText = (Editable) textView.getText();
 
         final TextServicesManager textServicesManager = (TextServicesManager) textView.getContext().
                 getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE);
@@ -121,9 +119,9 @@
         return mLength - 1;
     }
 
-    private void addSpellCheckSpan(int start, int end) {
+    private void addSpellCheckSpan(Editable editable, int start, int end) {
         final int index = nextSpellCheckSpanIndex();
-        mText.setSpan(mSpellCheckSpans[index], start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        editable.setSpan(mSpellCheckSpans[index], start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
         mIds[index] = mSpanSequenceCounter++;
     }
 
@@ -168,8 +166,9 @@
     private void spellCheck() {
         if (mSpellCheckerSession == null) return;
 
-        final int selectionStart = Selection.getSelectionStart(mText);
-        final int selectionEnd = Selection.getSelectionEnd(mText);
+        Editable editable = (Editable) mTextView.getText();
+        final int selectionStart = Selection.getSelectionStart(editable);
+        final int selectionEnd = Selection.getSelectionEnd(editable);
 
         TextInfo[] textInfos = new TextInfo[mLength];
         int textInfosCount = 0;
@@ -178,12 +177,12 @@
             final SpellCheckSpan spellCheckSpan = mSpellCheckSpans[i];
             if (spellCheckSpan.isSpellCheckInProgress()) continue;
 
-            final int start = mText.getSpanStart(spellCheckSpan);
-            final int end = mText.getSpanEnd(spellCheckSpan);
+            final int start = editable.getSpanStart(spellCheckSpan);
+            final int end = editable.getSpanEnd(spellCheckSpan);
 
             // Do not check this word if the user is currently editing it
             if (start >= 0 && end > start && (selectionEnd < start || selectionStart > end)) {
-                final String word = mText.subSequence(start, end).toString();
+                final String word = editable.subSequence(start, end).toString();
                 spellCheckSpan.setSpellCheckInProgress(true);
                 textInfos[textInfosCount++] = new TextInfo(word, mCookie, mIds[i]);
             }
@@ -202,6 +201,8 @@
 
     @Override
     public void onGetSuggestions(SuggestionsInfo[] results) {
+        Editable editable = (Editable) mTextView.getText();
+
         for (int i = 0; i < results.length; i++) {
             SuggestionsInfo suggestionsInfo = results[i];
             if (suggestionsInfo.getCookie() != mCookie) continue;
@@ -217,9 +218,9 @@
 
                     SpellCheckSpan spellCheckSpan = mSpellCheckSpans[j];
                     if (!isInDictionary && looksLikeTypo) {
-                        createMisspelledSuggestionSpan(suggestionsInfo, spellCheckSpan);
+                        createMisspelledSuggestionSpan(editable, suggestionsInfo, spellCheckSpan);
                     }
-                    mText.removeSpan(spellCheckSpan);
+                    editable.removeSpan(spellCheckSpan);
                     break;
                 }
             }
@@ -234,18 +235,18 @@
         }
     }
 
-    private void createMisspelledSuggestionSpan(SuggestionsInfo suggestionsInfo,
-            SpellCheckSpan spellCheckSpan) {
-        final int start = mText.getSpanStart(spellCheckSpan);
-        final int end = mText.getSpanEnd(spellCheckSpan);
+    private void createMisspelledSuggestionSpan(Editable editable,
+            SuggestionsInfo suggestionsInfo, SpellCheckSpan spellCheckSpan) {
+        final int start = editable.getSpanStart(spellCheckSpan);
+        final int end = editable.getSpanEnd(spellCheckSpan);
 
         // Other suggestion spans may exist on that region, with identical suggestions, filter
         // them out to avoid duplicates. First, filter suggestion spans on that exact region.
-        SuggestionSpan[] suggestionSpans = mText.getSpans(start, end, SuggestionSpan.class);
+        SuggestionSpan[] suggestionSpans = editable.getSpans(start, end, SuggestionSpan.class);
         final int length = suggestionSpans.length;
         for (int i = 0; i < length; i++) {
-            final int spanStart = mText.getSpanStart(suggestionSpans[i]);
-            final int spanEnd = mText.getSpanEnd(suggestionSpans[i]);
+            final int spanStart = editable.getSpanStart(suggestionSpans[i]);
+            final int spanEnd = editable.getSpanEnd(suggestionSpans[i]);
             if (spanStart != start || spanEnd != end) {
                 suggestionSpans[i] = null;
                 break;
@@ -293,7 +294,7 @@
 
         SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions,
                 SuggestionSpan.FLAG_EASY_CORRECT | SuggestionSpan.FLAG_MISSPELLED);
-        mText.setSpan(suggestionSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        editable.setSpan(suggestionSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
         // TODO limit to the word rectangle region
         mTextView.invalidate();
@@ -304,22 +305,24 @@
         private Object mRange = new Object();
 
         public void init(int start, int end) {
-            mText.setSpan(mRange, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+            ((Editable) mTextView.getText()).setSpan(mRange, start, end,
+                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
         }
 
         public void close() {
-            mText.removeSpan(mRange);
+            ((Editable) mTextView.getText()).removeSpan(mRange);
         }
 
         public boolean isDone() {
-            return mText.getSpanStart(mRange) < 0;
+            return ((Editable) mTextView.getText()).getSpanStart(mRange) < 0;
         }
 
         public void parse() {
+            Editable editable = (Editable) mTextView.getText();
             // Iterate over the newly added text and schedule new SpellCheckSpans
-            final int start = mText.getSpanStart(mRange);
-            final int end = mText.getSpanEnd(mRange);
-            mWordIterator.setCharSequence(mText, start, end);
+            final int start = editable.getSpanStart(mRange);
+            final int end = editable.getSpanEnd(mRange);
+            mWordIterator.setCharSequence(editable, start, end);
 
             // Move back to the beginning of the current word, if any
             int wordStart = mWordIterator.preceding(start);
@@ -333,14 +336,16 @@
                 wordEnd = mWordIterator.getEnd(wordStart);
             }
             if (wordEnd == BreakIterator.DONE) {
-                mText.removeSpan(mRange);
+                editable.removeSpan(mRange);
                 return;
             }
 
             // We need to expand by one character because we want to include the spans that
             // end/start at position start/end respectively.
-            SpellCheckSpan[] spellCheckSpans = mText.getSpans(start-1, end+1, SpellCheckSpan.class);
-            SuggestionSpan[] suggestionSpans = mText.getSpans(start-1, end+1, SuggestionSpan.class);
+            SpellCheckSpan[] spellCheckSpans = editable.getSpans(start - 1, end + 1,
+                    SpellCheckSpan.class);
+            SuggestionSpan[] suggestionSpans = editable.getSpans(start - 1, end + 1,
+                    SuggestionSpan.class);
 
             int nbWordsChecked = 0;
             boolean scheduleOtherSpellCheck = false;
@@ -350,20 +355,20 @@
                     // A new word has been created across the interval boundaries with this edit.
                     // Previous spans (ended on start / started on end) removed, not valid anymore
                     if (wordStart < start && wordEnd > start) {
-                        removeSpansAt(start, spellCheckSpans);
-                        removeSpansAt(start, suggestionSpans);
+                        removeSpansAt(editable, start, spellCheckSpans);
+                        removeSpansAt(editable, start, suggestionSpans);
                     }
 
                     if (wordStart < end && wordEnd > end) {
-                        removeSpansAt(end, spellCheckSpans);
-                        removeSpansAt(end, suggestionSpans);
+                        removeSpansAt(editable, end, spellCheckSpans);
+                        removeSpansAt(editable, end, suggestionSpans);
                     }
 
                     // Do not create new boundary spans if they already exist
                     boolean createSpellCheckSpan = true;
                     if (wordEnd == start) {
                         for (int i = 0; i < spellCheckSpans.length; i++) {
-                            final int spanEnd = mText.getSpanEnd(spellCheckSpans[i]);
+                            final int spanEnd = editable.getSpanEnd(spellCheckSpans[i]);
                             if (spanEnd == start) {
                                 createSpellCheckSpan = false;
                                 break;
@@ -373,7 +378,7 @@
 
                     if (wordStart == end) {
                         for (int i = 0; i < spellCheckSpans.length; i++) {
-                            final int spanStart = mText.getSpanStart(spellCheckSpans[i]);
+                            final int spanStart = editable.getSpanStart(spellCheckSpans[i]);
                             if (spanStart == end) {
                                 createSpellCheckSpan = false;
                                 break;
@@ -386,7 +391,7 @@
                             scheduleOtherSpellCheck = true;
                             break;
                         }
-                        addSpellCheckSpan(wordStart, wordEnd);
+                        addSpellCheckSpan(editable, wordStart, wordEnd);
                         nbWordsChecked++;
                     }
                 }
@@ -401,23 +406,23 @@
             }
 
             if (scheduleOtherSpellCheck) {
-                mText.setSpan(mRange, wordStart, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+                editable.setSpan(mRange, wordStart, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
             } else {
-                mText.removeSpan(mRange);
+                editable.removeSpan(mRange);
             }
 
             spellCheck();
         }
 
-        private <T> void removeSpansAt(int offset, T[] spans) {
+        private <T> void removeSpansAt(Editable editable, int offset, T[] spans) {
             final int length = spans.length;
             for (int i = 0; i < length; i++) {
                 final T span = spans[i];
-                final int start = mText.getSpanStart(span);
+                final int start = editable.getSpanStart(span);
                 if (start > offset) continue;
-                final int end = mText.getSpanEnd(span);
+                final int end = editable.getSpanEnd(span);
                 if (end < offset) continue;
-                mText.removeSpan(span);
+                editable.removeSpan(span);
             }
         }
     }
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index daabf42..77d0c97 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -109,7 +109,6 @@
         if (confirm) {
             final CloseDialogReceiver closer = new CloseDialogReceiver(context);
             final AlertDialog dialog = new AlertDialog.Builder(context)
-                    .setIconAttribute(android.R.attr.alertDialogIcon)
                     .setTitle(com.android.internal.R.string.power_off)
                     .setMessage(resourceId)
                     .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 97bbe52..5b49bff 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -17,8 +17,6 @@
 package com.android.internal.widget;
 
 
-import com.android.internal.R;
-
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -39,6 +37,10 @@
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+
+import com.android.internal.R;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -401,6 +403,34 @@
         invalidate();
     }
 
+    private void notifyCellAdded() {
+        if (mOnPatternListener != null) {
+            mOnPatternListener.onPatternCellAdded(mPattern);
+        }
+        sendAccessEvent(R.string.lockscreen_access_pattern_cell_added);
+    }
+
+    private void notifyPatternStarted() {
+        if (mOnPatternListener != null) {
+            mOnPatternListener.onPatternStart();
+        }
+        sendAccessEvent(R.string.lockscreen_access_pattern_start);
+    }
+
+    private void notifyPatternDetected() {
+        if (mOnPatternListener != null) {
+            mOnPatternListener.onPatternDetected(mPattern);
+        }
+        sendAccessEvent(R.string.lockscreen_access_pattern_detected);
+    }
+
+    private void notifyPatternCleared() {
+        if (mOnPatternListener != null) {
+            mOnPatternListener.onPatternCleared();
+        }
+        sendAccessEvent(R.string.lockscreen_access_pattern_cleared);
+    }
+
     /**
      * Clear the pattern.
      */
@@ -554,9 +584,7 @@
     private void addCellToPattern(Cell newCell) {
         mPatternDrawLookup[newCell.getRow()][newCell.getColumn()] = true;
         mPattern.add(newCell);
-        if (mOnPatternListener != null) {
-            mOnPatternListener.onPatternCellAdded(mPattern);
-        }
+        notifyCellAdded();
     }
 
     // helper method to find which cell a point maps to
@@ -619,6 +647,27 @@
     }
 
     @Override
+    public boolean onHoverEvent(MotionEvent event) {
+        if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) {
+            final int action = event.getAction();
+            switch (action) {
+                case MotionEvent.ACTION_HOVER_ENTER:
+                    event.setAction(MotionEvent.ACTION_DOWN);
+                    break;
+                case MotionEvent.ACTION_HOVER_MOVE:
+                    event.setAction(MotionEvent.ACTION_MOVE);
+                    break;
+                case MotionEvent.ACTION_HOVER_EXIT:
+                    event.setAction(MotionEvent.ACTION_UP);
+                    break;
+            }
+            onTouchEvent(event);
+            event.setAction(action);
+        }
+        return super.onHoverEvent(event);
+    }
+
+    @Override
     public boolean onTouchEvent(MotionEvent event) {
         if (!mInputEnabled || !isEnabled()) {
             return false;
@@ -636,10 +685,8 @@
                 return true;
             case MotionEvent.ACTION_CANCEL:
                 resetPattern();
-                if (mOnPatternListener != null) {
-                    mPatternInProgress = false;
-                    mOnPatternListener.onPatternCleared();
-                }
+                mPatternInProgress = false;
+                notifyPatternCleared();
                 if (PROFILE_DRAWING) {
                     if (mDrawingProfilingStarted) {
                         Debug.stopMethodTracing();
@@ -661,9 +708,9 @@
             final int patternSizePreHitDetect = mPattern.size();
             Cell hitCell = detectAndAddHit(x, y);
             final int patternSize = mPattern.size();
-            if (hitCell != null && (mOnPatternListener != null) && (patternSize == 1)) {
+            if (hitCell != null && patternSize == 1) {
                 mPatternInProgress = true;
-                mOnPatternListener.onPatternStart();
+                notifyPatternStarted();
             }
             // note current x and y for rubber banding of in progress patterns
             final float dx = Math.abs(x - mInProgressX);
@@ -778,11 +825,17 @@
         }
     }
 
+    private void sendAccessEvent(int resId) {
+        setContentDescription(mContext.getString(resId));
+        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+        setContentDescription(null);
+    }
+
     private void handleActionUp(MotionEvent event) {
         // report pattern detected
-        if (!mPattern.isEmpty() && mOnPatternListener != null) {
+        if (!mPattern.isEmpty()) {
             mPatternInProgress = false;
-            mOnPatternListener.onPatternDetected(mPattern);
+            notifyPatternDetected();
             invalidate();
         }
         if (PROFILE_DRAWING) {
@@ -798,13 +851,13 @@
         final float x = event.getX();
         final float y = event.getY();
         final Cell hitCell = detectAndAddHit(x, y);
-        if (hitCell != null && mOnPatternListener != null) {
+        if (hitCell != null) {
             mPatternInProgress = true;
             mPatternDisplayMode = DisplayMode.Correct;
-            mOnPatternListener.onPatternStart();
-        } else if (mOnPatternListener != null) {
+            notifyPatternStarted();
+        } else {
             mPatternInProgress = false;
-            mOnPatternListener.onPatternCleared();
+            notifyPatternCleared();
         }
         if (hitCell != null) {
             final float startX = getCenterXForColumn(hitCell.column);
diff --git a/core/java/com/android/internal/widget/TransportControlView.java b/core/java/com/android/internal/widget/TransportControlView.java
index 1042a59..73d9f10 100644
--- a/core/java/com/android/internal/widget/TransportControlView.java
+++ b/core/java/com/android/internal/widget/TransportControlView.java
@@ -336,20 +336,27 @@
         if (state == mPlayState) {
             return;
         }
+        final int imageResId;
+        final int imageDescId;
         switch (state) {
             case RemoteControlClient.PLAYSTATE_PLAYING:
-                mBtnPlay.setImageResource(com.android.internal.R.drawable.ic_media_pause);
+                imageResId = com.android.internal.R.drawable.ic_media_pause;
+                imageDescId = com.android.internal.R.string.lockscreen_transport_pause_description;
                 break;
 
             case RemoteControlClient.PLAYSTATE_BUFFERING:
-                mBtnPlay.setImageResource(com.android.internal.R.drawable.ic_media_stop);
+                imageResId = com.android.internal.R.drawable.ic_media_stop;
+                imageDescId = com.android.internal.R.string.lockscreen_transport_stop_description;
                 break;
 
             case RemoteControlClient.PLAYSTATE_PAUSED:
             default:
-                mBtnPlay.setImageResource(com.android.internal.R.drawable.ic_media_play);
+                imageResId = com.android.internal.R.drawable.ic_media_play;
+                imageDescId = com.android.internal.R.string.lockscreen_transport_play_description;
                 break;
         }
+        mBtnPlay.setImageResource(imageResId);
+        mBtnPlay.setContentDescription(getResources().getString(imageDescId));
         mPlayState = state;
     }
 
diff --git a/core/res/res/drawable-hdpi/stat_notify_disabled.png b/core/res/res/drawable-hdpi/stat_notify_disabled.png
new file mode 100644
index 0000000..5b5a7dc
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_notify_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_disabled.png b/core/res/res/drawable-mdpi/stat_notify_disabled.png
new file mode 100644
index 0000000..9661d31
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_notify_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_notify_disabled.png b/core/res/res/drawable-xhdpi/stat_notify_disabled.png
new file mode 100644
index 0000000..0a003af
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/stat_notify_disabled.png
Binary files differ
diff --git a/core/res/res/layout/keyguard_transport_control.xml b/core/res/res/layout/keyguard_transport_control.xml
index 2ebe5fc..6e24ce2 100644
--- a/core/res/res/layout/keyguard_transport_control.xml
+++ b/core/res/res/layout/keyguard_transport_control.xml
@@ -66,7 +66,8 @@
                     android:src="@drawable/ic_media_rew"
                     android:clickable="true"
                     android:background="?android:attr/selectableItemBackground"
-                    android:padding="10dip"/>
+                    android:padding="10dip"
+                    android:contentDescription="@string/lockscreen_transport_prev_description"/>
             </FrameLayout>
             <FrameLayout
                 android:layout_width="wrap_content"
@@ -80,7 +81,8 @@
                     android:clickable="true"
                     android:src="@drawable/ic_media_play"
                     android:background="?android:attr/selectableItemBackground"
-                    android:padding="10dip"/>
+                    android:padding="10dip"
+                    android:contentDescription="@string/lockscreen_transport_play_description"/>
             </FrameLayout>
             <FrameLayout
                 android:layout_width="wrap_content"
@@ -94,7 +96,8 @@
                     android:clickable="true"
                     android:src="@drawable/ic_media_ff"
                     android:background="?android:attr/selectableItemBackground"
-                    android:padding="10dip"/>
+                    android:padding="10dip"
+                    android:contentDescription="@string/lockscreen_transport_next_description"/>
             </FrameLayout>
         </LinearLayout>
     </LinearLayout>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b1dc252..fb4783b 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -953,7 +953,7 @@
         social updates from your friends. Malicious apps can use this to pretend to be a friend
         and trick you into revealing passwords or other confidential information.</string>
 
-    
+
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_readCalendar">read calendar events plus confidential information</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1831,6 +1831,17 @@
     <string name="lockscreen_permanent_disabled_sim_instructions">Your SIM card is permanently disabled.\n
     Please contact your wireless service provider to obtain another SIM card.</string>
 
+    <!-- Shown on transport control of lockscreen. Pressing button goes to previous track. -->
+    <string name="lockscreen_transport_prev_description">Previous track button</string>
+    <!-- Shown on transport control of lockscreen. Pressing button goes to next track. -->
+    <string name="lockscreen_transport_next_description">Next track button</string>
+    <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+    <string name="lockscreen_transport_pause_description">Pause button</string>
+    <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+    <string name="lockscreen_transport_play_description">Play button</string>
+    <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+    <string name="lockscreen_transport_stop_description">Stop button</string>
+
     <!-- Shown in the lock screen when there is emergency calls only mode. -->
     <string name="emergency_calls_only" msgid="2485604591272668370">Emergency calls only</string>
 
@@ -1958,6 +1969,15 @@
     <!-- Displayed on lock screen's right tab - turn sound off -->
     <string name="lockscreen_sound_off_label">Sound off</string>
 
+    <!-- Accessibility description sent when user starts drawing a lock pattern. [CHAR LIMIT=NONE] -->
+    <string name="lockscreen_access_pattern_start">Pattern started</string>
+    <!-- Accessibility description sent when the pattern times out and is cleared. [CHAR LIMIT=NONE] -->
+    <string name="lockscreen_access_pattern_cleared">Pattern cleared</string>
+    <!-- Accessibility description sent when user adds a cell to the pattern. [CHAR LIMIT=NONE]  -->
+    <string name="lockscreen_access_pattern_cell_added">Cell added</string>
+    <!-- Accessibility description sent when user completes drawing a pattern. [CHAR LIMIT=NONE] -->
+    <string name="lockscreen_access_pattern_detected">Pattern completed</string>
+
     <!-- Password keyboard strings. Used by LockScreen and Settings --><skip />
     <!-- Label for "switch to symbols" key.  Must be short to fit on key! -->
     <string name="password_keyboard_label_symbol_key">\?123</string>
diff --git a/data/sounds/AudioPackage7.mk b/data/sounds/AudioPackage7.mk
index 629ceb3..66edb7a 100755
--- a/data/sounds/AudioPackage7.mk
+++ b/data/sounds/AudioPackage7.mk
@@ -27,35 +27,33 @@
 	$(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
 	$(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
-	$(LOCAL_PATH)/notifications/ogg/Altair.ogg:system/media/audio/notifications/Altair.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
-	$(LOCAL_PATH)/notifications/ogg/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
 	$(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
-	$(LOCAL_PATH)/notifications/ogg/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
-	$(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
-	$(LOCAL_PATH)/ringtones/ogg/Acheron.ogg:system/media/audio/ringtones/Acheron.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \
-	$(LOCAL_PATH)/ringtones/ogg/Cassiopeia.ogg:system/media/audio/ringtones/Cassiopeia.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \
-	$(LOCAL_PATH)/ringtones/ogg/Nasqueron.ogg:system/media/audio/ringtones/Nasqueron.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:system/media/audio/ringtones/Perseus.ogg \
@@ -66,4 +64,4 @@
 	$(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Testudo.ogg:system/media/audio/ringtones/Testudo.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:system/media/audio/ringtones/UrsaMinor.ogg \
-	$(LOCAL_PATH)/ringtones/ogg/Vespa.ogg:system/media/audio/ringtones/Vespa.ogg
+	$(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg
diff --git a/data/sounds/effects/ogg/Lock.ogg b/data/sounds/effects/ogg/Lock.ogg
index ed845be..e7928e4 100644
--- a/data/sounds/effects/ogg/Lock.ogg
+++ b/data/sounds/effects/ogg/Lock.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/Unlock.ogg b/data/sounds/effects/ogg/Unlock.ogg
index 0a47b5c..cca9594 100644
--- a/data/sounds/effects/ogg/Unlock.ogg
+++ b/data/sounds/effects/ogg/Unlock.ogg
Binary files differ
diff --git a/data/sounds/effects/wav/Lock.wav b/data/sounds/effects/wav/Lock.wav
index 1655a89..b8076369 100644
--- a/data/sounds/effects/wav/Lock.wav
+++ b/data/sounds/effects/wav/Lock.wav
Binary files differ
diff --git a/data/sounds/effects/wav/Unlock.wav b/data/sounds/effects/wav/Unlock.wav
index 2229d03..e1d475e 100644
--- a/data/sounds/effects/wav/Unlock.wav
+++ b/data/sounds/effects/wav/Unlock.wav
Binary files differ
diff --git a/data/sounds/notifications/ogg/Acrux.ogg b/data/sounds/notifications/ogg/Acrux.ogg
new file mode 100644
index 0000000..74ad149
--- /dev/null
+++ b/data/sounds/notifications/ogg/Acrux.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Bellatrix.ogg b/data/sounds/notifications/ogg/Bellatrix.ogg
new file mode 100644
index 0000000..37a1bdc
--- /dev/null
+++ b/data/sounds/notifications/ogg/Bellatrix.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Pollux.ogg b/data/sounds/notifications/ogg/Pollux.ogg
new file mode 100644
index 0000000..2f907fd
--- /dev/null
+++ b/data/sounds/notifications/ogg/Pollux.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Tejat.ogg b/data/sounds/notifications/ogg/Tejat.ogg
new file mode 100644
index 0000000..04ba06c
--- /dev/null
+++ b/data/sounds/notifications/ogg/Tejat.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Girtab.ogg b/data/sounds/ringtones/ogg/Girtab.ogg
new file mode 100644
index 0000000..f6b3a35
--- /dev/null
+++ b/data/sounds/ringtones/ogg/Girtab.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Zeta.ogg b/data/sounds/ringtones/ogg/Zeta.ogg
new file mode 100644
index 0000000..ef64d2f
--- /dev/null
+++ b/data/sounds/ringtones/ogg/Zeta.ogg
Binary files differ
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index de0fabc..50964d5 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -285,7 +285,7 @@
             of the fill (if any) without worrying about blending artifacts.
          */
          final boolean useLayer = haveStroke && haveFill && st.mShape != LINE &&
-                 currStrokeAlpha < 255;
+                 currStrokeAlpha < 255 && (mAlpha < 255 || mColorFilter != null);
 
         /*  Drawing with a layer is slower than direct drawing, but it
             allows us to apply paint effects like alpha and colorfilter to
diff --git a/media/java/android/media/videoeditor/AudioTrack.java b/media/java/android/media/videoeditor/AudioTrack.java
index 2de82f2..c5cc2ca 100755
--- a/media/java/android/media/videoeditor/AudioTrack.java
+++ b/media/java/android/media/videoeditor/AudioTrack.java
@@ -147,14 +147,16 @@
         } catch (Exception e) {
             throw new IllegalArgumentException(e.getMessage() + " : " + filename);
         }
-        switch (mMANativeHelper.getFileType(properties.fileType)) {
+        int fileType = mMANativeHelper.getFileType(properties.fileType);
+        switch (fileType) {
             case MediaProperties.FILE_3GP:
             case MediaProperties.FILE_MP4:
             case MediaProperties.FILE_MP3:
+            case MediaProperties.FILE_AMR:
                 break;
 
             default: {
-                throw new IllegalArgumentException("Unsupported input file type");
+                throw new IllegalArgumentException("Unsupported input file type: " + fileType);
             }
         }
         switch (mMANativeHelper.getAudioCodecType(properties.audioFormat)) {
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index d7b8eaa..03ae62a 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -3239,6 +3239,9 @@
             case FileType.M4V:
                 retValue = MediaProperties.FILE_M4V;
                 break;
+            case FileType.AMR:
+                retValue = MediaProperties.FILE_AMR;
+                break;
 
             default:
                 retValue = -1;
diff --git a/media/java/android/media/videoeditor/MediaProperties.java b/media/java/android/media/videoeditor/MediaProperties.java
index fd034ab..cf518a5 100755
--- a/media/java/android/media/videoeditor/MediaProperties.java
+++ b/media/java/android/media/videoeditor/MediaProperties.java
@@ -286,7 +286,7 @@
      */
     public static final int FILE_3GP = 0;
     public static final int FILE_MP4 = 1;
-    // 2 is for AMRNB
+    public static final int FILE_AMR = 2;
     public static final int FILE_MP3 = 3;
     // 4 is for PCM
     public static final int FILE_JPEG = 5;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index fa9417a..1165af5 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -2005,6 +2005,11 @@
             mConnectingDataSource->setUID(mUID);
         }
 
+        String8 cacheConfig;
+        bool disconnectAtHighwatermark;
+        NuCachedSource2::RemoveCacheSpecificHeaders(
+                &mUriHeaders, &cacheConfig, &disconnectAtHighwatermark);
+
         mLock.unlock();
         status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
         mLock.lock();
@@ -2024,7 +2029,10 @@
                     new ThrottledSource(
                         mConnectingDataSource, 50 * 1024 /* bytes/sec */));
 #else
-            mCachedSource = new NuCachedSource2(mConnectingDataSource);
+            mCachedSource = new NuCachedSource2(
+                    mConnectingDataSource,
+                    cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
+                    disconnectAtHighwatermark);
 #endif
 
             dataSource = mCachedSource;
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 9adb841..4f183f5 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -177,7 +177,10 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-NuCachedSource2::NuCachedSource2(const sp<DataSource> &source)
+NuCachedSource2::NuCachedSource2(
+        const sp<DataSource> &source,
+        const char *cacheConfig,
+        bool disconnectAtHighwatermark)
     : mSource(source),
       mReflector(new AHandlerReflector<NuCachedSource2>(this)),
       mLooper(new ALooper),
@@ -190,9 +193,24 @@
       mNumRetriesLeft(kMaxNumRetries),
       mHighwaterThresholdBytes(kDefaultHighWaterThreshold),
       mLowwaterThresholdBytes(kDefaultLowWaterThreshold),
-      mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs) {
+      mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs),
+      mDisconnectAtHighwatermark(disconnectAtHighwatermark) {
+    // We are NOT going to support disconnect-at-highwatermark indefinitely
+    // and we are not guaranteeing support for client-specified cache
+    // parameters. Both of these are temporary measures to solve a specific
+    // problem that will be solved in a better way going forward.
+
     updateCacheParamsFromSystemProperty();
 
+    if (cacheConfig != NULL) {
+        updateCacheParamsFromString(cacheConfig);
+    }
+
+    if (mDisconnectAtHighwatermark) {
+        // Makes no sense to disconnect and do keep-alives...
+        mKeepAliveIntervalUs = 0;
+    }
+
     mLooper->setName("NuCachedSource2");
     mLooper->registerHandler(mReflector);
     mLooper->start();
@@ -339,6 +357,12 @@
         if (mFetching && mCache->totalSize() >= mHighwaterThresholdBytes) {
             LOGI("Cache full, done prefetching for now");
             mFetching = false;
+
+            if (mDisconnectAtHighwatermark
+                    && (mSource->flags() & DataSource::kIsHTTPBasedSource)) {
+                LOGV("Disconnecting at high watermark");
+                static_cast<HTTPBase *>(mSource.get())->disconnect();
+            }
         }
     } else {
         Mutex::Autolock autoLock(mLock);
@@ -637,4 +661,34 @@
          mKeepAliveIntervalUs);
 }
 
+// static
+void NuCachedSource2::RemoveCacheSpecificHeaders(
+        KeyedVector<String8, String8> *headers,
+        String8 *cacheConfig,
+        bool *disconnectAtHighwatermark) {
+    *cacheConfig = String8();
+    *disconnectAtHighwatermark = false;
+
+    if (headers == NULL) {
+        return;
+    }
+
+    ssize_t index;
+    if ((index = headers->indexOfKey(String8("x-cache-config"))) >= 0) {
+        *cacheConfig = headers->valueAt(index);
+
+        headers->removeItemsAt(index);
+
+        LOGV("Using special cache config '%s'", cacheConfig->string());
+    }
+
+    if ((index = headers->indexOfKey(
+                    String8("x-disconnect-at-highwatermark"))) >= 0) {
+        *disconnectAtHighwatermark = true;
+        headers->removeItemsAt(index);
+
+        LOGV("Client requested disconnection at highwater mark");
+    }
+}
+
 }  // namespace android
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index f04c566..7a03e7e 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -28,7 +28,10 @@
 struct PageCache;
 
 struct NuCachedSource2 : public DataSource {
-    NuCachedSource2(const sp<DataSource> &source);
+    NuCachedSource2(
+            const sp<DataSource> &source,
+            const char *cacheConfig = NULL,
+            bool disconnectAtHighwatermark = false);
 
     virtual status_t initCheck() const;
 
@@ -56,6 +59,11 @@
     status_t getEstimatedBandwidthKbps(int32_t *kbps);
     status_t setCacheStatCollectFreq(int32_t freqMs);
 
+    static void RemoveCacheSpecificHeaders(
+            KeyedVector<String8, String8> *headers,
+            String8 *cacheConfig,
+            bool *disconnectAtHighwatermark);
+
 protected:
     virtual ~NuCachedSource2();
 
@@ -105,6 +113,8 @@
     // If the keep-alive interval is 0, keep-alives are disabled.
     int64_t mKeepAliveIntervalUs;
 
+    bool mDisconnectAtHighwatermark;
+
     void onMessageReceived(const sp<AMessage> &msg);
     void onFetch();
     void onRead(const sp<AMessage> &msg);
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index 24dce1a..8343bbd 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -186,6 +186,9 @@
 
         mTransientTextManager = new TransientTextManager(mCarrierView);
 
+        mUpdateMonitor.registerInfoCallback(mInfoCallback);
+        mUpdateMonitor.registerSimStateCallback(mSimStateCallback);
+
         resetStatusInfo();
         refreshDate();
         updateOwnerInfo();
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 10cf3aa..f67f0e0 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -218,7 +218,7 @@
 
         // take a guess to start
         mSimState = IccCard.State.READY;
-        mBatteryStatus = BATTERY_STATUS_FULL;
+        mBatteryStatus = BATTERY_STATUS_UNKNOWN;
         mBatteryLevel = 100;
 
         mTelephonyPlmn = getDefaultPlmn();
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 071044e..265024b 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -98,7 +98,8 @@
     private View mLockScreen;
     private View mUnlockScreen;
 
-    private boolean mScreenOn = false;
+    private volatile boolean mScreenOn = false;
+    private volatile boolean mWindowFocused = false;
     private boolean mEnableFallback = false; // assume no fallback UI until we know better
 
     private boolean mShowLockBeforeUnlock = false;
@@ -110,6 +111,7 @@
 
     private boolean mFaceLockServiceRunning = false;
     private final Object mFaceLockServiceRunningLock = new Object();
+    private final Object mFaceLockStartupLock = new Object();
 
     private Handler mHandler;
     private final int MSG_SHOW_FACELOCK_AREA_VIEW = 0;
@@ -514,13 +516,10 @@
         stopAndUnbindFromFaceLock();
     }
 
-    @Override
-    public void onScreenTurnedOn() {
-        mScreenOn = true;
-        show();
-
-        // When screen is turned on, need to bind to FaceLock service if we are using FaceLock
-        // But only if not dealing with a call
+    /** When screen is turned on and focused, need to bind to FaceLock service if we are using
+     *  FaceLock, but only if we're not dealing with a call
+    */
+    private void activateFaceLockIfAble() {
         final boolean transportInvisible = mTransportControlView == null ? true :
                 mTransportControlView.getVisibility() != View.VISIBLE;
         if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
@@ -534,12 +533,34 @@
         }
     }
 
-    /** Unbind from facelock if something covers this window (such as an alarm) */
+    @Override
+    public void onScreenTurnedOn() {
+        boolean runFaceLock = false;
+        //Make sure to start facelock iff the screen is both on and focused
+        synchronized(mFaceLockStartupLock) {
+            mScreenOn = true;
+            runFaceLock = mWindowFocused;
+        }
+        show();
+        if(runFaceLock) activateFaceLockIfAble();
+    }
+
+    /** Unbind from facelock if something covers this window (such as an alarm)
+     * bind to facelock if the lockscreen window just came into focus, and the screen is on
+     */
     @Override
     public void onWindowFocusChanged (boolean hasWindowFocus) {
+        boolean runFaceLock = false;
+        //Make sure to start facelock iff the screen is both on and focused
+        synchronized(mFaceLockStartupLock) {
+            if(mScreenOn && !mWindowFocused) runFaceLock = hasWindowFocus;
+            mWindowFocused = hasWindowFocus;
+        }
         if(!hasWindowFocus) {
             stopAndUnbindFromFaceLock();
             mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+        } else if (runFaceLock) {
+            activateFaceLockIfAble();
         }
     }
 
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 5758954..f9f5458 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -1966,6 +1966,9 @@
             synchronized (mQueueLock) {
                 mBackupRunning = false;
                 if (mStatus == BackupConstants.TRANSPORT_NOT_INITIALIZED) {
+                    // Make sure we back up everything and perform the one-time init
+                    clearMetadata();
+                    if (DEBUG) Slog.d(TAG, "Server requires init; rerunning");
                     backupNow();
                 }
             }
@@ -1975,6 +1978,12 @@
             mWakelock.release();
         }
 
+        // Remove the PM metadata state. This will generate an init on the next pass.
+        void clearMetadata() {
+            final File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
+            if (pmState.exists()) pmState.delete();
+        }
+
         // Invoke an agent's doBackup() and start a timeout message spinning on the main
         // handler in case it doesn't get back to us.
         int invokeAgentForBackup(String packageName, IBackupAgent agent,
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 78dbbd6..1941c6a 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1677,6 +1677,18 @@
             e.fillInStackTrace();
             Slog.i(TAG, "Set screen state: " + on, e);
         }
+        if (on) {
+            if ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
+                // If we are turning the screen state on, but the screen
+                // light is currently off, then make sure that we set the
+                // light at this point to 0.  This is the case where we are
+                // turning on the screen and waiting for the UI to be drawn
+                // before showing it to the user.  We want the light off
+                // until it is ready to be shown to the user, not it using
+                // whatever the last value it had.
+                mScreenBrightness.forceValueLocked(Power.BRIGHTNESS_OFF);
+            }
+        }
         int err = Power.setScreenState(on);
         if (err == 0) {
             mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);
@@ -2029,8 +2041,6 @@
                 RuntimeException e = new RuntimeException("here");
                 e.fillInStackTrace();
                 Slog.i(TAG, "Setting screen brightness: " + brightness, e);
-                mScreenBrightness.setTargetLocked(brightness, steps,
-                        INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue);
             }
         }
 
@@ -2103,6 +2113,15 @@
                     + " delta=" + delta);
         }
 
+        void forceValueLocked(int value) {
+            targetValue = -1;
+            curValue = value;
+            setLightBrightness(mask, value);
+            if (animating) {
+                finishAnimationLocked(false, value);
+            }
+        }
+
         void setTargetLocked(int target, int stepsToTarget, int initialValue,
                 int nominalCurrentValue) {
             if (!initialized) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 5006de7..3ae62ad 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -163,6 +163,11 @@
             pm = PackageManagerService.main(context,
                     factoryTest != SystemServer.FACTORY_TEST_OFF,
                     onlyCore);
+            boolean firstBoot = false;
+            try {
+                firstBoot = pm.isFirstBoot();
+            } catch (RemoteException e) {
+            }
 
             ActivityManagerService.setSystemProcess();
 
@@ -208,7 +213,8 @@
 
             Slog.i(TAG, "Window Manager");
             wm = WindowManagerService.main(context, power,
-                    factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
+                    factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
+                    !firstBoot);
             ServiceManager.addService(Context.WINDOW_SERVICE, wm);
 
             ActivityManagerService.self().setWindowManager(wm);
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 7bc19ab4..b9d3d76 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -589,8 +589,8 @@
                 }
             }
             app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
-                    System.identityHashCode(r),
-                    r.info, r.compat, r.icicle, results, newIntents, !andResume,
+                    System.identityHashCode(r), r.info, mService.mConfiguration,
+                    r.compat, r.icicle, results, newIntents, !andResume,
                     mService.isNextTransitionForward(), profileFile, profileFd,
                     profileAutoStop);
             
@@ -4035,7 +4035,18 @@
         // But then we need to figure out how it needs to deal with that.
         Configuration oldConfig = r.configuration;
         r.configuration = newConfig;
-        
+
+        // Determine what has changed.  May be nothing, if this is a config
+        // that has come back from the app after going idle.  In that case
+        // we just want to leave the official config object now in the
+        // activity and do nothing else.
+        final int changes = oldConfig.diff(newConfig);
+        if (changes == 0 && !r.forceNewConfig) {
+            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+                    "Configuration no differences in " + r);
+            return true;
+        }
+
         // If the activity isn't currently running, just leave the new
         // configuration and it will pick that up next time it starts.
         if (r.app == null || r.app.thread == null) {
@@ -4046,8 +4057,7 @@
             return true;
         }
         
-        // Figure out what has changed between the two configurations.
-        int changes = oldConfig.diff(newConfig);
+        // Figure out how to handle the changes between the configurations.
         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
             Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
                     + Integer.toHexString(changes) + ", handles=0x"
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 0da5cc6..e610782 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -85,7 +85,6 @@
 import android.net.NetworkPolicy;
 import android.net.NetworkQuotaInfo;
 import android.net.NetworkState;
-import android.net.NetworkStats;
 import android.net.NetworkTemplate;
 import android.os.Binder;
 import android.os.Environment;
@@ -489,7 +488,7 @@
             final long end = currentTime;
             final long totalBytes = getTotalBytes(policy.template, start, end);
 
-            if (policy.limitBytes != LIMIT_DISABLED && totalBytes >= policy.limitBytes) {
+            if (policy.isOverLimit(totalBytes)) {
                 if (policy.lastSnooze >= start) {
                     enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
                 } else {
@@ -574,7 +573,7 @@
                 final CharSequence title = res.getText(R.string.data_usage_warning_title);
                 final CharSequence body = res.getString(R.string.data_usage_warning_body);
 
-                builder.setSmallIcon(R.drawable.ic_menu_info_details);
+                builder.setSmallIcon(R.drawable.stat_notify_error);
                 builder.setTicker(title);
                 builder.setContentTitle(title);
                 builder.setContentText(body);
@@ -606,7 +605,7 @@
                         break;
                 }
 
-                builder.setSmallIcon(com.android.internal.R.drawable.ic_menu_block);
+                builder.setSmallIcon(R.drawable.stat_notify_disabled);
                 builder.setTicker(title);
                 builder.setContentTitle(title);
                 builder.setContentText(body);
@@ -640,7 +639,7 @@
                         break;
                 }
 
-                builder.setSmallIcon(R.drawable.ic_menu_info_details);
+                builder.setSmallIcon(R.drawable.stat_notify_error);
                 builder.setTicker(title);
                 builder.setContentTitle(title);
                 builder.setContentText(body);
@@ -677,7 +676,7 @@
 
         builder.setOnlyAlertOnce(true);
         builder.setOngoing(true);
-        builder.setSmallIcon(R.drawable.ic_menu_info_details);
+        builder.setSmallIcon(R.drawable.stat_notify_error);
         builder.setTicker(title);
         builder.setContentTitle(title);
         builder.setContentText(body);
@@ -750,8 +749,7 @@
             final long totalBytes = getTotalBytes(policy.template, start, end);
 
             // disable data connection when over limit and not snoozed
-            final boolean overLimit = policy.limitBytes != LIMIT_DISABLED
-                    && totalBytes > policy.limitBytes && policy.lastSnooze < start;
+            final boolean overLimit = policy.isOverLimit(totalBytes) && policy.lastSnooze < start;
             final boolean enabled = !overLimit;
 
             setNetworkTemplateEnabled(policy.template, enabled);
@@ -1535,10 +1533,7 @@
 
     private long getTotalBytes(NetworkTemplate template, long start, long end) {
         try {
-            final NetworkStats stats = mNetworkStats.getSummaryForNetwork(
-                    template, start, end);
-            final NetworkStats.Entry entry = stats.getValues(0, null);
-            return entry.rxBytes + entry.txBytes;
+            return mNetworkStats.getSummaryForNetwork(template, start, end).getTotalBytes();
         } catch (RemoteException e) {
             // ignored; service lives in system_server
             return 0;
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 19dd606..0e9f64c 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1157,6 +1157,10 @@
         } // synchronized (mInstallLock)
     }
 
+    public boolean isFirstBoot() {
+        return !mRestoredSettings;
+    }
+
     private String getRequiredVerifierLPr() {
         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
@@ -2983,12 +2987,14 @@
         }
         if (pkgs != null) {
             for (int i=0; i<pkgs.size(); i++) {
-                try {
-                    ActivityManagerNative.getDefault().showBootMessage(
-                            mContext.getResources().getString(
-                                    com.android.internal.R.string.android_upgrading_apk,
-                                    i+1, pkgs.size()), true);
-                } catch (RemoteException e) {
+                if (!isFirstBoot()) {
+                    try {
+                        ActivityManagerNative.getDefault().showBootMessage(
+                                mContext.getResources().getString(
+                                        com.android.internal.R.string.android_upgrading_apk,
+                                        i+1, pkgs.size()), true);
+                    } catch (RemoteException e) {
+                    }
                 }
                 PackageParser.Package p = pkgs.get(i);
                 synchronized (mInstallLock) {
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 7cdb5b1..bfe6613 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -1238,9 +1238,8 @@
                 mReadMessages.append("No start tag found in settings file\n");
                 PackageManagerService.reportSettingsProblem(Log.WARN,
                         "No start tag found in package manager settings");
-                Log
-                        .wtf(PackageManagerService.TAG,
-                                "No start tag found in package manager settings");
+                Log.wtf(PackageManagerService.TAG,
+                        "No start tag found in package manager settings");
                 return false;
             }
 
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 73a9601..06a6e98 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -297,6 +297,8 @@
 
     final boolean mHaveInputMethods;
 
+    final boolean mAllowBootMessages;
+
     final boolean mLimitedAlphaCompositing;
 
     final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
@@ -633,8 +635,8 @@
     float mCompatibleScreenScale;
 
     public static WindowManagerService main(Context context,
-            PowerManagerService pm, boolean haveInputMethods) {
-        WMThread thr = new WMThread(context, pm, haveInputMethods);
+            PowerManagerService pm, boolean haveInputMethods, boolean allowBootMsgs) {
+        WMThread thr = new WMThread(context, pm, haveInputMethods, allowBootMsgs);
         thr.start();
 
         synchronized (thr) {
@@ -654,19 +656,21 @@
         private final Context mContext;
         private final PowerManagerService mPM;
         private final boolean mHaveInputMethods;
+        private final boolean mAllowBootMessages;
 
         public WMThread(Context context, PowerManagerService pm,
-                boolean haveInputMethods) {
+                boolean haveInputMethods, boolean allowBootMsgs) {
             super("WindowManager");
             mContext = context;
             mPM = pm;
             mHaveInputMethods = haveInputMethods;
+            mAllowBootMessages = allowBootMsgs;
         }
 
         public void run() {
             Looper.prepare();
             WindowManagerService s = new WindowManagerService(mContext, mPM,
-                    mHaveInputMethods);
+                    mHaveInputMethods, mAllowBootMessages);
             android.os.Process.setThreadPriority(
                     android.os.Process.THREAD_PRIORITY_DISPLAY);
             android.os.Process.setCanSelfBackground(false);
@@ -728,9 +732,10 @@
     }
 
     private WindowManagerService(Context context, PowerManagerService pm,
-            boolean haveInputMethods) {
+            boolean haveInputMethods, boolean showBootMsgs) {
         mContext = context;
         mHaveInputMethods = haveInputMethods;
+        mAllowBootMessages = showBootMsgs;
         mLimitedAlphaCompositing = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_sf_limitedAlpha);
 
@@ -4846,6 +4851,9 @@
     public void showBootMessage(final CharSequence msg, final boolean always) {
         boolean first = false;
         synchronized(mWindowMap) {
+            if (!mAllowBootMessages) {
+                return;
+            }
             if (!mShowingBootMessages) {
                 if (!always) {
                     return;
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 51eb0a3..dab0705 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -22,6 +22,9 @@
 ifeq ($(TARGET_BOARD_PLATFORM), omap3)
 	LOCAL_CFLAGS += -DNO_RGBX_8888
 endif
+ifeq ($(TARGET_BOARD_PLATFORM), omap4)
+	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
+endif
 ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
 	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE
 endif
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index dded39e..fe41e7e 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -88,6 +88,7 @@
                 PendingIntent intent = tracker.mDeliveryIntent;
                 Intent fillIn = new Intent();
                 fillIn.putExtra("pdu", sms.getPdu());
+                fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP2);
                 try {
                     intent.send(mContext, Activity.RESULT_OK, fillIn);
                 } catch (CanceledException ex) {}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index 4e1cc9a..c1553d8 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -122,6 +122,7 @@
                     PendingIntent intent = tracker.mDeliveryIntent;
                     Intent fillIn = new Intent();
                     fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString));
+                    fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP);
                     try {
                         intent.send(mContext, Activity.RESULT_OK, fillIn);
                     } catch (CanceledException ex) {}
diff --git a/test-runner/src/android/test/mock/MockContentProvider.java b/test-runner/src/android/test/mock/MockContentProvider.java
index b63ff3d..e0ce322 100644
--- a/test-runner/src/android/test/mock/MockContentProvider.java
+++ b/test-runner/src/android/test/mock/MockContentProvider.java
@@ -21,16 +21,12 @@
 import android.content.ContentProviderResult;
 import android.content.ContentValues;
 import android.content.Context;
-import android.content.EntityIterator;
 import android.content.IContentProvider;
 import android.content.OperationApplicationException;
 import android.content.pm.PathPermission;
 import android.content.pm.ProviderInfo;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -55,84 +51,75 @@
      * IContentProvider that directs all calls to this MockContentProvider.
      */
     private class InversionIContentProvider implements IContentProvider {
-        @SuppressWarnings("unused")
+        @Override
         public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
                 throws RemoteException, OperationApplicationException {
             return MockContentProvider.this.applyBatch(operations);
         }
 
-        @SuppressWarnings("unused")
+        @Override
         public int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException {
             return MockContentProvider.this.bulkInsert(url, initialValues);
         }
 
-        @SuppressWarnings("unused")
-        public IBulkCursor bulkQuery(Uri url, String[] projection, String selection,
-                String[] selectionArgs, String sortOrder, IContentObserver observer,
-                CursorWindow window) throws RemoteException {
-            throw new UnsupportedOperationException("Must not come here");
-        }
-
-        @SuppressWarnings("unused")
+        @Override
         public int delete(Uri url, String selection, String[] selectionArgs)
                 throws RemoteException {
             return MockContentProvider.this.delete(url, selection, selectionArgs);
         }
 
-        @SuppressWarnings("unused")
+        @Override
         public String getType(Uri url) throws RemoteException {
             return MockContentProvider.this.getType(url);
         }
 
-        @SuppressWarnings("unused")
+        @Override
         public Uri insert(Uri url, ContentValues initialValues) throws RemoteException {
             return MockContentProvider.this.insert(url, initialValues);
         }
 
-        @SuppressWarnings("unused")
+        @Override
         public AssetFileDescriptor openAssetFile(Uri url, String mode) throws RemoteException,
                 FileNotFoundException {
             return MockContentProvider.this.openAssetFile(url, mode);
         }
 
-        @SuppressWarnings("unused")
+        @Override
         public ParcelFileDescriptor openFile(Uri url, String mode) throws RemoteException,
                 FileNotFoundException {
             return MockContentProvider.this.openFile(url, mode);
         }
 
-        @SuppressWarnings("unused")
+        @Override
         public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
                 String sortOrder) throws RemoteException {
             return MockContentProvider.this.query(url, projection, selection,
                     selectionArgs, sortOrder);
         }
 
-        @SuppressWarnings("unused")
+        @Override
         public int update(Uri url, ContentValues values, String selection, String[] selectionArgs)
                 throws RemoteException {
             return MockContentProvider.this.update(url, values, selection, selectionArgs);
         }
 
-        /**
-         * @hide
-         */
-        @SuppressWarnings("unused")
+        @Override
         public Bundle call(String method, String request, Bundle args)
                 throws RemoteException {
             return MockContentProvider.this.call(method, request, args);
         }
 
+        @Override
         public IBinder asBinder() {
             throw new UnsupportedOperationException();
         }
 
-        @SuppressWarnings("unused")
+        @Override
         public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
             return MockContentProvider.this.getStreamTypes(url, mimeTypeFilter);
         }
 
-        @SuppressWarnings("unused")
+        @Override
         public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts)
                 throws RemoteException, FileNotFoundException {
             return MockContentProvider.this.openTypedAssetFile(url, mimeType, opts);
diff --git a/test-runner/src/android/test/mock/MockIContentProvider.java b/test-runner/src/android/test/mock/MockIContentProvider.java
index 183be41..b7733a4 100644
--- a/test-runner/src/android/test/mock/MockIContentProvider.java
+++ b/test-runner/src/android/test/mock/MockIContentProvider.java
@@ -23,9 +23,6 @@
 import android.content.IContentProvider;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -47,12 +44,6 @@
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
-    public IBulkCursor bulkQuery(Uri url, String[] projection, String selection,
-            String[] selectionArgs, String sortOrder, IContentObserver observer,
-            CursorWindow window) {
-        throw new UnsupportedOperationException("unimplemented mock method");
-    }
-
     @SuppressWarnings("unused")
     public int delete(Uri url, String selection, String[] selectionArgs)
             throws RemoteException {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
index 3835378..c91a3bf 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
@@ -23,9 +23,6 @@
 import android.content.OperationApplicationException;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -41,78 +38,84 @@
  * TODO: never return null when the method is not supposed to. Return fake data instead.
  */
 public final class BridgeContentProvider implements IContentProvider {
-
+    @Override
     public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> arg0)
             throws RemoteException, OperationApplicationException {
         // TODO Auto-generated method stub
         return null;
     }
 
+    @Override
     public int bulkInsert(Uri arg0, ContentValues[] arg1) throws RemoteException {
         // TODO Auto-generated method stub
         return 0;
     }
 
-    public IBulkCursor bulkQuery(Uri arg0, String[] arg1, String arg2, String[] arg3,
-            String arg4, IContentObserver arg5, CursorWindow arg6) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
+    @Override
     public Bundle call(String arg0, String arg1, Bundle arg2) throws RemoteException {
         // TODO Auto-generated method stub
         return null;
     }
 
+    @Override
     public int delete(Uri arg0, String arg1, String[] arg2) throws RemoteException {
         // TODO Auto-generated method stub
         return 0;
     }
 
+    @Override
     public String getType(Uri arg0) throws RemoteException {
         // TODO Auto-generated method stub
         return null;
     }
 
+    @Override
     public Uri insert(Uri arg0, ContentValues arg1) throws RemoteException {
         // TODO Auto-generated method stub
         return null;
     }
 
+    @Override
     public AssetFileDescriptor openAssetFile(Uri arg0, String arg1) throws RemoteException,
             FileNotFoundException {
         // TODO Auto-generated method stub
         return null;
     }
 
+    @Override
     public ParcelFileDescriptor openFile(Uri arg0, String arg1) throws RemoteException,
             FileNotFoundException {
         // TODO Auto-generated method stub
         return null;
     }
 
+    @Override
     public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4)
             throws RemoteException {
         // TODO Auto-generated method stub
         return null;
     }
 
+    @Override
     public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3)
             throws RemoteException {
         // TODO Auto-generated method stub
         return 0;
     }
 
+    @Override
     public IBinder asBinder() {
         // TODO Auto-generated method stub
         return null;
     }
 
+    @Override
     public String[] getStreamTypes(Uri arg0, String arg1) throws RemoteException {
         // TODO Auto-generated method stub
         return null;
     }
 
+    @Override
     public AssetFileDescriptor openTypedAssetFile(Uri arg0, String arg1, Bundle arg2)
             throws RemoteException, FileNotFoundException {
         // TODO Auto-generated method stub