Merge "P2p cleanup"
diff --git a/api/current.txt b/api/current.txt
index 5758606..57d65ba 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2684,6 +2684,7 @@
     method public final boolean isChild();
     method public boolean isDestroyed();
     method public boolean isFinishing();
+    method public boolean isImmersive();
     method public boolean isTaskRoot();
     method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public boolean moveTaskToBack(boolean);
@@ -2771,6 +2772,7 @@
     method public final void setFeatureDrawableResource(int, int);
     method public final void setFeatureDrawableUri(int, android.net.Uri);
     method public void setFinishOnTouchOutside(boolean);
+    method public void setImmersive(boolean);
     method public void setIntent(android.content.Intent);
     method public final void setProgress(int);
     method public final void setProgressBarIndeterminate(boolean);
@@ -6331,6 +6333,7 @@
     field public static final int FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS = 256; // 0x100
     field public static final int FLAG_FINISH_ON_TASK_LAUNCH = 2; // 0x2
     field public static final int FLAG_HARDWARE_ACCELERATED = 512; // 0x200
+    field public static final int FLAG_IMMERSIVE = 2048; // 0x800
     field public static final int FLAG_MULTIPROCESS = 1; // 0x1
     field public static final int FLAG_NO_HISTORY = 128; // 0x80
     field public static final int FLAG_SINGLE_USER = 1073741824; // 0x40000000
@@ -20553,6 +20556,7 @@
     method public int addSpeech(java.lang.String, java.lang.String);
     method public boolean areDefaultsEnforced();
     method public java.lang.String getDefaultEngine();
+    method public java.util.Locale getDefaultLanguage();
     method public java.util.List<android.speech.tts.TextToSpeech.EngineInfo> getEngines();
     method public java.util.Set<java.lang.String> getFeatures(java.util.Locale);
     method public java.util.Locale getLanguage();
@@ -29077,6 +29081,7 @@
     method public void setRelativeScrollPosition(int, int);
     method public deprecated void setRemoteAdapter(int, int, android.content.Intent);
     method public void setRemoteAdapter(int, android.content.Intent);
+    method public void setRemoteAdapter(int, java.util.ArrayList<android.widget.RemoteViews>);
     method public void setScrollPosition(int, int);
     method public void setShort(int, java.lang.String, short);
     method public void setString(int, java.lang.String, java.lang.String);
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index ecf3b19..7efe189 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -557,7 +557,7 @@
         public IAccessibilityServiceClientWrapper(Context context, Looper looper,
                 Callbacks callback) {
             mCallback = callback;
-            mCaller = new HandlerCaller(context, looper, this);
+            mCaller = new HandlerCaller(context, looper, this, true /*asyncHandler*/);
         }
 
         public void setConnection(IAccessibilityServiceConnection connection, int connectionId) {
diff --git a/core/java/android/accounts/AccountAuthenticatorResponse.java b/core/java/android/accounts/AccountAuthenticatorResponse.java
index 614e139..41f26ac 100644
--- a/core/java/android/accounts/AccountAuthenticatorResponse.java
+++ b/core/java/android/accounts/AccountAuthenticatorResponse.java
@@ -33,7 +33,7 @@
     /**
      * @hide
      */
-    /* package private */ AccountAuthenticatorResponse(IAccountAuthenticatorResponse response) {
+    public AccountAuthenticatorResponse(IAccountAuthenticatorResponse response) {
         mAccountAuthenticatorResponse = response;
     }
 
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 5dc9da2..cbeffc1 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2544,7 +2544,7 @@
                 // Put event logging here so it gets called even if subclass
                 // doesn't call through to superclass's implmeentation of each
                 // of these methods below
-                EventLog.writeEvent(50000, 0, item.getTitleCondensed());
+                EventLog.writeEvent(50000, 0, item.getTitleCondensed().toString());
                 if (onOptionsItemSelected(item)) {
                     return true;
                 }
@@ -2562,7 +2562,7 @@
                 return false;
                 
             case Window.FEATURE_CONTEXT_MENU:
-                EventLog.writeEvent(50000, 1, item.getTitleCondensed());
+                EventLog.writeEvent(50000, 1, item.getTitleCondensed().toString());
                 if (onContextItemSelected(item)) {
                     return true;
                 }
@@ -4818,8 +4818,8 @@
      * <code>android:immersive</code> but may be changed at runtime by
      * {@link #setImmersive}.
      *
+     * @see #setImmersive(boolean)
      * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE
-     * @hide
      */
     public boolean isImmersive() {
         try {
@@ -4831,7 +4831,7 @@
 
     /**
      * Adjust the current immersive mode setting.
-     * 
+     *
      * Note that changing this value will have no effect on the activity's
      * {@link android.content.pm.ActivityInfo} structure; that is, if
      * <code>android:immersive</code> is set to <code>true</code>
@@ -4840,9 +4840,8 @@
      * always have its {@link android.content.pm.ActivityInfo#FLAG_IMMERSIVE
      * FLAG_IMMERSIVE} bit set.
      *
-     * @see #isImmersive
+     * @see #isImmersive()
      * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE
-     * @hide
      */
     public void setImmersive(boolean i) {
         try {
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index b20cf88..e34c827 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -116,6 +116,10 @@
      */
     public static final String SYNC_EXTRAS_INITIALIZE = "initialize";
 
+    /** @hide */
+    public static final Intent ACTION_SYNC_CONN_STATUS_CHANGED =
+            new Intent("com.android.sync.SYNC_CONN_STATUS_CHANGED");
+
     public static final String SCHEME_CONTENT = "content";
     public static final String SCHEME_ANDROID_RESOURCE = "android.resource";
     public static final String SCHEME_FILE = "file";
@@ -181,7 +185,7 @@
     };
 
     /** @hide */
-    static String syncErrorToString(int error) {
+    public static String syncErrorToString(int error) {
         if (error < 1 || error > SYNC_ERROR_NAMES.length) {
             return String.valueOf(error);
         }
diff --git a/core/java/android/content/PeriodicSync.java b/core/java/android/content/PeriodicSync.java
index 17813ec..513a556 100644
--- a/core/java/android/content/PeriodicSync.java
+++ b/core/java/android/content/PeriodicSync.java
@@ -79,6 +79,25 @@
         return account.equals(other.account)
                 && authority.equals(other.authority)
                 && period == other.period
-                && SyncStorageEngine.equals(extras, other.extras);
+                && syncExtrasEquals(extras, other.extras);
+    }
+
+    /** {@hide} */
+    public static boolean syncExtrasEquals(Bundle b1, Bundle b2) {
+        if (b1.size() != b2.size()) {
+            return false;
+        }
+        if (b1.isEmpty()) {
+            return true;
+        }
+        for (String key : b1.keySet()) {
+            if (!b2.containsKey(key)) {
+                return false;
+            }
+            if (!b1.get(key).equals(b2.get(key))) {
+                return false;
+            }
+        }
+        return true;
     }
 }
diff --git a/core/java/android/content/SyncAdaptersCache.java b/core/java/android/content/SyncAdaptersCache.java
index 7b643a0..8bb3ee7 100644
--- a/core/java/android/content/SyncAdaptersCache.java
+++ b/core/java/android/content/SyncAdaptersCache.java
@@ -31,7 +31,7 @@
  * A cache of services that export the {@link android.content.ISyncAdapter} interface.
  * @hide
  */
-/* package private */ class SyncAdaptersCache extends RegisteredServicesCache<SyncAdapterType> {
+public class SyncAdaptersCache extends RegisteredServicesCache<SyncAdapterType> {
     private static final String TAG = "Account";
 
     private static final String SERVICE_INTERFACE = "android.content.SyncAdapter";
@@ -39,7 +39,7 @@
     private static final String ATTRIBUTES_NAME = "sync-adapter";
     private static final MySerializer sSerializer = new MySerializer();
 
-    SyncAdaptersCache(Context context) {
+    public SyncAdaptersCache(Context context) {
         super(context, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME, sSerializer);
     }
 
diff --git a/core/java/android/content/SyncInfo.java b/core/java/android/content/SyncInfo.java
index abfe964..0284882 100644
--- a/core/java/android/content/SyncInfo.java
+++ b/core/java/android/content/SyncInfo.java
@@ -46,7 +46,7 @@
     public final long startTime;
 
     /** @hide */
-    SyncInfo(int authorityId, Account account, String authority,
+    public SyncInfo(int authorityId, Account account, String authority,
             long startTime) {
         this.authorityId = authorityId;
         this.account = account;
diff --git a/core/java/android/content/SyncStatusInfo.java b/core/java/android/content/SyncStatusInfo.java
index bb2b2da..49e3e35 100644
--- a/core/java/android/content/SyncStatusInfo.java
+++ b/core/java/android/content/SyncStatusInfo.java
@@ -46,7 +46,7 @@
 
     private static final String TAG = "Sync";
 
-    SyncStatusInfo(int authorityId) {
+    public SyncStatusInfo(int authorityId) {
         this.authorityId = authorityId;
     }
 
@@ -92,7 +92,7 @@
         }
     }
 
-    SyncStatusInfo(Parcel parcel) {
+    public SyncStatusInfo(Parcel parcel) {
         int version = parcel.readInt();
         if (version != VERSION && version != 1) {
             Log.w("SyncStatusInfo", "Unknown version: " + version);
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index e2ca1dd..8f3b62d 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -161,7 +161,6 @@
      */
     public static final int FLAG_SHOW_ON_LOCK_SCREEN = 0x0400;
     /**
-     * @hide
      * Bit in {@link #flags} corresponding to an immersive activity
      * that wishes not to be interrupted by notifications.
      * Applications that hide the system notification bar with
@@ -174,7 +173,14 @@
      * {@link #FLAG_IMMERSIVE} set, however, will not be interrupted; the
      * notification may be shown in some other way (such as a small floating
      * "toast" window).
-     * {@see android.app.Notification#FLAG_HIGH_PRIORITY}
+     *
+     * Note that this flag will always reflect the Activity's
+     * <code>android:immersive</code> manifest definition, even if the Activity's
+     * immersive state is changed at runtime via
+     * {@link android.app.Activity#setImmersive(boolean)}.
+     *
+     * @see android.app.Notification#FLAG_HIGH_PRIORITY
+     * @see android.app.Activity#setImmersive(boolean)
      */
     public static final int FLAG_IMMERSIVE = 0x0800;
     /**
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index 5324f81..d78262b 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -70,7 +70,8 @@
     
     public IInputMethodSessionWrapper(Context context,
             InputMethodSession inputMethodSession) {
-        mCaller = new HandlerCaller(context, this);
+        mCaller = new HandlerCaller(context, null,
+                this, true /*asyncHandler*/);
         mInputMethodSession = inputMethodSession;
     }
 
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index 5275314..2d67875 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -102,7 +102,8 @@
     public IInputMethodWrapper(AbstractInputMethodService context,
             InputMethod inputMethod) {
         mTarget = new WeakReference<AbstractInputMethodService>(context);
-        mCaller = new HandlerCaller(context.getApplicationContext(), this);
+        mCaller = new HandlerCaller(context.getApplicationContext(), null,
+                this, true /*asyncHandler*/);
         mInputMethod = new WeakReference<InputMethod>(inputMethod);
         mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
     }
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index ec660ee..3de362c 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -108,13 +108,6 @@
     public static ParcelFileDescriptor open(File file, int mode)
             throws FileNotFoundException {
         String path = file.getPath();
-        SecurityManager security = System.getSecurityManager();
-        if (security != null) {
-            security.checkRead(path);
-            if ((mode&MODE_WRITE_ONLY) != 0) {
-                security.checkWrite(path);
-            }
-        }
 
         if ((mode&MODE_READ_WRITE) == 0) {
             throw new IllegalArgumentException(
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index dc089bd..4dbc4b4 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4296,6 +4296,13 @@
         public static final String POWER_SOUNDS_ENABLED = "power_sounds_enabled";
 
         /**
+         * URI for the "wireless charging started" sound.
+         * @hide
+         */
+        public static final String WIRELESS_CHARGING_STARTED_SOUND =
+                "wireless_charging_started_sound";
+
+        /**
          * Whether we keep the device on while the device is plugged in.
          * Supported values are:
          * <ul>
diff --git a/core/java/android/server/package.html b/core/java/android/server/package.html
deleted file mode 100644
index c9f96a6..0000000
--- a/core/java/android/server/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/java/android/server/search/package.html b/core/java/android/server/search/package.html
deleted file mode 100644
index c9f96a6..0000000
--- a/core/java/android/server/search/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 500bb2c..9dc77b9 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -960,7 +960,7 @@
         IWallpaperEngineWrapper(WallpaperService context,
                 IWallpaperConnection conn, IBinder windowToken,
                 int windowType, boolean isPreview, int reqWidth, int reqHeight) {
-            mCaller = new HandlerCaller(context, context.getMainLooper(), this);
+            mCaller = new HandlerCaller(context, context.getMainLooper(), this, true);
             mConnection = conn;
             mWindowToken = windowToken;
             mWindowType = windowType;
diff --git a/core/java/android/speech/tts/ITextToSpeechService.aidl b/core/java/android/speech/tts/ITextToSpeechService.aidl
index 580d52c..6982029 100644
--- a/core/java/android/speech/tts/ITextToSpeechService.aidl
+++ b/core/java/android/speech/tts/ITextToSpeechService.aidl
@@ -97,7 +97,19 @@
      *         be empty too.
      */
     String[] getLanguage();
-
+    
+    /**
+     * Returns a default TTS language, country and variant as set by the user.
+     *
+     * Can be called from multiple threads.
+     *
+     * @return A 3-element array, containing language (ISO 3-letter code),
+     *         country (ISO 3-letter code) and variant used by the engine.
+     *         The country and variant may be {@code ""}. If country is empty, then variant must
+     *         be empty too.
+     */
+    String[] getClientDefaultLanguage();
+    
     /**
      * Checks whether the engine supports a given language.
      *
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index cb5e0cd..30a8626 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -1024,6 +1024,24 @@
     }
 
     /**
+     * Returns a Locale instance describing the language currently being used as the default
+     * Text-to-speech language.
+     *
+     * @return language, country (if any) and variant (if any) used by the client stored in a
+     *     Locale instance, or {@code null} on error.
+     */
+    public Locale getDefaultLanguage() {
+        return runAction(new Action<Locale>() {
+            @Override
+            public Locale run(ITextToSpeechService service) throws RemoteException {
+                String[] defaultLanguage = service.getClientDefaultLanguage();
+
+                return new Locale(defaultLanguage[0], defaultLanguage[1], defaultLanguage[2]);
+            }
+        }, null, "getDefaultLanguage");
+    }
+
+    /**
      * Sets the text-to-speech language.
      * The TTS engine will try to use the closest match to the specified
      * language as represented by the Locale, but there is no guarantee that the exact same Locale
@@ -1338,7 +1356,13 @@
 
                     try {
                         mConnectedService.setCallback(getCallerIdentity(), mCallback);
-                        Log.i(TAG, "Setuped connection to " + mName);
+                        String[] defaultLanguage = mConnectedService.getClientDefaultLanguage();
+
+                        mParams.putString(Engine.KEY_PARAM_LANGUAGE, defaultLanguage[0]);
+                        mParams.putString(Engine.KEY_PARAM_COUNTRY, defaultLanguage[1]);
+                        mParams.putString(Engine.KEY_PARAM_VARIANT, defaultLanguage[2]);
+
+                        Log.i(TAG, "Set up connection to " + mName);
                         return SUCCESS;
                     } catch (RemoteException re) {
                         Log.e(TAG, "Error connecting to service, setCallback() failed");
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 458350d..4054740 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -850,6 +850,11 @@
             return onGetLanguage();
         }
 
+        @Override
+        public String[] getClientDefaultLanguage() {
+            return getSettingsLocale();
+        }
+
         /*
          * If defaults are enforced, then no language is "available" except
          * perhaps the default language selected by the user.
diff --git a/core/java/android/view/SimulatedTrackball.java b/core/java/android/view/SimulatedTrackball.java
index b917371..0eb197e 100644
--- a/core/java/android/view/SimulatedTrackball.java
+++ b/core/java/android/view/SimulatedTrackball.java
@@ -40,7 +40,7 @@
     private static final int MAX_TAP_TIME = 250;
     // Where the cutoff is for determining an edge swipe
     private static final float EDGE_SWIPE_THRESHOLD = 0.9f;
-    private static final int FLICK_MSG_ID = 313;
+    private static final int MSG_FLICK = 313;
     // TODO: Pass touch slop from the input device
     private static final int TOUCH_SLOP = 30;
 
@@ -75,8 +75,11 @@
     // Has the TouchSlop constraint been invalidated
     private boolean mAlwaysInTapRegion = true;
 
-    // Most recent event. Used to determine what device sent the event.
-    private MotionEvent mRecentEvent;
+    // Information from the most recent event.
+    // Used to determine what device sent the event during a fling.
+    private int mLastSource;
+    private int mLastMetaState;
+    private int mLastDeviceId;
 
     // TODO: Currently using screen dimensions tuned to a Galaxy Nexus, need to
     // read this from a config file instead
@@ -101,33 +104,34 @@
         mTouchSlopSquared = mTouchSlop * mTouchSlop;
     }
 
-    private final Handler mHandler = new Handler(new Callback() {
+    private final Handler mHandler = new Handler(true /*async*/) {
             @Override
-        public boolean handleMessage(Message msg) {
-            if (msg.what != FLICK_MSG_ID)
-                return false;
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_FLICK: {
+                    final long time = SystemClock.uptimeMillis();
+                    ViewRootImpl viewroot = (ViewRootImpl) msg.obj;
+                    // Send the key
+                    viewroot.enqueueInputEvent(new KeyEvent(time, time,
+                            KeyEvent.ACTION_DOWN, msg.arg2, 0, mLastMetaState,
+                            mLastDeviceId, 0, KeyEvent.FLAG_FALLBACK, mLastSource));
+                    viewroot.enqueueInputEvent(new KeyEvent(time, time,
+                            KeyEvent.ACTION_UP, msg.arg2, 0, mLastMetaState,
+                            mLastDeviceId, 0, KeyEvent.FLAG_FALLBACK, mLastSource));
 
-            final long time = SystemClock.uptimeMillis();
-            ViewRootImpl viewroot = (ViewRootImpl) msg.obj;
-            // Send the key
-            viewroot.enqueueInputEvent(new KeyEvent(time, time,
-                    KeyEvent.ACTION_DOWN, msg.arg2, 0, mRecentEvent.getMetaState(),
-                    mRecentEvent.getDeviceId(), 0,
-                    KeyEvent.FLAG_FALLBACK, mRecentEvent.getSource()));
-            viewroot.enqueueInputEvent(new KeyEvent(time, time,
-                    KeyEvent.ACTION_UP, msg.arg2, 0, mRecentEvent.getMetaState(),
-                    mRecentEvent.getDeviceId(), 0,
-                    KeyEvent.FLAG_FALLBACK, mRecentEvent.getSource()));
-            Message msgCopy = Message.obtain(msg);
-            // Increase the delay by the decay factor
-            msgCopy.arg1 = (int) Math.ceil(mFlickDecay * msgCopy.arg1);
-            if (msgCopy.arg1 <= mMaxRepeatDelay) {
-                // Send the key again in arg1 milliseconds
-                mHandler.sendMessageDelayed(msgCopy, msgCopy.arg1);
+                    // Increase the delay by the decay factor and resend
+                    final int delay = (int) Math.ceil(mFlickDecay * msg.arg1);
+                    if (delay <= mMaxRepeatDelay) {
+                        Message msgCopy = Message.obtain(msg);
+                        msgCopy.arg1 = delay;
+                        msgCopy.setAsynchronous(true);
+                        mHandler.sendMessageDelayed(msgCopy, delay);
+                    }
+                    break;
+                }
             }
-            return false;
         }
-    });
+    };
 
     public void updateTrackballDirection(ViewRootImpl viewroot, MotionEvent event) {
         // Store what time the touchpad event occurred
@@ -148,7 +152,7 @@
                     mEdgeSwipePossible = true;
                 }
                 // Clear any flings
-                mHandler.removeMessages(FLICK_MSG_ID);
+                mHandler.removeMessages(MSG_FLICK);
 
                 break;
             case MotionEvent.ACTION_MOVE:
@@ -245,15 +249,20 @@
                     if (mMinFlickDistanceSquared <= xMoveSquared + yMoveSquared &&
                             time - mLastTouchPadEventTimeMs <= MAX_TAP_TIME &&
                             mKeySendRateMs <= mMaxRepeatDelay && mKeySendRateMs > 0) {
-                        Message message = Message.obtain(mHandler, FLICK_MSG_ID,
+                        mLastDeviceId = event.getDeviceId();
+                        mLastSource = event.getSource();
+                        mLastMetaState = event.getMetaState();
+
+                        Message message = Message.obtain(mHandler, MSG_FLICK,
                                 mKeySendRateMs, mLastKeySent, viewroot);
-                        mRecentEvent = event;
+                        message.setAsynchronous(true);
                         mHandler.sendMessageDelayed(message, mKeySendRateMs);
                     }
                 }
                 mEdgeSwipePossible = false;
                 break;
         }
+
         // Store touch event position and time
         mLastTouchPadEventTimeMs = time;
         mLastTouchpadXPosition = event.getX();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 61ecc31..080e7c0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -17332,6 +17332,13 @@
          *  <li>{@link android.view.View.MeasureSpec#AT_MOST}</li>
          * </ul>
          *
+         * <p><strong>Note:</strong> On API level 17 and lower, makeMeasureSpec's
+         * implementation was such that the order of arguments did not matter
+         * and overflow in either value could impact the resulting MeasureSpec.
+         * {@link android.widget.RelativeLayout} was affected by this bug.
+         * Apps targeting API levels greater than 17 will get the fixed, more strict
+         * behavior.</p>
+         *
          * @param size the size of the measure specification
          * @param mode the mode of the measure specification
          * @return the measure specification based on size and mode
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index a6b7dba..57bf0d3 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3416,13 +3416,13 @@
                             mTouchModeReset = new Runnable() {
                                 @Override
                                 public void run() {
+                                    mTouchModeReset = null;
                                     mTouchMode = TOUCH_MODE_REST;
                                     child.setPressed(false);
                                     setPressed(false);
                                     if (!mDataChanged) {
                                         performClick.run();
                                     }
-                                    mTouchModeReset = null;
                                 }
                             };
                             postDelayed(mTouchModeReset,
diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java
index f279f8e..a379157 100644
--- a/core/java/android/widget/AbsSpinner.java
+++ b/core/java/android/widget/AbsSpinner.java
@@ -375,7 +375,7 @@
         /**
          * Constructor called from {@link #CREATOR}
          */
-        private SavedState(Parcel in) {
+        SavedState(Parcel in) {
             super(in);
             selectedId = in.readLong();
             position = in.readInt();
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 217bedb..de6ee54 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -36,6 +36,8 @@
 import android.inputmethodservice.ExtractEditText;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.text.DynamicLayout;
@@ -187,6 +189,8 @@
 
     private TextView mTextView;
 
+    private final UserDictionaryListener mUserDictionaryListener = new UserDictionaryListener();
+
     Editor(TextView textView) {
         mTextView = textView;
     }
@@ -2602,6 +2606,11 @@
                 Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
                 intent.putExtra("word", originalText);
                 intent.putExtra("locale", mTextView.getTextServicesLocale().toString());
+                // Put a listener to replace the original text with a word which the user
+                // modified in a user dictionary dialog.
+                mUserDictionaryListener.waitForUserDictionaryAdded(
+                        mTextView, originalText, spanStart, spanEnd);
+                intent.putExtra("listener", new Messenger(mUserDictionaryListener));
                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                 mTextView.getContext().startActivity(intent);
                 // There is no way to know if the word was indeed added. Re-check.
@@ -3815,4 +3824,61 @@
         boolean mContentChanged;
         int mChangedStart, mChangedEnd, mChangedDelta;
     }
+
+    /**
+     * @hide
+     */
+    public static class UserDictionaryListener extends Handler {
+        public TextView mTextView;
+        public String mOriginalWord;
+        public int mWordStart;
+        public int mWordEnd;
+
+        public void waitForUserDictionaryAdded(
+                TextView tv, String originalWord, int spanStart, int spanEnd) {
+            mTextView = tv;
+            mOriginalWord = originalWord;
+            mWordStart = spanStart;
+            mWordEnd = spanEnd;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            final int code = msg.what;
+            if (code == 0) { /* CODE_WORD_ADDED */
+                if (!(msg.obj instanceof Bundle)) {
+                    Log.w(TAG, "Illegal message. Abort handling onUserDictionaryAdded.");
+                    return;
+                }
+                final Bundle bundle = (Bundle)msg.obj;
+                final String originalWord = bundle.getString("originalWord");
+                final String addedWord = bundle.getString("word");
+                onUserDictionaryAdded(originalWord, addedWord);
+            }
+        }
+
+        private void onUserDictionaryAdded(String originalWord, String addedWord) {
+            if (TextUtils.isEmpty(mOriginalWord) || TextUtils.isEmpty(addedWord)) {
+                return;
+            }
+            if (mWordStart < 0 || mWordEnd >= mTextView.length()) {
+                return;
+            }
+            if (!mOriginalWord.equals(originalWord)) {
+                return;
+            }
+            if (originalWord.equals(addedWord)) {
+                return;
+            }
+            final Editable editable = (Editable) mTextView.getText();
+            final String currentWord = editable.toString().substring(mWordStart, mWordEnd);
+            if (!currentWord.equals(originalWord)) {
+                return;
+            }
+            mTextView.replaceText_internal(mWordStart, mWordEnd, addedWord);
+            // Move cursor at the end of the replaced word
+            final int newCursorPosition = mWordStart + addedWord.length();
+            mTextView.setCursorPosition_internal(newCursorPosition, newCursorPosition);
+        }
+    }
 }
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index e0c5bbd..c4ef11c 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -891,7 +891,7 @@
             lp = (Gallery.LayoutParams) generateDefaultLayoutParams();
         }
 
-        addViewInLayout(child, fromLeft != mIsRtl ? -1 : 0, lp);
+        addViewInLayout(child, fromLeft != mIsRtl ? -1 : 0, lp, true);
 
         child.setSelected(offset == 0);
 
diff --git a/core/java/android/widget/HeaderViewListAdapter.java b/core/java/android/widget/HeaderViewListAdapter.java
index e2a269e..0685e61 100644
--- a/core/java/android/widget/HeaderViewListAdapter.java
+++ b/core/java/android/widget/HeaderViewListAdapter.java
@@ -79,7 +79,8 @@
     }
 
     public boolean isEmpty() {
-        return mAdapter == null || mAdapter.isEmpty();
+        return (mAdapter == null || mAdapter.isEmpty())
+	        && getFootersCount() + getHeadersCount() == 0;
     }
 
     private boolean areAllListInfosSelectable(ArrayList<ListView.FixedViewInfo> infos) {
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index aa977a1..b40260c 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -234,8 +234,15 @@
     /**
      * Set this to true if you want the ImageView to adjust its bounds
      * to preserve the aspect ratio of its drawable.
+     *
+     * <p><strong>Note:</strong> If the application targets API level 17 or lower,
+     * adjustViewBounds will allow the drawable to shrink the view bounds, but not grow
+     * to fill available measured space in all cases. This is for compatibility with
+     * legacy {@link android.view.View.MeasureSpec MeasureSpec} and
+     * {@link android.widget.RelativeLayout RelativeLayout} behavior.</p>
+     *
      * @param adjustViewBounds Whether to adjust the bounds of this view
-     * to presrve the original aspect ratio of the drawable
+     * to preserve the original aspect ratio of the drawable.
      * 
      * @see #getAdjustViewBounds()
      *
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 8a09282..e749e63 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -54,6 +54,21 @@
  * {@link #ALIGN_PARENT_BOTTOM}.
  * </p>
  *
+ * <p><strong>Note:</strong> In platform version 17 and lower, RelativeLayout was affected by
+ * a measurement bug that could cause child views to be measured with incorrect
+ * {@link android.view.View.MeasureSpec MeasureSpec} values. (See
+ * {@link android.view.View.MeasureSpec#makeMeasureSpec(int, int) MeasureSpec.makeMeasureSpec}
+ * for more details.) This was triggered when a RelativeLayout container was placed in
+ * a scrolling container, such as a ScrollView or HorizontalScrollView. If a custom view
+ * not equipped to properly measure with the MeasureSpec mode
+ * {@link android.view.View.MeasureSpec#UNSPECIFIED UNSPECIFIED} was placed in a RelativeLayout,
+ * this would silently work anyway as RelativeLayout would pass a very large
+ * {@link android.view.View.MeasureSpec#AT_MOST AT_MOST} MeasureSpec instead.</p>
+ *
+ * <p>This behavior has been preserved for apps that set <code>android:targetSdkVersion="17"</code>
+ * or older in their manifest's <code>uses-sdk</code> tag for compatibility. Apps targeting SDK
+ * version 18 or newer will receive the correct behavior</p>
+ *
  * <p>See the <a href="{@docRoot}guide/topics/ui/layout/relative.html">Relative
  * Layout</a> guide.</p>
  *
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 8d1be53..57e3c8b 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -53,7 +53,6 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 
-
 /**
  * A class that describes a view hierarchy that can be displayed in
  * another process. The hierarchy is inflated from a layout resource
@@ -340,7 +339,7 @@
             if (target == null) return;
 
             if (!mIsWidgetCollectionChild) {
-                Log.e("RemoteViews", "The method setOnClickFillInIntent is available " +
+                Log.e(LOG_TAG, "The method setOnClickFillInIntent is available " +
                         "only from RemoteViewsFactory (ie. on collection items).");
                 return;
             }
@@ -359,13 +358,13 @@
                         if (parent instanceof AppWidgetHostView || parent == null) {
                             // Somehow they've managed to get this far without having
                             // and AdapterView as a parent.
-                            Log.e("RemoteViews", "Collection item doesn't have AdapterView parent");
+                            Log.e(LOG_TAG, "Collection item doesn't have AdapterView parent");
                             return;
                         }
 
                         // Insure that a template pending intent has been set on an ancestor
                         if (!(parent.getTag() instanceof PendingIntent)) {
-                            Log.e("RemoteViews", "Attempting setOnClickFillInIntent without" +
+                            Log.e(LOG_TAG, "Attempting setOnClickFillInIntent without" +
                                     " calling setPendingIntentTemplate on parent.");
                             return;
                         }
@@ -472,7 +471,7 @@
                 av.setOnItemClickListener(listener);
                 av.setTag(pendingIntentTemplate);
             } else {
-                Log.e("RemoteViews", "Cannot setPendingIntentTemplate on a view which is not" +
+                Log.e(LOG_TAG, "Cannot setPendingIntentTemplate on a view which is not" +
                         "an AdapterView (id: " + viewId + ")");
                 return;
             }
@@ -487,6 +486,84 @@
         public final static int TAG = 8;
     }
 
+    private class SetRemoteViewsAdapterList extends Action {
+        public SetRemoteViewsAdapterList(int id, ArrayList<RemoteViews> list) {
+            this.viewId = id;
+            this.list = list;
+        }
+
+        public SetRemoteViewsAdapterList(Parcel parcel) {
+            viewId = parcel.readInt();
+            int count = parcel.readInt();
+            list = new ArrayList<RemoteViews>();
+
+            for (int i = 0; i < count; i++) {
+                RemoteViews rv = RemoteViews.CREATOR.createFromParcel(parcel);
+                list.add(rv);
+            }
+        }
+
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(TAG);
+            dest.writeInt(viewId);
+
+            if (list == null || list.size() == 0) {
+                dest.writeInt(0);
+            } else {
+                int count = list.size();
+                dest.writeInt(count);
+                for (int i = 0; i < count; i++) {
+                    RemoteViews rv = list.get(i);
+                    rv.writeToParcel(dest, flags);
+                }
+            }
+        }
+
+        @Override
+        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
+            final View target = root.findViewById(viewId);
+            if (target == null) return;
+
+            // Ensure that we are applying to an AppWidget root
+            if (!(rootParent instanceof AppWidgetHostView)) {
+                Log.e(LOG_TAG, "SetRemoteViewsAdapterIntent action can only be used for " +
+                        "AppWidgets (root id: " + viewId + ")");
+                return;
+            }
+            // Ensure that we are calling setRemoteAdapter on an AdapterView that supports it
+            if (!(target instanceof AbsListView) && !(target instanceof AdapterViewAnimator)) {
+                Log.e(LOG_TAG, "Cannot setRemoteViewsAdapter on a view which is not " +
+                        "an AbsListView or AdapterViewAnimator (id: " + viewId + ")");
+                return;
+            }
+
+            if (target instanceof AbsListView) {
+                AbsListView v = (AbsListView) target;
+                Adapter a = v.getAdapter();
+                if (a instanceof RemoteViewsListAdapter) {
+                    ((RemoteViewsListAdapter) a).setViewsList(list);
+                } else {
+                    v.setAdapter(new RemoteViewsListAdapter(v.getContext(), list));
+                }
+            } else if (target instanceof AdapterViewAnimator) {
+                AdapterViewAnimator v = (AdapterViewAnimator) target;
+                Adapter a = v.getAdapter();
+                if (a instanceof RemoteViewsListAdapter) {
+                    ((RemoteViewsListAdapter) a).setViewsList(list);
+                } else {
+                    v.setAdapter(new RemoteViewsListAdapter(v.getContext(), list));
+                }
+            }
+        }
+
+        public String getActionName() {
+            return "SetRemoteViewsAdapterList";
+        }
+
+        ArrayList<RemoteViews> list;
+        public final static int TAG = 15;
+    }
+
     private class SetRemoteViewsAdapterIntent extends Action {
         public SetRemoteViewsAdapterIntent(int id, Intent intent) {
             this.viewId = id;
@@ -511,13 +588,13 @@
 
             // Ensure that we are applying to an AppWidget root
             if (!(rootParent instanceof AppWidgetHostView)) {
-                Log.e("RemoteViews", "SetRemoteViewsAdapterIntent action can only be used for " +
+                Log.e(LOG_TAG, "SetRemoteViewsAdapterIntent action can only be used for " +
                         "AppWidgets (root id: " + viewId + ")");
                 return;
             }
             // Ensure that we are calling setRemoteAdapter on an AdapterView that supports it
             if (!(target instanceof AbsListView) && !(target instanceof AdapterViewAnimator)) {
-                Log.e("RemoteViews", "Cannot setRemoteViewsAdapter on a view which is not " +
+                Log.e(LOG_TAG, "Cannot setRemoteViewsAdapter on a view which is not " +
                         "an AbsListView or AdapterViewAnimator (id: " + viewId + ")");
                 return;
             }
@@ -585,7 +662,7 @@
             // If the view is an AdapterView, setting a PendingIntent on click doesn't make much
             // sense, do they mean to set a PendingIntent template for the AdapterView's children?
             if (mIsWidgetCollectionChild) {
-                Log.w("RemoteViews", "Cannot setOnClickPendingIntent for collection item " +
+                Log.w(LOG_TAG, "Cannot setOnClickPendingIntent for collection item " +
                         "(id: " + viewId + ")");
                 ApplicationInfo appInfo = root.getContext().getApplicationInfo();
 
@@ -772,7 +849,7 @@
             try {
                 //noinspection ConstantIfStatement
                 if (false) {
-                    Log.d("RemoteViews", "view: " + klass.getName() + " calling method: "
+                    Log.d(LOG_TAG, "view: " + klass.getName() + " calling method: "
                         + this.methodName + "()");
                 }
                 method.invoke(view);
@@ -945,7 +1022,7 @@
             this.type = in.readInt();
             //noinspection ConstantIfStatement
             if (false) {
-                Log.d("RemoteViews", "read viewId=0x" + Integer.toHexString(this.viewId)
+                Log.d(LOG_TAG, "read viewId=0x" + Integer.toHexString(this.viewId)
                         + " methodName=" + this.methodName + " type=" + this.type);
             }
 
@@ -1012,7 +1089,7 @@
             out.writeInt(this.type);
             //noinspection ConstantIfStatement
             if (false) {
-                Log.d("RemoteViews", "write viewId=0x" + Integer.toHexString(this.viewId)
+                Log.d(LOG_TAG, "write viewId=0x" + Integer.toHexString(this.viewId)
                         + " methodName=" + this.methodName + " type=" + this.type);
             }
 
@@ -1139,7 +1216,7 @@
             try {
                 //noinspection ConstantIfStatement
                 if (false) {
-                    Log.d("RemoteViews", "view: " + klass.getName() + " calling method: "
+                    Log.d(LOG_TAG, "view: " + klass.getName() + " calling method: "
                         + this.methodName + "(" + param.getName() + ") with "
                         + (this.value == null ? "null" : this.value.getClass().getName()));
                 }
@@ -1562,6 +1639,9 @@
                     case BitmapReflectionAction.TAG:
                         mActions.add(new BitmapReflectionAction(parcel));
                         break;
+                    case SetRemoteViewsAdapterList.TAG:
+                        mActions.add(new SetRemoteViewsAdapterList(parcel));
+                        break;
                     default:
                         throw new ActionException("Tag " + tag + " not found");
                     }
@@ -1982,7 +2062,7 @@
      *
      * @param appWidgetId The id of the app widget which contains the specified view. (This
      *      parameter is ignored in this deprecated method)
-     * @param viewId The id of the {@link AbsListView}
+     * @param viewId The id of the {@link AdapterView}
      * @param intent The intent of the service which will be
      *            providing data to the RemoteViewsAdapter
      * @deprecated This method has been deprecated. See
@@ -1997,7 +2077,7 @@
      * Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
      * Can only be used for App Widgets.
      *
-     * @param viewId The id of the {@link AbsListView}
+     * @param viewId The id of the {@link AdapterView}
      * @param intent The intent of the service which will be
      *            providing data to the RemoteViewsAdapter
      */
@@ -2006,6 +2086,25 @@
     }
 
     /**
+     * Creates a simple Adapter for the viewId specified. The viewId must point to an AdapterView,
+     * ie. {@link ListView}, {@link GridView}, {@link StackView} or {@link AdapterViewAnimator}.
+     * This is a simpler but less flexible approach to populating collection widgets. Its use is
+     * encouraged for most scenarios, as long as the total memory within the list of RemoteViews
+     * is relatively small (ie. doesn't contain large or numerous Bitmaps, see {@link
+     * RemoteViews#setImageViewBitmap}). In the case of numerous images, the use of API is still
+     * possible by setting image URIs instead of Bitmaps, see {@link RemoteViews#setImageViewUri}.
+     *
+     * This API is supported in the compatibility library for previous API levels, see
+     * RemoteViewsCompat.
+     *
+     * @param viewId The id of the {@link AdapterView}
+     * @param list The list of RemoteViews which will populate the view specified by viewId.
+     */
+    public void setRemoteAdapter(int viewId, ArrayList<RemoteViews> list) {
+        addAction(new SetRemoteViewsAdapterList(viewId, list));
+    }
+
+    /**
      * Equivalent to calling {@link android.widget.AbsListView#smoothScrollToPosition(int, int)}.
      *
      * @param viewId The id of the view to change
diff --git a/core/java/android/widget/RemoteViewsListAdapter.java b/core/java/android/widget/RemoteViewsListAdapter.java
new file mode 100644
index 0000000..9598771
--- /dev/null
+++ b/core/java/android/widget/RemoteViewsListAdapter.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+
+/**
+ * @hide
+ */
+public class RemoteViewsListAdapter extends BaseAdapter {
+
+    private Context mContext;
+    private ArrayList<RemoteViews> mRemoteViewsList;
+    private ArrayList<Integer> mViewTypes = new ArrayList<Integer>();
+
+    public RemoteViewsListAdapter(Context context, ArrayList<RemoteViews> remoteViews) {
+        mContext = context;
+        mRemoteViewsList = remoteViews;
+        init();
+    }
+
+    public void setViewsList(ArrayList<RemoteViews> remoteViews) {
+        mRemoteViewsList = remoteViews;
+        init();
+        notifyDataSetChanged();
+    }
+
+    private void init() {
+        if (mRemoteViewsList == null) return;
+
+        mViewTypes.clear();
+        for (RemoteViews rv: mRemoteViewsList) {
+            if (!mViewTypes.contains(rv.getLayoutId())) {
+                mViewTypes.add(rv.getLayoutId());
+            }
+        }
+    }
+
+    @Override
+    public int getCount() {
+        if (mRemoteViewsList != null) {
+            return mRemoteViewsList.size();
+        } else {
+            return 0;
+        }
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return null;
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (position < getCount()) {
+            RemoteViews rv = mRemoteViewsList.get(position);
+            View v;
+            if (convertView != null && rv != null &&
+                    convertView.getId() == rv.getLayoutId()) {
+                v = convertView;
+                rv.reapply(mContext, v);
+            } else {
+                v = rv.apply(mContext, parent);
+            }
+            return v;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        if (position < getCount()) {
+            int layoutId = mRemoteViewsList.get(position).getLayoutId();
+            return mViewTypes.indexOf(layoutId);
+        } else {
+            return 0;
+        }
+    }
+
+    public int getViewTypeCount() {
+        return mViewTypes.size();
+    }
+
+    @Override
+    public boolean hasStableIds() {
+        return false;
+    }
+}
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index cd8638da..0281602 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -1247,6 +1247,7 @@
      */
     @Override
     public void onActionViewCollapsed() {
+        setQuery("", false);
         clearFocus();
         updateViewsVisibility(true);
         mQueryTextView.setImeOptions(mCollapsedImeOptions);
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 925864c..fa64fd3 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -25,6 +25,8 @@
 import android.database.DataSetObserver;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.Gravity;
@@ -697,6 +699,69 @@
         return width;
     }
 
+    @Override
+    public Parcelable onSaveInstanceState() {
+        final SavedState ss = new SavedState(super.onSaveInstanceState());
+        ss.showDropdown = mPopup != null && mPopup.isShowing();
+        return ss;
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+
+        super.onRestoreInstanceState(ss.getSuperState());
+
+        if (ss.showDropdown) {
+            ViewTreeObserver vto = getViewTreeObserver();
+            if (vto != null) {
+                final OnGlobalLayoutListener listener = new OnGlobalLayoutListener() {
+                    @Override
+                    public void onGlobalLayout() {
+                        if (!mPopup.isShowing()) {
+                            mPopup.show();
+                        }
+                        final ViewTreeObserver vto = getViewTreeObserver();
+                        if (vto != null) {
+                            vto.removeOnGlobalLayoutListener(this);
+                        }
+                    }
+                };
+                vto.addOnGlobalLayoutListener(listener);
+            }
+        }
+    }
+
+    static class SavedState extends AbsSpinner.SavedState {
+        boolean showDropdown;
+
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        private SavedState(Parcel in) {
+            super(in);
+            showDropdown = in.readByte() != 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            super.writeToParcel(out, flags);
+            out.writeByte((byte) (showDropdown ? 1 : 0));
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+
     /**
      * <p>Wrapper class for an Adapter. Transforms the embedded Adapter instance
      * into a ListAdapter.</p>
@@ -941,8 +1006,7 @@
             mHintText = hintText;
         }
 
-        @Override
-        public void show() {
+        void computeContentWidth() {
             final Drawable background = getBackground();
             int hOffset = 0;
             if (background != null) {
@@ -955,6 +1019,7 @@
             final int spinnerPaddingLeft = Spinner.this.getPaddingLeft();
             final int spinnerPaddingRight = Spinner.this.getPaddingRight();
             final int spinnerWidth = Spinner.this.getWidth();
+
             if (mDropDownWidth == WRAP_CONTENT) {
                 int contentWidth =  measureContentWidth(
                         (SpinnerAdapter) mAdapter, getBackground());
@@ -977,11 +1042,25 @@
                 hOffset += spinnerPaddingLeft;
             }
             setHorizontalOffset(hOffset);
+        }
+
+        @Override
+        public void show() {
+            final boolean wasShowing = isShowing();
+
+            computeContentWidth();
+
             setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
             super.show();
             getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
             setSelection(Spinner.this.getSelectedItemPosition());
 
+            if (wasShowing) {
+                // Skip setting up the layout/dismiss listener below. If we were previously
+                // showing it will still stick around.
+                return;
+            }
+
             // Make sure we hide if our anchor goes away.
             // TODO: This might be appropriate to push all the way down to PopupWindow,
             // but it may have other side effects to investigate first. (Text editing handles, etc.)
@@ -992,6 +1071,12 @@
                     public void onGlobalLayout() {
                         if (!Spinner.this.isVisibleToUser()) {
                             dismiss();
+                        } else {
+                            computeContentWidth();
+
+                            // Use super.show here to update; we don't want to move the selected
+                            // position or adjust other things that would be reset otherwise.
+                            DropdownPopup.super.show();
                         }
                     }
                 };
diff --git a/core/java/com/android/internal/os/HandlerCaller.java b/core/java/com/android/internal/os/HandlerCaller.java
index 84699dc..b442ff5 100644
--- a/core/java/com/android/internal/os/HandlerCaller.java
+++ b/core/java/com/android/internal/os/HandlerCaller.java
@@ -24,38 +24,32 @@
 public class HandlerCaller {
 
     public final Context mContext;
-    
+
     final Looper mMainLooper;
     final Handler mH;
 
     final Callback mCallback;
 
     class MyHandler extends Handler {
-        MyHandler(Looper looper) {
-            super(looper);
+        MyHandler(Looper looper, boolean async) {
+            super(looper, null, async);
         }
-        
+
         @Override
         public void handleMessage(Message msg) {
             mCallback.executeMessage(msg);
         }
     }
-    
+
     public interface Callback {
         public void executeMessage(Message msg);
     }
-    
-    public HandlerCaller(Context context, Callback callback) {
-        mContext = context;
-        mMainLooper = context.getMainLooper();
-        mH = new MyHandler(mMainLooper);
-        mCallback = callback;
-    }
 
-    public HandlerCaller(Context context, Looper looper, Callback callback) {
+    public HandlerCaller(Context context, Looper looper, Callback callback,
+            boolean asyncHandler) {
         mContext = context;
-        mMainLooper = looper;
-        mH = new MyHandler(mMainLooper);
+        mMainLooper = looper != null ? looper : context.getMainLooper();
+        mH = new MyHandler(mMainLooper, asyncHandler);
         mCallback = callback;
     }
 
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 6fb459c..61bc002 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -687,6 +687,7 @@
                 if (mSpinner == null) {
                     mSpinner = new Spinner(mContext, null,
                             com.android.internal.R.attr.actionDropDownStyle);
+                    mSpinner.setId(com.android.internal.R.id.action_bar_spinner);
                     mListNavLayout = new LinearLayout(mContext, null,
                             com.android.internal.R.attr.actionBarTabBarStyle);
                     LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 907b52a..555c7c2 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -123,14 +123,14 @@
      */
     public static final int ID_DEFAULT_STATUS_WIDGET = -2;
 
-    protected final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
-    protected final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
-    protected final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
+    public final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
+    public final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
+    public final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
     public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type";
     public static final String PASSWORD_TYPE_ALTERNATE_KEY = "lockscreen.password_type_alternate";
-    protected final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt";
-    protected final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled";
-    protected final static String LOCKSCREEN_OPTIONS = "lockscreen.options";
+    public final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt";
+    public final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled";
+    public final static String LOCKSCREEN_OPTIONS = "lockscreen.options";
     public final static String LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK
             = "lockscreen.biometric_weak_fallback";
     public final static String BIOMETRIC_WEAK_EVER_CHOSEN_KEY
@@ -138,7 +138,7 @@
     public final static String LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS
             = "lockscreen.power_button_instantly_locks";
 
-    protected final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
+    public final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
 
     private final Context mContext;
     private final ContentResolver mContentResolver;
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 842c557..3315045 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -87,7 +87,7 @@
 {
     sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
     sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
-            new SurfaceTextureClient(surfaceTexture) : NULL);
+            new SurfaceTextureClient(surfaceTexture->getBufferQueue()) : NULL);
     return surfaceTextureClient;
 }
 
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index b1664c6..2b265db 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -627,7 +627,11 @@
         goto exit;
     }
     surfaceTexture = android::SurfaceTexture_getSurfaceTexture(_env, win);
-    window = new android::SurfaceTextureClient(surfaceTexture);
+
+    if (surfaceTexture == NULL)
+        goto not_valid_surface;
+
+    window = new android::SurfaceTextureClient(surfaceTexture->getBufferQueue());
 
     if (window == NULL)
         goto not_valid_surface;
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index a3981ce..6ee504d 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -71,8 +71,8 @@
     // Don't throw NPE -- I feel like it's sort of mean for a logging function
     // to be all crashy if you pass in NULL -- but make the NULL value explicit.
     const char *str = value != NULL ? env->GetStringUTFChars(value, NULL) : "NULL";
-    jint len = strlen(str);
-    const int max = sizeof(buf) - sizeof(len) - 2;  // Type byte, final newline
+    uint32_t len = strlen(str);
+    size_t max = sizeof(buf) - sizeof(len) - 2;  // Type byte, final newline
     if (len > max) len = max;
 
     buf[0] = EVENT_TYPE_STRING;
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 9484c6b..854c9ae 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -102,7 +102,7 @@
         jobject surface) {
 
     sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface));
-    sp<ANativeWindow> window = new SurfaceTextureClient(surfaceTexture);
+    sp<ANativeWindow> window = new SurfaceTextureClient(surfaceTexture->getBufferQueue());
 
     window->incStrong(0);
     SET_INT(textureView, gTextureViewClassInfo.nativeWindow, jint(window.get()));
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index f8904bd..1c9562e 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -355,7 +355,7 @@
     
     sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(_env, native_window));
 
-    window = new SurfaceTextureClient(surfaceTexture);
+    window = new SurfaceTextureClient(surfaceTexture->getBufferQueue());
     if (window == NULL)
         goto not_valid_surface;
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 316de50..9822e63 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -164,9 +164,10 @@
     <protected-broadcast android:name="android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED" />
     <protected-broadcast android:name="android.net.conn.TETHER_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.conn.INET_CONDITION_ACTION" />
-
-
-
+    <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE" />
+    <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE" />
+    <protected-broadcast android:name="android.intent.action.AIRPLANE_MODE" />
+    <protected-broadcast android:name="android.intent.action.ADVANCED_SETTINGS" />
 
     <!-- ====================================== -->
     <!-- Permissions for things that cost money -->
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 563d1a5..6ccc590 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -170,7 +170,7 @@
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Kostenpflichtige Aktionen"</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Ihre Nachrichten"</string>
     <string name="permgroupdesc_messages" msgid="7821999071003699236">"SMS, E-Mails und andere Nachrichten lesen und schreiben"</string>
-    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Ihre persönlichen Informationen"</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Ihre personenbezogenen Daten"</string>
     <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Direkter Zugriff auf Informationen über Sie, die in Ihrer Kontaktkarte gespeichert sind"</string>
     <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ihre sozialen Informationen"</string>
     <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direkter Zugriff auf Informationen über Ihre Kontakte und sozialen Verbindungen"</string>
@@ -375,8 +375,8 @@
     <string name="permlab_movePackage" msgid="3289890271645921411">"App-Ressourcen verschieben"</string>
     <string name="permdesc_movePackage" msgid="319562217778244524">"Ermöglicht der App, App-Ressourcen von internen auf externe Medien zu verschieben und umgekehrt"</string>
     <string name="permlab_readLogs" msgid="6615778543198967614">"Vertrauliche Protokolldaten lesen"</string>
-    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Ermöglicht der App, die verschiedenen Protokolldateien des Systems zu lesen. So können allgemeine Informationen zu den auf Ihrem Tablet durchgeführten Aktionen eingesehen werden, darunter auch persönliche oder geheime Daten."</string>
-    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Ermöglicht der App, die verschiedenen Protokolldateien des Systems zu lesen. So können allgemeine Informationen zu den auf Ihrem Telefon durchgeführten Aktionen eingesehen werden, darunter auch persönliche oder geheime Daten."</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Ermöglicht der App, die verschiedenen Protokolldateien des Systems zu lesen. So können allgemeine Informationen zu den auf Ihrem Tablet durchgeführten Aktionen eingesehen werden, darunter auch personenbezogene oder vertrauliche Daten."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Ermöglicht der App, die verschiedenen Protokolldateien des Systems zu lesen. So können allgemeine Informationen zu den auf Ihrem Telefon durchgeführten Aktionen eingesehen werden, darunter auch personenbezogene oder vertrauliche Daten."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Für Wiedergabe beliebigen Mediendecodierer verwenden"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Ermöglicht der App, alle installierten Mediendecodierer zur Wiedergabe zu verwenden."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Lese-/Schreibberechtigung für zu Diagnosegruppe gehörige Elemente"</string>
@@ -413,9 +413,9 @@
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ermöglicht der App, das Anrufprotokoll Ihres Tablets zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihr Anrufprotokoll löschen oder ändern."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ermöglicht der App, das Anrufprotokoll Ihres Telefons zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihr Anrufprotokoll löschen oder ändern."</string>
     <string name="permlab_readProfile" msgid="4701889852612716678">"Meine Kontaktkarten lesen"</string>
-    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Ermöglicht der App, auf Ihrem Gerät gespeicherte persönliche Profildaten zu lesen, einschließlich Ihres Namens und Ihrer Kontaktdaten. Die App kann Sie somit identifizieren und Ihre Profildaten an andere senden."</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Ermöglicht der App, auf Ihrem Gerät gespeicherte personenbezogene Profildaten zu lesen, einschließlich Ihres Namens und Ihrer Kontaktdaten. Die App kann Sie somit identifizieren und Ihre Profildaten an andere senden."</string>
     <string name="permlab_writeProfile" msgid="907793628777397643">"Meine Kontaktkarten ändern"</string>
-    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ermöglicht der App, auf Ihrem Gerät gespeicherte persönliche Profildaten zu ändern, einschließlich Ihres Namens und Ihrer Kontaktdaten, sowie Daten hinzuzufügen. Die App kann Sie so identifizieren und Ihre Profildaten an andere senden."</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ermöglicht der App, auf Ihrem Gerät gespeicherte personenbezogene Profildaten zu ändern, einschließlich Ihres Namens und Ihrer Kontaktdaten, sowie Daten hinzuzufügen. Die App kann Sie so identifizieren und Ihre Profildaten an andere senden."</string>
     <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"In sozialem Stream lesen"</string>
     <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Ermöglicht der App, auf Updates aus sozialen Netzwerken von Ihnen und Ihren Freunden zuzugreifen und diese zu synchronisieren. Seien Sie vorsichtig, wenn Sie Informationen teilen: Der App wird erlaubt, die Kommunikation zwischen Ihnen und Ihren Freunden in sozialen Netzwerken zu lesen, unabhängig von der Vertraulichkeit der kommunizierten Informationen. Hinweis: Diese Berechtigung kann möglicherweise nicht in allen sozialen Netzwerken erzwungen werden."</string>
     <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"In sozialem Stream schreiben"</string>
@@ -496,7 +496,7 @@
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"Auf Check-in-Eigenschaften zugreifen"</string>
     <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Ermöglicht der App Schreib-/Lesezugriff auf vom Check-in-Service hochgeladene Elemente. Nicht für normale Apps vorgesehen."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"Widgets auswählen"</string>
-    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Ermöglicht der App, dem System zu melden, welche Widgets von welcher App verwendet werden können. Mit dieser Berechtigung können Apps anderen Apps Zugriff auf persönliche Daten gewähren. Nicht für normale Apps vorgesehen."</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Ermöglicht der App, dem System zu melden, welche Widgets von welcher App verwendet werden können. Mit dieser Berechtigung können Apps anderen Apps Zugriff auf personenbezogene Daten gewähren. Nicht für normale Apps vorgesehen."</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"Telefonstatus ändern"</string>
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Ermöglicht der App, die Telefonfunktionen des Geräts zu steuern. Eine App mit dieser Berechtigung kann das Netzwerk wechseln oder das Radio des Telefons ein- und ausschalten, ohne Sie darüber zu informieren."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"Telefonstatus und Identität abrufen"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index a111c4b..c930f02 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -59,7 +59,7 @@
     <string name="BaMmi" msgid="455193067926770581">"Zabrana poziva"</string>
     <string name="PwdMmi" msgid="7043715687905254199">"Promjena zaporke"</string>
     <string name="PinMmi" msgid="3113117780361190304">"PIN je promijenjen"</string>
-    <string name="CnipMmi" msgid="3110534680557857162">"Pozivni je broj prisutan"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Sadržan je pozivni broj"</string>
     <string name="CnirMmi" msgid="3062102121430548731">"Pozivni broj je ograničen"</string>
     <string name="ThreeWCMmi" msgid="9051047170321190368">"Trostrani poziv"</string>
     <string name="RuacMmi" msgid="7827887459138308886">"Odbijanje neželjenih i neugodnih poziva"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 2d15fb3..1b5c6610 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1047,7 +1047,7 @@
     <string name="chooseUsbActivity" msgid="6894748416073583509">"בחר יישום עבור התקן ה-USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"אין יישומים שיכולים לבצע פעולה זו."</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
-    <string name="aerr_application" msgid="932628488013092776">"לצערנו, פעולת ה<xliff:g id="APPLICATION">%1$s</xliff:g> הופסקה."</string>
+    <string name="aerr_application" msgid="932628488013092776">"לצערנו, פעולת <xliff:g id="APPLICATION">%1$s</xliff:g> הופסקה."</string>
     <string name="aerr_process" msgid="4507058997035697579">"לצערנו, התהליך <xliff:g id="PROCESS">%1$s</xliff:g> הופסק."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
     <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> אינו מגיב."\n\n"תרצה לסגור אותו?"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index d8652cd..1239695 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -762,7 +762,7 @@
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Tentar novamente"</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Excedido o n.º máximo de tentativas de Desbloqueio Através do Rosto"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"A carregar, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
-    <string name="lockscreen_charged" msgid="321635745684060624">"Cobrado"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Carregado"</string>
     <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"Ligue o carregador."</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Nenhum cartão SIM"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 51fc346..a949499c 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -492,7 +492,7 @@
     <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"anzisha moja kwa moja usanidi wa simu ya CDMA"</string>
     <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Inaruhusu programu kuanza ugawaji wa CDMA. Programu hasidi zinaweza anza ugawaji wa CDMA usio wa lazima."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"dhibiti arifa za usasishaji mahali"</string>
-    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Inaruhusu programu kuwezesha/kulemeza arifa za usasishaji za eneo kutoka kwa redio. Si ya matumizi na programu za kawaida."</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Huruhusu kuwasha au kuzima arifa za masasisho ya mahali kutoka kwa redio. Sio ya kutumiwa kwenye programu za kawaida."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"fikia mipangilio ya ukaguzi"</string>
     <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Inaruhusu kusoma/kuandika kwa programu kufikia mipangilio iliyopakiwa na huduma ya kuangalia. Si ya matumizi na programu za kawaida."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"chagua wijeti"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 460a811..7ef501f 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1031,4 +1031,7 @@
         <item>150</item>
         <item>100</item>
     </integer-array>
+
+    <!-- Flag indicating if the speed up audio on mt call code should be executed -->
+    <bool name="config_speed_up_audio_on_mt_calls">false</bool>
 </resources>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 547a192..21bae04 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -79,4 +79,5 @@
   <item type="id" name="action_menu_presenter" />
   <item type="id" name="overflow_menu_presenter" />
   <item type="id" name="popup_submenu_presenter" />
+  <item type="id" name="action_bar_spinner" />
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 592ebb7..4c3644c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -218,6 +218,7 @@
   <java-symbol type="id" name="sms_short_code_remember_choice_checkbox" />
   <java-symbol type="id" name="sms_short_code_remember_undo_instruction" />
   <java-symbol type="id" name="breadcrumb_section" />
+  <java-symbol type="id" name="action_bar_spinner" />
 
   <java-symbol type="attr" name="actionModeShareDrawable" />
   <java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -277,6 +278,7 @@
   <java-symbol type="bool" name="config_safe_media_volume_enabled" />
   <java-symbol type="bool" name="config_camera_sound_forced" />
   <java-symbol type="bool" name="config_dontPreferApn" />
+  <java-symbol type="bool" name="config_speed_up_audio_on_mt_calls" />
 
   <java-symbol type="integer" name="config_cursorWindowSize" />
   <java-symbol type="integer" name="config_longPressOnPowerBehavior" />
diff --git a/data/sounds/AudioPackage10.mk b/data/sounds/AudioPackage10.mk
index a930a54..90d8eaa 100755
--- a/data/sounds/AudioPackage10.mk
+++ b/data/sounds/AudioPackage10.mk
@@ -29,6 +29,7 @@
 	$(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
 	$(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)/effects/ogg/WirelessChargingStarted.ogg:system/media/audio/ui/WirelessChargingStarted.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
diff --git a/data/sounds/effects/ogg/LowBattery.ogg b/data/sounds/effects/ogg/LowBattery.ogg
index 710e385..ab9eba3 100644
--- a/data/sounds/effects/ogg/LowBattery.ogg
+++ b/data/sounds/effects/ogg/LowBattery.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/WirelessChargingStarted.ogg b/data/sounds/effects/ogg/WirelessChargingStarted.ogg
new file mode 100644
index 0000000..66f6cd2
--- /dev/null
+++ b/data/sounds/effects/ogg/WirelessChargingStarted.ogg
Binary files differ
diff --git a/docs/downloads/training/ThreadSample.zip b/docs/downloads/training/ThreadSample.zip
new file mode 100644
index 0000000..bdc3ccf
--- /dev/null
+++ b/docs/downloads/training/ThreadSample.zip
Binary files differ
diff --git a/docs/html/google/play/billing/billing_overview.jd b/docs/html/google/play/billing/billing_overview.jd
index 28c3838..aa48fc8 100644
--- a/docs/html/google/play/billing/billing_overview.jd
+++ b/docs/html/google/play/billing/billing_overview.jd
@@ -34,8 +34,8 @@
 </div>
 
 <p>This documentation describes the fundamental In-app Billing components and 
-features that you need to understand in order to implement your own In-app 
-Billing application.</p>
+features that you need to understand in order to add In-app 
+Billing features into your application.</p>
 
 <h2 id="api">In-app Billing API</h2>
 <p>Your application accesses the In-app Billing service using an API that is 
@@ -148,7 +148,7 @@
 complete, the application resumes.
 </p>
 
-<h2>The Sample Applications</h2>
+<h2 id="samples">Sample Applications</h2>
 <p>To help you integrate In-app Billing into your application, the Android SDK 
 provides two sample applications that demonstrate how to sell in-app products 
 from inside an app.</p>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 23c102e..961afda 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -3,42 +3,42 @@
 page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
 
 sdk.win32_bundle_download=adt-bundle-windows-x86.zip
-sdk.win32_bundle_bytes=417851015
-sdk.win32_bundle_checksum=42d9a6c15113d405a97eed05e6d42e2b
+sdk.win32_bundle_bytes=418030942
+sdk.win32_bundle_checksum=ce32861d8f7c93ff6ff6971bd99d228e
 
 sdk.win64_bundle_download=adt-bundle-windows-x86_64.zip
-sdk.win64_bundle_bytes=417851515
-sdk.win64_bundle_checksum=73bdd1168fce0e36a27255a4335c865d
+sdk.win64_bundle_bytes=418155677
+sdk.win64_bundle_checksum=f09aa4557bd1dc2703fde95dcdd6b92e
 
 sdk.mac64_bundle_download=adt-bundle-mac-x86_64.zip
-sdk.mac64_bundle_bytes=382957959
-sdk.mac64_bundle_checksum=a320f8bbaee8572a36e68c434564bdd0
+sdk.mac64_bundle_bytes=383216991
+sdk.mac64_bundle_checksum=ea6c074ee30c426c503dab5c225a5076
 
 sdk.linux32_bundle_download=adt-bundle-linux-x86.zip
-sdk.linux32_bundle_bytes=411065882
-sdk.linux32_bundle_checksum=39687b06fedfea7487ff0824a4d32ee8
+sdk.linux32_bundle_bytes=411205048
+sdk.linux32_bundle_checksum=e64594cd339b8d9a400b9d16c616b3c3
 
 sdk.linux64_bundle_download=adt-bundle-linux-x86_64.zip
-sdk.linux64_bundle_bytes=411217430
-sdk.linux64_bundle_checksum=b0590fe9c1533da9b20ea65525b77677
+sdk.linux64_bundle_bytes=411478695
+sdk.linux64_bundle_checksum=582bfc9083ff4cbcfacc8223bd8c3be1
 
 
 
-sdk.win_installer=installer_r21-windows.exe
-sdk.win_installer_bytes=77523031
-sdk.win_installer_checksum=29ca8cb8f0bc8db627fa2adc2139a3cc
+sdk.win_installer=installer_r21.0.1-windows.exe
+sdk.win_installer_bytes=76520869
+sdk.win_installer_checksum=e2012262471a2583d4a559b15fcf45ff
 
-sdk.win_download=android-sdk_r21-windows.zip
-sdk.win_bytes=99093893
-sdk.win_checksum=7311452823470365f7975a545f8a2be4
+sdk.win_download=android-sdk_r21.0.1-windows.zip
+sdk.win_bytes=99107847
+sdk.win_checksum=613568d774c3bf25c5d24db16601af83
 
-sdk.mac_download=android-sdk_r21-macosx.zip
-sdk.mac_bytes=65792626
-sdk.mac_checksum=67e46adca90dd18d7291443f6c15d6af
+sdk.mac_download=android-sdk_r21.0.1-macosx.zip
+sdk.mac_bytes=65804128
+sdk.mac_checksum=30401c43a014cd5d6ec9d0c62854a1d9
 
-sdk.linux_download=android-sdk_r21-linux.tgz
-sdk.linux_bytes=91378351
-sdk.linux_checksum=7f8d73b629f808cdcfc9f9900bbd7580
+sdk.linux_download=android-sdk_r21.0.1-linux.tgz
+sdk.linux_bytes=91394975
+sdk.linux_checksum=eaa5a8d76d692d1d027f2bbcee019644
 
 
 
@@ -222,7 +222,7 @@
   <input id="32" onclick="onAgreeChecked()" type="radio" name="bit" value="32">
     <label for="32">32-bit</label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
   <input id="64" onclick="onAgreeChecked()" type="radio" name="bit" value="64">
-    <label for="64">64-bit</label>  
+    <label for="64">64-bit</label>
 </p>
 <p><a href="" class="button disabled" id="downloadForRealz" onclick="return onDownloadForRealz(this);"></a></p>
 </div>
@@ -241,7 +241,7 @@
 
 <h1 style="margin-top:0">Get the Android SDK</h1>
 
-  
+
 <p>The Android SDK provides you the API libraries and developer tools necessary to build, test,
   and debug apps for Android.</p>
 
@@ -290,7 +290,7 @@
 
 
 
- 
+
 
 <!-- alternative SDK options -->
 <div class="col-13" style="margin:0;">
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index 93d1db6..efdbd4d 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -1,8 +1,8 @@
 page.title=Installing the Eclipse Plugin
 adt.zip.version=21.0.0
-adt.zip.download=ADT-21.0.0.zip
-adt.zip.bytes=13556487
-adt.zip.checksum=7db4eaae5df6a34fd853317a2bd8250b
+adt.zip.download=ADT-21.0.1.zip
+adt.zip.bytes=13569302
+adt.zip.checksum=acfb01bf3fd1240f1fc21488c3dd16bf
 
 @jd:body
 
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index f2ff07c..243683c 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -57,6 +57,125 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>ADT 21.0.1</a> <em>(December 2012)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+<dl>
+  <dt>Dependencies:</dt>
+
+  <dd>
+    <ul>
+      <li>Java 1.6 or higher is required for ADT 21.0.1.</li>
+      <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 21.0.1.</li>
+      <li>ADT 21.0.1 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK
+      Tools r21.0.1</a>. If you haven't already installed SDK Tools r21.0.1 into your SDK, use the
+      Android SDK Manager to do so.</li>
+    </ul>
+  </dd>
+
+  <dt>General Notes:</dt>
+  <dd>
+    <ul>
+      <li>Build
+        <ul>
+          <li>Updated build to detect and handle package name conflicts between an application and
+            the libraries it depends on. Libraries cannot share package names unless all of them
+            share the same package name.
+            (<a href="http://code.google.com/p/android/issues/detail?id=40152">Issue 40152</a>,
+             <a href="http://code.google.com/p/android/issues/detail?id=40273">Issue 40273</a>)
+          </li>
+          <li>Added a flag to disable dex merging to deal with cases where merging could generate
+            a broken dex file. If this happens to your project, add the following setting to your
+            {@code project.properties} file: {@code dex.disable.merger=true} This setting
+            causes the build system to revert to the older, slower dex processing that does not
+            pre-dex libraries.</li>
+        </ul>
+      </li>
+    </ul>
+  </dd>
+
+  <dt>Bug fixes:</dt>
+  <dd>
+    <ul>
+      <li>Lint
+        <ul>
+          <li>Corrected check for {@code 0px} values in style XML elements.
+            (<a href="http://code.google.com/p/android/issues/detail?id=39601">Issue 39601</a>)
+            </li>
+          <li>Fixed incorrect flagging of formatting strings.
+            (<a href="http://code.google.com/p/android/issues/detail?id=39758">Issue 39758</a>)
+            </li>
+          <li>Fixed problem where {@code tools:ignore} directive in the manifest file was ignored
+            by the Lint tool.
+            (<a href="http://code.google.com/p/android/issues/detail?id=40136">Issue 40136</a>)
+            </li>
+          <li>Fixed problem with flagging a wakelock release inside a conditional.
+            (<a href="http://code.google.com/p/android/issues/detail?id=40424">Issue 40424</a>)
+            </li>
+          <li>Fixed incorrect reporting of missing {@code layout_width} and {@code layout_height}
+            XML fields.
+            (<a href="http://code.google.com/p/android/issues/detail?id=38958">Issue 38958</a>)
+            </li>
+          <li>Fixed handling of custom namespace attributes.</li>
+          <li>Added fixes for filtering out library project warnings.</li>
+          <li>Removed warnings about missing classes before a build.</li>
+        </ul>
+      </li>
+
+      <li>Android Virtual Device Manager
+        <ul>
+          <li>Fixed handling of {@code devices.xml} file in other locales.
+            (<a href="http://code.google.com/p/android/issues/detail?id=39704">Issue 39704</a>)
+            </li>
+          <li>Fixed problem where the AVD Manager would not allow you to create a new AVD using
+            the <strong>4.0" WVGA</strong> or <strong> 4.65" 720p</strong> device definitions.
+            (<a href="http://code.google.com/p/android/issues/detail?id=39939">Issue 39939</a>)
+            </li>
+          <li>Fixed problem where deleted device definitions were not removed.</li>
+          <li>Fixed incorrect screen resolution setting for the Nexus One device definition.</li>
+          <li>Fixed problem where writing of an AVD settings file does not properly escape
+            {@code \\} path characters.</li>
+        </ul>
+      </li>
+
+      <li>Layout Editor
+        <ul>
+          <li>Fixed problem where layout cannot render strings starting with {@code \@}.
+            (<a href="http://code.google.com/p/android/issues/detail?id=40222">Issue 40222</a>)
+            </li>
+          <li>Fixed preview error when using the {@code android:numColumns} attribute in a layout.
+            (<a href="http://code.google.com/p/android/issues/detail?id=21296">Issue 21296</a>)
+            </li>
+          <li>Fixed compatibility issue with IntelliJ layout preview caused by layout editor
+            deleting the {@code .android/devices.xml} file.</li>
+          <li>Added fixes to editor for {@link android.widget.GridLayout}.</li>
+        </ul>
+      </li>
+
+      <li>Added support for {@code ldrtl} and {@code ldltr} resource qualifiers.</li>
+      <li>Fixed problem where Android XML resources mistakenly get compiled into {@code *.out.xml}
+        output files, causing project errors.
+        (<a href="http://code.google.com/p/android/issues/detail?id=3767">Issue 3767</a>)</li>
+      <li>Fixed error which caused resource refresh operations to fail.
+        (<a href="http://code.google.com/p/android/issues/detail?id=39213">Issue 39213</a>)</li>
+      <li>Updated the Custom View code template handle to library projects properly.</li>
+      <li>Fixed support for library string resources ({@code strings.xml}) when exporting an
+        application that references a library with string resources.
+        (<a href="http://code.google.com/p/android/issues/detail?id=39751">Issue 39751</a>)</li>
+      <li>Fixed problem where bad AVD setting files caused Device Manager and graphical XML editors
+        to crash.
+        (<a href="http://code.google.com/p/android/issues/detail?id=40400">Issue 40400</a>)</li>
+    </ul>
+  </dd>
+
+</dl>
+</div>
+</div>
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>ADT 21.0.0</a> <em>(November 2012)</em>
   </p>
 
diff --git a/docs/html/tools/sdk/ndk/index.jd b/docs/html/tools/sdk/ndk/index.jd
index ad4fd7c..f3c9a44 100644
--- a/docs/html/tools/sdk/ndk/index.jd
+++ b/docs/html/tools/sdk/ndk/index.jd
@@ -1,19 +1,18 @@
 ndk=true
 
-ndk.win_download=android-ndk-r8c-windows.zip
-ndk.win_bytes=233787657
-ndk.win_checksum=3ff1570fa4ea865b7702507ea43dbae4
+ndk.win_download=android-ndk-r8d-windows.zip
+ndk.win_bytes=327014028
+ndk.win_checksum=d78ec3d4ec15ad3b18b9f488a5763c23
 
-ndk.mac_download=android-ndk-r8c-darwin-x86.tar.bz2
-ndk.mac_bytes=214270840
-ndk.mac_checksum=74a23e9e058512121835e0d6932e72d5
+ndk.mac_download=android-ndk-r8d-darwin-x86.tar.bz2
+ndk.mac_bytes=308328942
+ndk.mac_checksum=5cd9ef9fb7e03943ee8c9e147e42e571
 
-ndk.linux_download=android-ndk-r8c-linux-x86.tar.bz2
-ndk.linux_bytes=179945337
-ndk.linux_checksum=b0851346ff90c9266bc050016a228319
+ndk.linux_download=android-ndk-r8d-linux-x86.tar.bz2
+ndk.linux_bytes=254644383
+ndk.linux_checksum=e1fa0379a3feb59f2f0865f1a90bd382
 
 page.title=Android NDK
-
 @jd:body
 
 
@@ -250,6 +249,170 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt="">Android NDK, Revision 8d</a> <em>(December 2012)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+    <dl>
+      <dt>Important changes:</dt>
+      <dd>
+        <ul>
+          <li>Added the GNU Compiler Collection (GCC) 4.7 compiler to the NDK. The GCC 4.6 compiler
+            is still the default, so you must to explicitly enable the new version as follows:
+            <ul>
+              <li>For {@code ndk-build}, export the {@code NDK_TOOLCHAIN_VERSION=4.7} variable
+                <em>or</em> add it to {@code Application.mk}.</li>
+              <li>For standalone builds, add the {@code --toolchain=} option to
+                {@code make-standalone-toolchain.sh}, for example:
+                <pre>--toolchain=arm-linux-androideabi-4.7</pre></li>
+            </ul>
+            <p class="note">
+              <strong>Note:</strong> This feature is experimental. Please try it and
+              <a href="http://code.google.com/p/android/issues/list">report any issues</a>.</p>
+          </li>
+          <li>Added {@code stlport} exception support via gabi++.  Note that the new gabi++
+            depends on {@code dlopen} and related code, meaning that:
+            <ul>
+              <li>You can no longer build a <em>static</em> executable using the {@code -static}
+                option or include {@code libstlport_static.a} using
+                {@code APP_STL := stlport_static}. (You can still use the {@code -static} option
+                with a standalone toolchain.) Compiling a <em>dynamic</em> executable using
+                {@code include $(BUILD_EXECUTABLE)} continues to work because the compiler
+                automatically adds the {@code -ldl} option.</li>
+              <li>If your project links using {@code -nostdlib} and {-Wl,--no-undefined}, you
+                must manually include the {@code -ldl} option.</li>
+            </ul>
+              For more information, see {@code CPLUSPLUS-SUPPORT.html}.
+
+              <p class="note">
+                <strong>Note:</strong> This feature is experimental and works better with the GCC
+                4.6/4.7 compilers than with GCC 4.4.3 or Clang 3.1. Please try it and
+                <a href="http://code.google.com/p/android/issues/list">report any issues</a>.</p>
+          </li>
+          <li>Added a {@code -mstack-protector-guard=} option for x86 to choose between a
+            <em>global</em> default path which is compatible with older Android C library (bionic)
+            and a new <em>tls</em> path (%gs:20) for {@code -fstack-protector},
+            {@code -fstack-protector-all} and {@code -fstack-protector-strong} using the GCC 4.6
+            and higher compilers.
+
+            <p class="note">
+              <strong>Note:</strong> The {@code -mstack-protector-guard} setting itself does not
+              enable any {@code -fstack-protector*} options.</p>
+          </li>
+          <li>Added {@code android_setCpu()} function to
+            {@code sources/android/cpufeatures/cpu-features.c} for use when auto-detection via
+            {@code /proc} is not possible in Android 4.1 and higher.
+            (<a href="http://code.google.com/p/chromium/issues/detail?id=164154">Chromium Issue
+            164154</a>)</li>
+        </ul>
+      </dd>
+
+      <dt>Important bug fixes:</dt>
+      <dd>
+        <ul>
+          <li>Fixed unnecessary rebuild of object files when using the {@code ndk-build} script.
+            (<a href="http://code.google.com/p/android/issues/detail?id=39810">Issue 39810</a>)</li>
+          <li>Fixed a linker failure with the NDK 8c release for Mac OS X 10.6.x that produced the
+            following error:
+            <pre>
+dyld: lazy symbol binding failed: Symbol not found: _memmem
+Referenced from: ...../arm-linux-androideabi/bin/ld
+Expected in: /usr/lib/libSystem.B.dylib</pre>
+            This problem was caused by building on Mac OS X 10.7, which produced binaries that were
+            not compatible with Mac OS 10.6.x and the NDK.
+          </li>
+          <li>Removed the {@code -x c++} options from the Clang++ standalone build script.
+          (<a href="http://code.google.com/p/android/issues/detail?id=39089">Issue 39089</a>)</li>
+          <li>Fixed issues using the {@code NDK_TOOLCHAIN_VERSION=clang3.1} option in Cygwin.
+           (<a href="http://code.google.com/p/android/issues/detail?id=39585">Issue 39585</a>)</li>
+          <li>Fixed the {@code make-standalone-toolchain.sh} script to allow generation of a
+            standalone toolchain using the Cygwin or MinGW environments. The resulting toolchain
+            can be used in Cygwin, MingGW or CMD.exe environments.
+            (<a href="http://code.google.com/p/android/issues/detail?id=39915">Issue 39915</a>,
+            <a href="http://code.google.com/p/android/issues/detail?id=39585">Issue 39585</a>)</li>
+          <li>Added missing {@code SL_IID_ANDROIDBUFFERQUEUESOURCE} option in android-14 builds for
+            ARM and X86.
+            (<a href="http://code.google.com/p/android/issues/detail?id=40625">Issue 40625</a>)</li>
+          <li>Fixed x86 CPU detection for the {@code ANDROID_CPU_X86_FEATURE_MOVBE} feature.
+            (<a href="http://code.google.com/p/android/issues/detail?id=39317">Issue 39317</a>)</li>
+          <li>Fixed an issue preventing the Standard Template Library (STL) from using C++
+            sources that do not have a {@code .cpp} file extension.</li>
+          <li>Fixed GCC 4.6 ARM internal compiler error <em>at reload1.c:1061</em>.
+            (<a href="http://code.google.com/p/android/issues/detail?id=20862">Issue 20862</a>)</li>
+          <li>Fixed GCC 4.4.3 ARM internal compiler error <em>at emit-rtl.c:1954</em>.
+            (<a href="http://code.google.com/p/android/issues/detail?id=22336">Issue 22336</a>)</li>
+          <li>Fixed GCC 4.4.3 ARM internal compiler error <em>at postreload.c:396</em>.
+            (<a href="http://code.google.com/p/android/issues/detail?id=22345">Issue 22345</a>)</li>
+          <li>Fixed problem with GCC 4.6/4.7 skipping lambda functions.
+            (<a href="http://code.google.com/p/android/issues/detail?id=35933">Issue 35933</a>)</li>
+        </ul>
+      </dd>
+
+      <dt>Other bug fixes:</dt>
+      <dd>
+        <ul>
+          <li>NDK header file fixes:
+            <ul>
+              <li>Fixed {@code __WINT_TYPE__} and {@code wint_t} to be the same type.</li>
+              <li>Corrected typo in {@code android/bitmap.h}.
+                (<a href="http://code.google.com/p/android/issues/detail?id=15134">Issue 15134</a>)
+              </li>
+              <li>Corrected typo in {@code errno.h}.</li>
+              <li>Added check for the presence of {@code __STDC_VERSION__} in {@code sys/cdefs.h}.
+                (<a href="http://code.google.com/p/android/issues/detail?id=14627">Issue 14627</a>)
+              </li>
+              <li>Reorganized headers in {@code byteswap.h} and {@code dirent.h}.</li>
+              <li>Fixed {@code limits.h} to include {@code page.h} which provides {@code PAGE_SIZE}
+                settings.
+                (<a href="http://code.google.com/p/android/issues/detail?id=39983">Issue 39983</a>)
+              </li>
+              <li>Fixed return type of {@code glGetAttribLocation()} and
+                {@code glGetUniformLocation()} from {@code int} to {@code GLint}.</li>
+              <li>Fixed {@code __BYTE_ORDER} constant for x86 builds.
+                (<a href="http://code.google.com/p/android/issues/detail?id=39824">Issue 39824</a>)
+              </li>
+            </ul>
+          </li>
+          <li>Fixed {@code ndk-build} script to not overwrite {@code -Os} with {@code -O2} for ARM
+            builds.</li>
+          <li>Fixed build scripts to allow overwriting of {@code HOST_AWK}, {@code HOST_SED}, and
+            {@code HOST_MAKE} settings.</li>
+          <li>Fixed issue for {@code ld.gold} on {@code fsck_msdos} builds linking objects built by
+            the Intel C/C++ compiler (ICC).</li>
+          <li>Fixed ARM EHABI support in Clang to conform to specifications.</li>
+          <li>Fixed GNU Debugger (GDB) to shorten the time spent on walking the target's link map
+            during {@code solib} events.
+            (<a href="http://code.google.com/p/android/issues/detail?id=38402">Issue 38402</a>)</li>
+          <li>Fixed missing {@code libgcc.a} file when linking shared libraries.</li>
+        </ul>
+      </dd>
+
+      <dt>Other changes:</dt>
+      <dd>
+        <ul>
+          <li>Backported 64-bit built-in atomic functions for ARM to GCC 4.6.</li>
+          <li>Added documentation for audio output latency, along with other documentation and
+            fixes.</li>
+          <li>Fixed debug builds with Clang so that non-void functions now raise a {@code SIGILL}
+            signal for paths without a return statement.</li>
+          <li>Updated {@code make-standalone-toolchain.sh} to accept the suffix {@code -clang3.1}
+            which is equivalent to adding {@code --llvm-version=3.1} to the GCC 4.6 toolchain.</li>
+          <li>Updated GCC and Clang bug report URL to:
+            <a href="http://source.android.com/source/report-bugs.html">http://source.android.com/source/report-bugs.html</a></li>
+          <li>Added ARM ELF support to {@code llvm-objdump}.</li>
+          <li>Suppressed <em>treating c input as c++</em> warning for Clang builds.</li>
+          <li>Updated build so that only the 32-bit version of {@code libiberty.a} is built and
+            placed in {@code lib32/}.</li>
+        </ul>
+      </dd>
+    </dl>
+  </div>
+</div>
+
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt="">Android NDK, Revision 8c</a> <em>(November 2012)</em>
   </p>
 
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index a5dfa5a..9349a4e 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -28,6 +28,109 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>SDK Tools, Revision 21.0.1</a> <em>(December 2012)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+    <dd>
+      <ul>
+        <li>Android SDK Platform-tools revision 16 or later.</li>
+        <li>If you are developing in Eclipse with ADT, note that the SDK Tools r21.0.1 is
+          designed for use with ADT 21.0.1 and later. If you haven't already, update your
+        <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 21.0.0.</li>
+        <li>If you are developing outside Eclipse, you must have
+          <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
+    </ul>
+    </dd>
+
+    <dt>General Notes:</dt>
+    <dd>
+      <ul>
+        <li>Build
+          <ul>
+            <li>Updated build to detect and handle package name conflicts between an application and
+              the libraries it depends on. Libraries cannot share package names unless all of them
+              share the same package name.
+              (<a href="http://code.google.com/p/android/issues/detail?id=40152">Issue 40152</a>,
+               <a href="http://code.google.com/p/android/issues/detail?id=40273">Issue 40273</a>)
+            </li>
+            <li>Added a flag to disable dex merging to deal with cases where merging could generate
+              a broken dex file. If this happens to your project, add the following setting to your
+              {@code project.properties} file: {@code dex.disable.merger=true} This setting
+              causes the build system to revert to the older, slower dex processing that does not
+              pre-dex libraries.</li>
+          </ul>
+        </li>
+
+        <li>Renderscript
+          <ul>
+            <li>Added support for
+              <a href="{@docRoot}guide/topics/renderscript/compute.html#filterscript">Filterscript</a>
+              compilation.</li>
+            <li>Added new project setting to control the Renderscript compilation target separately
+              from an Android project. Adding the following line to a {@code project.properties}
+              file causes Renderscript code to be compiled for Android API Level 17, while the
+              containing application can target a different (lower) API level:
+              <pre>renderscript.target = 17</pre>
+              Previously, the Renderscript compilation target was tied to the
+              {@code android:minSdkVersion} setting in the manifest.
+              (<a href="http://code.google.com/p/android/issues/detail?id=40487">Issue 40487</a>)
+            </li>
+          </ul>
+        </li>
+
+      </ul>
+    </dd>
+
+
+    <dt>Bug fixes:</dt>
+    <dd>
+      <ul>
+        <li>Lint
+          <ul>
+            <li>Corrected check for {@code 0px} values in style XML elements.
+              (<a href="http://code.google.com/p/android/issues/detail?id=39601">Issue 39601</a>)
+              </li>
+            <li>Fixed incorrect flagging of formatting strings.
+              (<a href="http://code.google.com/p/android/issues/detail?id=39758">Issue 39758</a>)
+              </li>
+            <li>Fixed problem where {@code tools:ignore} directive in the manifest file was ignored
+              by the Lint tool.
+              (<a href="http://code.google.com/p/android/issues/detail?id=40136">Issue 40136</a>)
+              </li>
+            <li>Fixed problem with flagging a wakelock release inside a conditional.
+              (<a href="http://code.google.com/p/android/issues/detail?id=40424">Issue 40424</a>)
+              </li>
+            <li>Fixed incorrect reporting of missing {@code layout_width} and {@code layout_height}
+              XML fields.
+              (<a href="http://code.google.com/p/android/issues/detail?id=38958">Issue 38958</a>)
+              </li>
+            <li>Fixed handling of custom namespace attributes.</li>
+            <li>Added fixes for filtering out library project warnings.</li>
+            <li>Removed warnings about missing classes before a build.</li>
+          </ul>
+        </li>
+
+        <li>Fixed problem with UI Automator Viewer execution script where Android tools directory
+          is not set.</li>
+        <li>Fixed problem with the SDK Manager so that it auto-selects the most recently released
+          platform on startup.</li>
+        <li>Fixed Java finding script to look for the currently supported version of Java (1.6 or
+          higher).</li>
+        <li>Fixed the SDK Manager launcher in the ADT bundle so that it can properly launch the
+          SDK Manager program when it is placed at the root of the bundle.</li>
+      </ul>
+    </dd>
+    </dl>
+  </div>
+</div>
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>SDK Tools, Revision 21</a> <em>(November 2012)</em>
   </p>
 
@@ -37,14 +140,15 @@
     <dt>Dependencies:</dt>
     <dd>
       <ul>
-        <li>Android SDK Platform-tools revision 15 or later.</li>
+        <li>Android SDK Platform-tools revision 16 or later.</li>
         <li>If you are developing in Eclipse with ADT, note that the SDK Tools r21 is designed
         for use with ADT 21.0.0 and later. If you haven't already, update your
         <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 21.0.0.</li>
         <li>If you are developing outside Eclipse, you must have
           <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
-    </ul>
+      </ul>
     </dd>
+
     <dt>General Notes:</dt>
     <dd>
       <ul>
@@ -827,7 +931,7 @@
 </ul>
 </dd>
 </dl>
- </div>
+</div>
 </div>
 
 <div class="toggle-content closed">
@@ -861,7 +965,7 @@
 </ul>
 </dd>
 </dl>
- </div>
+</div>
 </div>
 
 <div class="toggle-content closed">
@@ -892,7 +996,7 @@
 provides the equivalent library project support.</p>
 </dd>
 </dl>
- </div>
+</div>
 </div>
 
 <div class="toggle-content closed">
@@ -941,7 +1045,7 @@
 </ul>
 </dd>
 </dl>
- </div>
+</div>
 </div>
 
 <div class="toggle-content closed">
@@ -991,7 +1095,7 @@
 </ul>
 </dd>
 </dl>
- </div>
+</div>
 </div>
 
 <div class="toggle-content closed">
@@ -1055,6 +1159,6 @@
 href="/tools/help/layoutopt.html">layoutopt</a>.</p>
 </dd>
 </dl>
- </div>
+</div>
 </div>
 
diff --git a/docs/html/training/improving-layouts/reusing-layouts.jd b/docs/html/training/improving-layouts/reusing-layouts.jd
index fdd3333..87431d3 100644
--- a/docs/html/training/improving-layouts/reusing-layouts.jd
+++ b/docs/html/training/improving-layouts/reusing-layouts.jd
@@ -109,6 +109,10 @@
          layout=”@layout/title”/>
 </pre>
 
+<p>However, if you want to override layout attributes using
+the <code>&lt;include&gt;</code> tag, you must override both
+<code>android:layout_height</code> and <code>android:layout_width</code> in order for
+other layout attributes to take effect.</p>
 
 
 <h2 id="Merge">Use the &lt;merge&gt; Tag</h2>
diff --git a/docs/html/training/load-data-background/define-launch-query.jd b/docs/html/training/load-data-background/define-launch-query.jd
deleted file mode 100644
index f7978f4..0000000
--- a/docs/html/training/load-data-background/define-launch-query.jd
+++ /dev/null
@@ -1,83 +0,0 @@
-page.title=Defining and Launching the Query
-trainingnavtop=true
-startpage=true
-
-@jd:body
-
-<!-- This is the training bar -->
-<div id="tb-wrapper">
-  <div id="tb">
-<h2>This lesson teaches you to</h2>
-<ol>
-    <li>
-        <a href="#DefineLaunch">Define and Launch the Query</a>
-    </li>
-</ol>
-  </div>
-</div>
-
-<p>
-    To perform a query, create the {@link android.support.v4.content.CursorLoader}, set up its
-    query, and pass it to the loader framework. From then on, the framework manages everything.
-    It runs the query on a background thread, returns the results to the foreground, and
-    watches for changes to the data associated with the query.
-</p>
-<p>
-    Pass a {@link android.support.v4.content.CursorLoader} to the loader framework in
-    your implementation of
-    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}.
-    The loader framework calls this method when you <i>create</i> a loader by calling
-    {@link android.support.v4.app.LoaderManager#initLoader initLoader()}. You can create
-    a {@link android.support.v4.content.CursorLoader} anywhere,
-    but the preferred way is to create it in
-    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()},
-    because this defers creation until the object is actually needed.
-</p>
-<p>
-    Notice that {@link android.support.v4.app.LoaderManager#initLoader initLoader()} will only
-    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}
-    if the {@link android.support.v4.content.CursorLoader} doesn't already exist; otherwise, it
-    re-uses the existing {@link android.support.v4.content.CursorLoader}. The loader framework
-    tracks {@link android.support.v4.content.CursorLoader} instance using the <code>id</code>
-    value passed to {@link android.support.v4.app.LoaderManager#initLoader initLoader()}.
-</p>
-<h2 id="DefineLaunch">Define and Launch the Query</h2>
-<p>
-    To create a {@link android.support.v4.content.CursorLoader} and define its
-    query at the same time, call the constructor
-{@link android.support.v4.content.CursorLoader#CursorLoader(Context, Uri, String[], String, String[], String)
-    CursorLoader(context, uri, projection, selection, selectionArgs, sortOrder)}. The
-    <code>context</code> and <code>uri</code> arguments are required, but the others are optional.
-    To use the default value for an optional argument, pass in <code>null</code>. The
-    {@link android.support.v4.content.CursorLoader} runs the query against the
-    {@link android.content.ContentProvider} identified by <code>uri</code>, just as if you had
-    called {@link android.content.ContentResolver#query ContentResolver.query()} with the same
-    arguments.
-</p>
-<p>
-    For example:
-</p>
-<pre>
-public Loader&lt;Cursor&gt; onCreateLoader(int loaderID, Bundle bundle)
-{
-    /*
-     * Takes action based on the ID of the Loader that's being created
-     */
-    switch (loaderID) {
-        case URL_LOADER:
-            /*
-             * Return a new CursorLoader
-             */
-            return new CursorLoader(
-                this,                           // Context
-                DataProviderContract.IMAGE_URI, // Provider's content URI
-                PROJECTION,                     // Columns to return
-                null,                           // Return all rows
-                null,                           // No search arguments
-                null);                          // Default search order
-        default:
-            // An invalid id was passed in
-            return null;
-    }
-}
-</pre>
diff --git a/docs/html/training/load-data-background/handle-results.jd b/docs/html/training/load-data-background/handle-results.jd
index f8e003a..ce0024f 100644
--- a/docs/html/training/load-data-background/handle-results.jd
+++ b/docs/html/training/load-data-background/handle-results.jd
@@ -13,92 +13,125 @@
     <a href="#HandleResults">Handle Query Results</a>
   </li>
   <li>
-    <a href="#HandleReset">Clear Out Old Data</a></li>
+    <a href="#HandleReset">Delete Old Cursor References</a></li>
 </ol>
+
+<h2>Try it out</h2>
+<div class="download-box">
+    <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a>
+    <p class="filename">ThreadSample.zip</p>
+</div>
+
   </div>
 </div>
 
 <p>
-    {@link android.support.v4.content.CursorLoader} returns its query results to your
-    implementation of
-    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished
-    LoaderCallbacks.onLoadFinished()}, in the form of a {@link android.database.Cursor}. In the
-    callback, you can update your data display, do further processing on the
-    {@link android.database.Cursor} data, and so forth.
+    As shown in the previous lesson, you should begin loading your data with a
+    {@link android.support.v4.content.CursorLoader} in your implementation of
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader
+    onCreateLoader()}. The loader then provides the query results to your
+    {@link android.app.Activity} or {@link android.support.v4.app.FragmentActivity} in your
+    implementation of {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished
+    LoaderCallbacks.onLoadFinished()}. One of the incoming arguments to this method is a
+    {@link android.database.Cursor} containing the query results. You can use this object to
+    update your data display or do further processing.
 </p>
 <p>
-    When the loader framework detects changes to data associated with the query,
-    it resets the {@link android.support.v4.content.CursorLoader}, closes the current
-    {@link android.database.Cursor}, and then invokes your implementation of
+    Besides
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} and
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()},
+    you also have to implement
     {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}.
-    Use this callback to delete references to the current {@link android.database.Cursor}; when the
-    loader framework destroys the {@link android.database.Cursor}, you won't have outstanding
-    references that cause memory leaks.
+    This method is invoked when {@link android.support.v4.content.CursorLoader} detects
+    that data associated with the {@link android.database.Cursor} has changed. When the
+    data changes, the framework also re-runs the current query.
 </p>
-<h2 id="HandleFinished">Handle Query Results</h2>
+<h2 id="HandleResults">Handle Query Results</h2>
 <p>
-    The following two snippets are an example of displaying the results of a query, using a
-    {@link android.widget.ListView} backed by a
-    {@link android.support.v4.widget.SimpleCursorAdapter}.
+    To display {@link android.database.Cursor} data returned by
+    {@link android.support.v4.content.CursorLoader}, use a
+    {@link android.view.View} class that implements {@link android.widget.AdapterView} and
+    provide the view with an adapter that implements
+    {@link android.support.v4.widget.CursorAdapter}. The system then automatically moves data from
+    the {@link android.database.Cursor} to the view.
 </p>
 <p>
-    The first snippet shows the {@link android.widget.ListView} and
-    {@link android.support.v4.widget.SimpleCursorAdapter}:
-</p>
-<pre>
-// Gets a handle to the Android built-in ListView widget
-mListView = ((ListView) findViewById(android.R.id.list));
-// Creates a CursorAdapter
-mAdapter =
-    new SimpleCursorAdapter(
-    this,                   // Current context
-    R.layout.logitem,       // View for each item in the list
-    null,                   // Don't provide the cursor yet
-    FROM_COLUMNS,           // List of cursor columns to display
-    TO_FIELDS,              // List of TextViews in each line
-    0                       // flags
-);
-// Links the adapter to the ListView
-mListView.setAdapter(mAdapter);
-</pre>
-<p>
-    The next snippet shows an implementation of
+    You can set up the linkage between the view and adapter before you have any data to display,
+    and then move a {@link android.database.Cursor} into the adapter in the
     {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}
-    that moves the query results in the returned {@link android.database.Cursor} to the
-    {@link android.support.v4.widget.SimpleCursorAdapter}. Changing the
-    {@link android.database.Cursor} in the
-    {@link android.support.v4.widget.SimpleCursorAdapter} triggers a refresh of the
-    {@link android.widget.ListView} with the new data:
-</p>
-<pre>
-public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor cursor)
-{
-    /*
-     * Move the results into the adapter. This
-     * triggers the ListView to re-display.
-     */
-    mAdapter.swapCursor(cursor);
-}
-</pre>
-<h2 id="HandleReset">Handle a Loader Reset</h2>
-<p>
-    The loader framework resets the {@link android.support.v4.content.CursorLoader} whenever the
-    {@link android.database.Cursor} becomes invalid. This usually occurs because the data associated
-    with the {@link android.database.Cursor} has changed. Before re-running the query,
-    the framework calls your implementation of
-    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}. In
-    this callback, make sure to prevent memory leaks by deleting all references to the current
-    {@link android.database.Cursor}. Once you return from
-    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()},
-    the loader framework re-runs the query.
+    method. As soon as you move the {@link android.database.Cursor} into the adapter, the
+    system automatically updates the view. This also happens if you change the contents of the
+    {@link android.database.Cursor}.
 </p>
 <p>
     For example:
 </p>
 <pre>
-public void onLoaderReset(Loader&lt;Cursor&gt; loader)
-{
-    // Remove the reference to the current Cursor
-    mAdapter.swapCursor(null);
+public String[] mFromColumns = {
+    DataProviderContract.IMAGE_PICTURENAME_COLUMN
+};
+public int[] mToFields = {
+    R.id.PictureName
+};
+// Gets a handle to a List View
+ListView mListView = (ListView) findViewById(R.id.dataList);
+/*
+ * Defines a SimpleCursorAdapter for the ListView
+ *
+ */
+SimpleCursorAdapter mAdapter =
+    new SimpleCursorAdapter(
+            this,                // Current context
+            R.layout.list_item,  // Layout for a single row
+            null,                // No Cursor yet
+            mFromColumns,        // Cursor columns to use
+            mToFields,           // Layout fields to use
+            0                    // No flags
+    );
+// Sets the adapter for the view
+mListView.setAdapter(mAdapter);
+...
+/*
+ * Defines the callback that {@link android.support.v4.content.CursorLoader} calls
+ * when it's finished its query
+ */
+&#64;Override
+public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor cursor) {
+    ...
+    /*
+     * Moves the query results into the adapter, causing the
+     * ListView fronting this adapter to re-display
+     */
+    mAdapter.changeCursor(cursor);
+}
+</pre>
+<h2 id="HandleReset">Delete Old Cursor References</h2>
+<p>
+    The {@link android.support.v4.content.CursorLoader} is reset whenever its
+    {@link android.database.Cursor} becomes invalid. This usually occurs because the data associated
+    with the {@link android.database.Cursor} has changed. Before re-running the query,
+    the framework calls your implementation of
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}. In
+    this callback, you should delete all references to the current {@link android.database.Cursor}
+    in order to prevent memory leaks. Once
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}
+    finishes, {@link android.support.v4.content.CursorLoader} re-runs its query.
+</p>
+<p>
+    For example:
+</p>
+<pre>
+/*
+ * Invoked when the CursorLoader is being reset. For example, this is
+ * called if the data in the provider changes and the Cursor becomes stale.
+ */
+&#64;Override
+public void onLoaderReset(Loader&lt;Cursor&gt; loader) {
+    
+    /*
+     * Clears out the adapter's reference to the Cursor.
+     * This prevents memory leaks.
+     */
+    mAdapter.changeCursor(null);
 }
 </pre>
diff --git a/docs/html/training/load-data-background/index.jd b/docs/html/training/load-data-background/index.jd
index 574a32c..dc9d84a 100644
--- a/docs/html/training/load-data-background/index.jd
+++ b/docs/html/training/load-data-background/index.jd
@@ -8,22 +8,11 @@
 
 <!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
 <h2>Dependencies and prerequisites</h2>
-<h3>Dependencies</h3>
 <ul>
     <li>
         Android 1.6 or later
     </li>
 </ul>
-<h3>Prerequisites</h3>
-<ul>
-    <li>
-        <a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a> class
-    </li>
-    <li>
-        <a href="{@docRoot}training/basics/activity-lifecycle/index.html">
-        Managing the Activity Lifecycle</a> class
-    </li>
-</ul>
 
 <!-- related docs (NOT javadocs) -->
 <h2>You should also read</h2>
@@ -38,71 +27,42 @@
 <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">Content Provider Basics</a>
     </li>
 </ul>
+
+<h2>Try it out</h2>
+<div class="download-box">
+    <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a>
+    <p class="filename">ThreadSample.zip</p>
+</div>
+
 </div>
 </div>
 <p>
-    A {@link android.support.v4.content.CursorLoader} runs a query against a
-    {@link android.content.ContentProvider} on a background thread and returns a
-    {@link android.database.Cursor} to the main thread.
+    Querying a {@link android.content.ContentProvider} for data you want to display takes time.
+    If you run the query directly from an {@link android.app.Activity}, it may get blocked and
+    cause the system to issue an "Application Not Responding" message. Even if it doesn't, users
+    will see an annoying delay in the UI. To avoid these problems, you should initiate a query on a
+    separate thread, wait for it to finish, and then display the results.
 </p>
 <p>
-    {@link android.support.v4.content.CursorLoader} has these advantages over alternate ways of
-    running a query:
-</p>
-<dl>
-    <dt>
-        Query on a background thread
-    </dt>
-    <dd>
-        A {@link android.support.v4.content.CursorLoader} query runs asynchronously on a
-        background thread, so it doesn't cause "Application Not Responding" (ANR) errors on the UI
-        thread. {@link android.support.v4.content.CursorLoader} creates and starts the
-        background thread; all you have to do is initialize the loader framework and handle the
-        results of the query.
-    </dd>
-    <dt>
-        Automatic re-query
-    </dt>
-    <dd>
-        A {@link android.support.v4.content.CursorLoader} automatically runs a new query when
-        the loader framework detects that the data underlying the {@link android.database.Cursor}
-        has changed.
-    </dd>
-    <dt>
-        Simple API
-    </dt>
-    <dd>
-        The {@link android.support.v4.content.CursorLoader} API provides the
-        query framework and cursor monitoring that you would have to define yourself if you used
-        {@link android.os.AsyncTask}.
-    </dd>
-</dl>
-<p>
-    A {@link android.support.v4.content.CursorLoader} is limited in that the query must be
-    against a {@link android.net.Uri} and must return a {@link android.database.Cursor}. Because of
-    this, a {@link android.support.v4.content.CursorLoader} can only run a query against a
-    {@link android.content.ContentProvider}.
+    You can do this in a straightforward way by using an object that runs a query asynchronously in
+    the background and reconnects to your {@link android.app.Activity} when it's finished. This
+    object is a {@link android.support.v4.content.CursorLoader}. Besides doing the initial
+    background query, a {@link android.support.v4.content.CursorLoader} automatically re-runs the
+    query when data associated with the query changes.
 </p>
 <p>
-    This class describes how to define and use a {@link android.support.v4.content.CursorLoader}.
-    Examples in this class use the {@link android.support.v4 v4 support library} versions of
-    classes, which support platforms starting with Android 1.6.
+    This class describes how to use a {@link android.support.v4.content.CursorLoader} to run a
+    background query. Examples in this class use the {@link android.support.v4 v4 support library}
+    versions of classes, which support platforms starting with Android 1.6.
 </p>
 <h2>Lessons</h2>
 <dl>
     <dt>
-        <strong><a href="setup-loader.html">Setting Up the Loader</a></strong>
+        <strong><a href="setup-loader.html">Running a Query with a CursorLoader</a></strong>
     </dt>
     <dd>
-        Learn how to set up an {@link android.app.Activity} that inherits the necessary classes
-        for running a {@link android.support.v4.content.CursorLoader} and returning results.
-    </dd>
-    <dt>
-        <strong><a href="define-launch-query.html">Defining and Launching the Query</a></strong>
-    </dt>
-    <dd>
-        Learn how to perform a query against a {@link android.content.ContentProvider} using
-        a {@link android.support.v4.content.CursorLoader}.
+        Learn how to run a query in the background, using a
+        {@link android.support.v4.content.CursorLoader}.
     </dd>
     <dt>
         <strong>
diff --git a/docs/html/training/load-data-background/setup-loader.jd b/docs/html/training/load-data-background/setup-loader.jd
index 4b40611..17fe7b0 100644
--- a/docs/html/training/load-data-background/setup-loader.jd
+++ b/docs/html/training/load-data-background/setup-loader.jd
@@ -1,4 +1,4 @@
-page.title=Setting Up the Loader
+page.title=Running a Query with a CursorLoader
 trainingnavtop=true
 startpage=true
 
@@ -10,81 +10,133 @@
 <h2>This lesson teaches you to</h2>
 <ol>
     <li>
-        <a href="#AddExtensions">Extend an Activity</a>
+        <a href="#Extend">Define an Activity That Uses CursorLoader</a>
     </li>
     <li>
-        <a href="#GetLoader">Retrieve a LoaderManager</a>
+        <a href="#InitializeLoader">Initialize the Query</a>
     </li>
     <li>
-        <a href="#InitializeLoader">Initialize the Loader Framework</a>
+        <a href="#DefineLaunch">Start the Query</a>
     </li>
 </ol>
+
+<h2>Try it out</h2>
+<div class="download-box">
+    <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a>
+    <p class="filename">ThreadSample.zip</p>
+</div>
+
   </div>
 </div>
 <p>
-    You create a {@link android.support.v4.content.CursorLoader} within a
-    <b>loader framework</b>. To set up the framework, you implement the
+    A {@link android.support.v4.content.CursorLoader} runs an asynchronous query in the background
+    against a {@link android.content.ContentProvider}, and returns the results to the
+    {@link android.app.Activity} or {@link android.support.v4.app.FragmentActivity} from which it
+    was called. This allows the {@link android.app.Activity} or
+    {@link android.support.v4.app.FragmentActivity} to continue to interact with the user while the
+    query is ongoing.
+</p>
+<h2 id="Extend">Define an Activity That Uses CursorLoader</h2>
+<p>
+    To use a {@link android.support.v4.content.CursorLoader} with an
+    {@link android.app.Activity} or {@link android.support.v4.app.FragmentActivity}, use the
     {@link android.support.v4.app.LoaderManager.LoaderCallbacks LoaderCallbacks&lt;Cursor&gt;}
-    as part of an {@link android.app.Activity}. In addition, to provide compatibility
-    compatible with platform versions starting with Android 1.6, you must extend the
-    {@link android.app.Activity} with the {@link android.support.v4.app.FragmentActivity} class.
+    interface. A {@link android.support.v4.content.CursorLoader} invokes callbacks defined
+    in this interface to communicate with the class; this lesson and the next one
+    describe each callback in detail.
 </p>
+<p>
+    For example, this is how you should define a {@link android.support.v4.app.FragmentActivity}
+    that uses the support library version of {@link android.support.v4.content.CursorLoader}. By
+    extending {@link android.support.v4.app.FragmentActivity}, you get support for
+    {@link android.support.v4.content.CursorLoader} as well as
+    {@link android.support.v4.app.Fragment}:
+</p>
+<pre>
+public class PhotoThumbnailFragment extends FragmentActivity implements
+        LoaderManager.LoaderCallbacks&lt;Cursor&gt; {
+...
+}
+</pre>
+<h2 id="InitializeLoader">Initialize the Query</h2>
+<p>
+    To initialize a query, call
+    {@link android.support.v4.app.LoaderManager#initLoader LoaderManager.initLoader()}. This
+    initializes the background framework. You can do this after the user has entered data that's
+    used in the query, or, if you don't need any user data, you can do it in
+    {@link android.support.v4.app.FragmentActivity#onCreate onCreate()} or
+    {@link android.support.v4.app.Fragment#onCreateView onCreateView()}. For example:
+</p>
+<pre>
+    // Identifies a particular Loader being used in this component
+    private static final int URL_LOADER = 0;
+    ...
+    /* When the system is ready for the Fragment to appear, this displays
+     * the Fragment's View
+     */
+    public View onCreateView(
+            LayoutInflater inflater,
+            ViewGroup viewGroup,
+            Bundle bundle) {
+        ...
+        /*
+         * Initializes the CursorLoader. The URL_LOADER value is eventually passed
+         * to onCreateLoader().
+         */
+        getLoaderManager().initLoader(URL_LOADER, null, this);
+        ...
+    }
+</pre>
 <p class="note">
-    <strong>Note:</strong> A {@link android.support.v4.app.Fragment} is not a prerequisite for
-    {@link android.support.v4.content.CursorLoader}. As a convenience, the support library class
-    {@link android.support.v4.app.FragmentActivity} contains the fragment and the loader frameworks,
-    but they are completely independent of each other.
-</p>
-<p>
-    Before you can use the loader framework, you need to initialize it. To do this, retrieve
-    a {@link android.support.v4.app.LoaderManager} object and call its
-    {@link android.support.v4.app.LoaderManager#initLoader initLoader()} method.
-</p>
-<p>
-    If you do use one or more {@link android.support.v4.app.Fragment} objects in an
-    {@link android.app.Activity}, the {@link android.support.v4.app.LoaderManager} you retrieve is
-    available to all of them.
-</p>
-<h2 id="AddExtensions">Extend an Activity</h2>
-<p>
-    To set up an {@link android.app.Activity} subclass to contain a
-    {@link android.support.v4.content.CursorLoader}, extend the subclass with
-    must extend {@link android.support.v4.app.FragmentActivity}, which provides the loader
-    framework, and implement the {@link android.support.v4.app.LoaderManager.LoaderCallbacks
-    LoaderCallbacks&lt;Cursor&gt;} interface, which specifies method signatures that the loader
-    framework uses to interact with the {@link android.app.Activity}.
-</p>
-<p>
-    For example:
-</p>
-<pre>
-public class DisplayActivity extends FragmentActivity
-        implements LoaderManager.LoaderCallbacks&lt;Cursor&gt;
-</pre>
-<h2 id="GetLoader">Retrieve a LoaderManager</h2>
-<p>
-    To get an instance {@link android.support.v4.app.LoaderManager} for use in your
-    {@link android.app.Activity}, call
+    <strong>Note:</strong> The method {@link android.support.v4.app.Fragment#getLoaderManager
+    getLoaderManager()} is only available in the {@link android.support.v4.app.Fragment} class. To
+    get a {@link android.support.v4.app.LoaderManager} in a
+    {@link android.support.v4.app.FragmentActivity}, call
     {@link android.support.v4.app.FragmentActivity#getSupportLoaderManager
-    FragmentActivity.getSupportLoaderManager()} at the beginning of the
-    {@link android.app.Activity#onCreate onCreate()} method. For example:
+    getSupportLoaderManager()}.
 </p>
-<pre>
-private LoaderManager mLoaderManager;
-public void onCreate() {
-...
-mLoaderManager = this.getSupportLoaderManager();
-</pre>
-<h2 id="InitializeLoader">Initialize the Loader Framework</h2>
+<h2 id="DefineLaunch">Start the Query</h2>
 <p>
-    Once you have the {@link android.support.v4.app.LoaderManager} object, initialize
-    it by calling {@link android.support.v4.app.LoaderManager#initLoader initLoader()}. For
-    example:
+    As soon as the background framework is initialized, it calls your implementation of
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}.
+    To start the query, return a {@link android.support.v4.content.CursorLoader} from this method.
+    You can instantiate an empty {@link android.support.v4.content.CursorLoader} and then use its
+    methods to define your query, or you can instantiate the object and define the query at the
+    same time:
 </p>
 <pre>
-// CursorLoader instance identifier
-public static final int URL_LOADER = 0;
-...
-// Initializes the CursorLoader
-getSupportLoaderManager().initLoader(URL_LOADER, null, this);
+/*
+* Callback that's invoked when the system has initialized the Loader and
+* is ready to start the query. This usually happens when initLoader() is
+* called. The loaderID argument contains the ID value passed to the
+* initLoader() call.
+*/
+&#64;Override
+public Loader&lt;Cursor&gt; onCreateLoader(int loaderID, Bundle bundle)
+{
+    /*
+     * Takes action based on the ID of the Loader that's being created
+     */
+    switch (loaderID) {
+        case URL_LOADER:
+            // Returns a new CursorLoader
+            return new CursorLoader(
+                        getActivity(),   // Parent activity context
+                        mDataUrl,        // Table to query
+                        mProjection,     // Projection to return
+                        null,            // No selection clause
+                        null,            // No selection arguments
+                        null             // Default sort order
+        );
+        default:
+            // An invalid id was passed in
+            return null;
+    }
+}
 </pre>
+<p>
+    Once the background framework has the object, it starts the query in the background. When the
+    query is done, the background framework calls
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()},
+    which is described in the next lesson.
+</p>
diff --git a/docs/html/training/run-background-service/create-service.jd b/docs/html/training/run-background-service/create-service.jd
new file mode 100644
index 0000000..5f4799c
--- /dev/null
+++ b/docs/html/training/run-background-service/create-service.jd
@@ -0,0 +1,131 @@
+page.title=Creating a Background Service
+trainingnavtop=true
+@jd:body
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+    <li>
+        <a href="#CreateClass">Create an IntentService</a>
+    </li>
+    <li>
+        <a href="#DefineManifest">Define the IntentService in the Manifest</a>
+    </li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+    <li>
+<a href="{@docRoot}guide/components/services.html#ExtendingIntentService">Extending the IntentService Class</a>
+    </li>
+    <li>
+        <a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
+    </li>
+</ul>
+<h2>Try it out</h2>
+
+<div class="download-box">
+    <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a>
+    <p class="filename">ThreadSample.zip</p>
+</div>
+
+</div>
+</div>
+<p>
+    The {@link android.app.IntentService} class provides a straightforward structure for running
+    an operation on a single background thread. This allows it to handle long-running operations
+    without affecting your user interface's responsiveness. Also, an
+    {@link android.app.IntentService} isn't affected by most user interface lifecycle events, so it
+    continues to run in circumstances that would shut down an {@link android.os.AsyncTask}
+</p>
+<p>
+    An {@link android.app.IntentService} has a few limitations:
+</p>
+<ul>
+    <li>
+        It can't interact directly with your user interface. To put its results in the UI, you
+        have to send them to an {@link android.app.Activity}.
+    </li>
+    <li>
+        Work requests run sequentially. If an operation is running in an
+        {@link android.app.IntentService}, and you send it another request, the request waits until
+        the first operation is finished.
+    </li>
+    <li>
+        An operation running on an {@link android.app.IntentService} can't be interrupted.
+    </li>
+</ul>
+<p>
+    However, in most cases an {@link android.app.IntentService} is the preferred way to simple
+    background operations.
+</p>
+<p>
+    This lesson shows you how to create your own subclass of {@link android.app.IntentService}.
+    The lesson also shows you how to create the required callback method
+    {@link android.app.IntentService#onHandleIntent onHandleIntent()}. Finally, the lesson describes
+    shows you how to define the {@link android.app.IntentService} in your manifest file.
+</p>
+<h2 id="CreateClass">Create an IntentService</h2>
+<p>
+    To create an {@link android.app.IntentService} component for your app, define a class that
+    extends {@link android.app.IntentService}, and within it, define a method that
+    overrides {@link android.app.IntentService#onHandleIntent onHandleIntent()}. For example:
+</p>
+<pre>
+public class RSSPullService extends IntentService {
+    &#64;Override
+    protected void onHandleIntent(Intent workIntent) {
+        // Gets data from the incoming Intent
+        String dataString = workIntent.getDataString();
+        ...
+        // Do work here, based on the contents of dataString
+        ...
+    }
+}
+</pre>
+<p>
+    Notice that the other callbacks of a regular {@link android.app.Service} component, such as
+    {@link android.app.Service#onStartCommand onStartCommand()} are automatically invoked by
+    {@link android.app.IntentService}. In an {@link android.app.IntentService}, you should avoid
+    overriding these callbacks.
+</p>
+<h2 id="DefineManifest">Define the IntentService in the Manifest</h2>
+<p>
+    An {@link android.app.IntentService} also needs an entry in your application manifest.
+    Provide this entry as a
+    <code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+    element that's a child of the
+    <code><a href="{@docRoot}guide/topics/manifest/application-element.html">
+    &lt;application&gt;</a></code> element:
+</p>
+<pre>
+    &lt;application
+        android:icon="&#64;drawable/icon"
+        android:label="&#64;string/app_name"&gt;
+        ...
+        &lt;!--
+            Because android:exported is set to "false",
+            the service is only available to this app.
+        --&gt;
+        &lt;service
+            android:name=".RSSPullService"
+            android:exported="false"/&gt;
+        ...
+    &lt;application/&gt;
+</pre>
+<p>
+    The attribute <code>android:name</code> specifies the class name of the
+    {@link android.app.IntentService}.
+</p>
+<p>
+    Notice that the
+    <code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+    element doesn't contain an intent filter. The {@link android.app.Activity} that sends work
+    requests to the service uses an explicit {@link android.content.Intent}, so no filter is needed.
+    This also means that only components in the same app or other applications with the same user ID
+    can access the service.
+</p>
+<p>
+    Now that you have the basic {@link android.app.IntentService} class, you can send work requests
+    to it with {@link android.content.Intent} objects. The procedure for constructing these objects
+    and sending them to your {@link android.app.IntentService} is described in the next lesson.
+</p>
diff --git a/docs/html/training/run-background-service/index.jd b/docs/html/training/run-background-service/index.jd
new file mode 100644
index 0000000..173b87a
--- /dev/null
+++ b/docs/html/training/run-background-service/index.jd
@@ -0,0 +1,68 @@
+page.title=Running in a Background Service
+trainingnavtop=true
+startpage=true
+@jd:body
+<div id="tb-wrapper">
+<div id="tb">
+<h2>Dependencies and prerequisites</h2>
+<ul>
+  <li>Android 1.6 (API Level 4) or higher</li>
+</ul>
+<h2>You should also read</h2>
+<ul>
+    <li>
+<a href="{@docRoot}guide/components/services.html#ExtendingIntentService">Extending the IntentService Class</a>
+    </li>
+    <li>
+        <a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
+    </li>
+</ul>
+<h2>Try it out</h2>
+
+<div class="download-box">
+    <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a>
+    <p class="filename">ThreadSample.zip</p>
+</div>
+
+</div>
+</div>
+<!-- ------------------------------------------------------------------------------------------- -->
+<!-- Introduction -->
+<!-- ------------------------------------------------------------------------------------------- -->
+<p>
+    Unless you specify otherwise, most of the operations you do in an app run in the foreground on
+    a special thread called the UI thread. This can cause problems, because long-running operations
+    will interfere with the responsiveness of your user interface. This annoys your users, and can
+    even cause system errors. To avoid this, the Android framework offers several classes that
+    help you off-load operations onto a separate thread running in the background. The most useful
+    of these is {@link android.app.IntentService}.
+</p>
+<p>
+    This class describes how to implement an {@link android.app.IntentService}, send it work
+    requests, and report its results to other components.
+</p>
+<h2>Lessons</h2>
+<dl>
+    <dt>
+        <b><a href="create-service.html">Creating a Background Service</a></b>
+    </dt>
+    <dd>
+        Learn how to create an {@link android.app.IntentService}.
+    </dd>
+    <dt>
+        <b><a href="send-request.html">Sending Work Requests to the Background Service</a></b>
+    </dt>
+    <dd>
+        Learn how to send work requests to an {@link android.app.IntentService}.
+    </dd>
+    <dt>
+        <b><a href="report-status.html">Reporting Work Status</a></b>
+    </dt>
+    <dd>
+        Learn how to use an {@link android.content.Intent} and a
+        {@link android.support.v4.content.LocalBroadcastManager} to communicate the status of a
+        work request from an {@link android.app.IntentService} to the
+        {@link android.app.Activity} that sent the request.
+    </dd>
+</dl>
+
diff --git a/docs/html/training/run-background-service/report-status.jd b/docs/html/training/run-background-service/report-status.jd
new file mode 100644
index 0000000..41121c1
--- /dev/null
+++ b/docs/html/training/run-background-service/report-status.jd
@@ -0,0 +1,199 @@
+page.title=Reporting Work Status
+trainingnavtop=true
+@jd:body
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+    <li>
+        <a href="#ReportStatus">Report Status From an IntentService</a>
+    </li>
+    <li>
+        <a href="#ReceiveStatus">Receive Status Broadcasts from an IntentService</a>
+    </li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+    <li>
+        <a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
+    </li>
+    <li>
+        The section <b>Broadcast receivers</b> in the
+    <a href="{@docRoot}guide/components/fundamentals.html#Components">Application Components</a>
+        API guide.
+    </li>
+</ul>
+<h2>Try it out</h2>
+
+<div class="download-box">
+    <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a>
+    <p class="filename">ThreadSample.zip</p>
+</div>
+
+</div>
+</div>
+<p>
+    This lesson shows you how to report the status of a work request run in a background service
+    to the component that sent the request. This allows you, for example, to report the status of
+    the request in an {@link android.app.Activity} object's UI. The recommended way to send and
+    receive status is to use a {@link android.support.v4.content.LocalBroadcastManager}, which
+    limits broadcast {@link android.content.Intent} objects to components in your own app.
+</p>
+<h2 id="ReportStatus">Report Status From an IntentService</h2>
+
+<p>
+    To send the status of a work request in an {@link android.app.IntentService} to other
+    components, first create an {@link android.content.Intent} that contains the status in its
+    extended data. As an option, you can add an action and data URI to this
+    {@link android.content.Intent}.
+</p>
+<p>
+    Next, send the {@link android.content.Intent} by calling
+    {@link android.support.v4.content.LocalBroadcastManager#sendBroadcast
+    LocalBroadcastManager.sendBroadcast()}. This sends the {@link android.content.Intent} to any
+    component in your application that has registered to receive it.
+    To get an instance of {@link android.support.v4.content.LocalBroadcastManager}, call
+    {@link android.support.v4.content.LocalBroadcastManager#getInstance getInstance()}.
+</p>
+<p>
+    For example:
+</p>
+<pre>
+public final class Constants {
+    ...
+    // Defines a custom Intent action
+    public static final String BROADCAST_ACTION =
+        "com.example.android.threadsample.BROADCAST";
+    ...
+    // Defines the key for the status "extra" in an Intent
+    public static final String EXTENDED_DATA_STATUS =
+        "com.example.android.threadsample.STATUS";
+    ...
+}
+public class RSSPullService extends IntentService {
+...
+    /*
+     * Creates a new Intent containing a Uri object
+     * BROADCAST_ACTION is a custom Intent action
+     */
+    Intent localIntent =
+            new Intent(Constants.BROADCAST_ACTION)
+            // Puts the status into the Intent
+            .putExtra(Constants.EXTENDED_DATA_STATUS, status);
+    // Broadcasts the Intent to receivers in this app.
+    LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
+...
+}
+</pre>
+<p>
+    The next step is to handle the incoming broadcast {@link android.content.Intent} objects in
+    the component that sent the original work request.
+</p>
+<h2 id="ReceiveStatus">Receive Status Broadcasts from an IntentService</h2>
+<p>
+    
+    To receive broadcast {@link android.content.Intent} objects, use a subclass of
+    {@link android.content.BroadcastReceiver}. In the subclass, implement the
+    {@link android.content.BroadcastReceiver#onReceive BroadcastReceiver.onReceive()} callback
+    method, which {@link android.support.v4.content.LocalBroadcastManager} invokes when it receives
+    an {@link android.content.Intent}. {@link android.support.v4.content.LocalBroadcastManager}
+    passes the incoming {@link android.content.Intent} to
+    {@link android.content.BroadcastReceiver#onReceive BroadcastReceiver.onReceive()}.
+</p>
+<p>
+    For example:
+</p>
+<pre>
+// Broadcast receiver for receiving status updates from the IntentService
+private class ResponseReceiver extends BroadcastReceiver
+{
+    // Prevents instantiation
+    private DownloadStateReceiver() {
+    }
+    // Called when the BroadcastReceiver gets an Intent it's registered to receive
+    &#64;
+    public void onReceive(Context context, Intent intent) {
+...
+        /*
+         * Handle Intents here.
+         */
+...
+    }
+}
+</pre>
+<p>
+    Once you've defined the {@link android.content.BroadcastReceiver}, you can define filters
+    for it that match specific actions, categories, and data. To do this, create
+    an {@link android.content.IntentFilter}. This first snippet shows how to define the filter:
+</p>
+<pre>
+// Class that displays photos
+public class DisplayActivity extends FragmentActivity {
+    ...
+    public void onCreate(Bundle stateBundle) {
+        ...
+        super.onCreate(stateBundle);
+        ...
+        // The filter's action is BROADCAST_ACTION
+        IntentFilter mStatusIntentFilter = new IntentFilter(
+                Constants.BROADCAST_ACTION);
+    
+        // Adds a data filter for the HTTP scheme
+        mStatusIntentFilter.addDataScheme("http");
+        ...
+</pre>
+<p>
+    To register the {@link android.content.BroadcastReceiver} and the
+    {@link android.content.IntentFilter} with the system, get an instance of
+    {@link android.support.v4.content.LocalBroadcastManager} and call its
+    {@link android.support.v4.content.LocalBroadcastManager#registerReceiver registerReceiver()}
+    method. This next snippet shows how to register the {@link android.content.BroadcastReceiver}
+    and its {@link android.content.IntentFilter}:
+</p>
+<pre>
+        // Instantiates a new DownloadStateReceiver
+        DownloadStateReceiver mDownloadStateReceiver =
+                new DownloadStateReceiver();
+        // Registers the DownloadStateReceiver and its intent filters
+        LocalBroadcastManager.getInstance(this).registerReceiver(
+                mDownloadStateReceiver,
+                mStatusIntentFilter);
+        ...
+</pre>
+<p>
+    A single {@link android.content.BroadcastReceiver} can handle more than one type of broadcast
+    {@link android.content.Intent} object, each with its own action. This feature allows you to
+    run different code for each action, without having to define a separate
+    {@link android.content.BroadcastReceiver} for each action. To define another
+    {@link android.content.IntentFilter} for the same
+    {@link android.content.BroadcastReceiver}, create the {@link android.content.IntentFilter} and
+    repeat the call to
+    {@link android.support.v4.content.LocalBroadcastManager#registerReceiver registerReceiver()}.
+    For example:
+</p>
+<pre>
+        /*
+         * Instantiates a new action filter.
+         * No data filter is needed.
+         */
+        statusIntentFilter = new IntentFilter(Constants.ACTION_ZOOM_IMAGE);
+        ...
+        // Registers the receiver with the new filter
+        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
+                mDownloadStateReceiver,
+                mIntentFilter);
+</pre>
+<p>
+    Sending an broadcast {@link android.content.Intent} doesn't start or resume an
+    {@link android.app.Activity}. The {@link android.content.BroadcastReceiver} for an
+    {@link android.app.Activity} receives and processes {@link android.content.Intent} objects even
+    when your app is in the background, but doesn't force your app to the foreground. If you
+    want to notify the user about an event that happened in the background while your app was not
+    visible, use a {@link android.app.Notification}. <i>Never</i> start an
+    {@link android.app.Activity} in response to an incoming broadcast
+    {@link android.content.Intent}.
+</p>
+<p>
+    
+</p>
+
diff --git a/docs/html/training/run-background-service/send-request.jd b/docs/html/training/run-background-service/send-request.jd
new file mode 100644
index 0000000..5b1114d
--- /dev/null
+++ b/docs/html/training/run-background-service/send-request.jd
@@ -0,0 +1,82 @@
+page.title=Sending Work Requests to the Background Service
+trainingnavtop=true
+@jd:body
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+    <li>
+<a href="#CreateRequest">Create and Send a Work Request to an IntentService</a>
+    </li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+    <li>
+        <a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
+    </li>
+</ul>
+<h2>Try it out</h2>
+
+<div class="download-box">
+    <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a>
+    <p class="filename">ThreadSample.zip</p>
+</div>
+
+</div>
+</div>
+<p>
+    The previous lesson showed you how to create an {@link android.app.IntentService} class. This
+    lesson shows you how to trigger the {@link android.app.IntentService} to run an operation by
+    sending it an {@link android.content.Intent}. This {@link android.content.Intent} can
+    contain optionally contain data for the {@link android.app.IntentService} to process. You can
+    send an {@link android.content.Intent} to an {@link android.app.IntentService} from any point
+    in an {@link android.app.Activity} or {@link android.app.Fragment}
+</p>
+<h2 id="CreateRequest">Create and Send a Work Request to an IntentService</h2>
+<p>
+    To create a work request and send it to an {@link android.app.IntentService}, create an
+    explicit {@link android.content.Intent}, add work request data to it, and send it to
+    {@link android.app.IntentService} by calling
+    {@link android.content.Context#startService startService()}.
+</p>
+<p>
+    The next snippets demonstrate this:
+</p>
+<ol>
+    <li>
+        Create a new, explicit {@link android.content.Intent} for the
+        {@link android.app.IntentService} called <code>RSSPullService</code>.
+        <br>
+<pre>
+/*
+ * Creates a new Intent to start the RSSPullService
+ * IntentService. Passes a URI in the
+ * Intent's "data" field.
+ */
+mServiceIntent = new Intent(getActivity(), RSSPullService.class);
+mServiceIntent.setData(Uri.parse(dataUrl));
+</pre>
+    </li>
+    <li>
+        Call {@link android.content.Context#startService startService()}
+        <br>
+<pre>
+// Starts the IntentService
+getActivity().startService(mServiceIntent);
+</pre>
+</ol>
+<p>
+    Notice that you can send the work request from anywhere in an Activity or Fragment.
+    For example, if you need to get user input first, you can send the request from a callback
+    that responds to a button click or similar gesture.
+</p>
+<p>
+    Once you call {@link android.content.Context#startService startService()},
+    the {@link android.app.IntentService} does the work defined in its
+    {@link android.app.IntentService#onHandleIntent onHandleIntent()} method, and then stops itself.
+</p>
+<p>
+    The next step is to report the results of the work request back to the originating Activity
+    or Fragment. The next lesson shows you how to do this with a
+    {@link android.content.BroadcastReceiver}.
+</p>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index ba9bbcf..77909b8 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -192,7 +192,7 @@
         </ul>
       </li>
     </ul>
-  </li><!-- end getting started -->    
+  </li><!-- end getting started -->
   
 
   <li class="nav-section">
@@ -605,7 +605,7 @@
           <div class="nav-section-header">
               <a href="<?cs var:toroot ?>training/notify-user/index.html"
                  description=
-                 "How to display messages called notifications outside of 
+                 "How to display messages called notifications outside of
                  your application's UI."
                >Notifying the User</a>
           </div>
@@ -679,19 +679,19 @@
             zh-CN-lang="支持各种屏幕尺寸"
             ko-lang="다양한 화면 크기 지원"
             ja-lang="さまざまな画面サイズのサポート"
-            es-lang="Cómo admitir varios tamaños de pantalla"               
+            es-lang="Cómo admitir varios tamaños de pantalla"
             >Supporting Different Screen Sizes</a>
           </li>
           <li><a href="/training/multiscreen/screendensities.html"
             zh-CN-lang="支持各种屏幕密度"
             ja-lang="さまざまな画面密度のサポート"
-            es-lang="Cómo admitir varias densidades de pantalla"               
+            es-lang="Cómo admitir varias densidades de pantalla"
             >Supporting Different Screen Densities</a>
           </li>
           <li><a href="/training/multiscreen/adaptui.html"
             zh-CN-lang="实施自适应用户界面流程"
             ja-lang="順応性のある UI フローの実装"
-            es-lang="Cómo implementar interfaces de usuario adaptables"               
+            es-lang="Cómo implementar interfaces de usuario adaptables"
             >Implementing Adaptive UI Flows</a>
           </li>
         </ul>
@@ -845,7 +845,29 @@
           </li>
         </ul>
       </li>
-
+<!--  Background Service -->
+      <li class="nav-section">
+        <div class="nav-section-header">
+          <a href="<?cs var:toroot ?>training/run-background-service/index.html"
+             description=
+             "How to improve UI performance and responsiveness by sending work to a
+             Service running in the background">Running in a Background Service</a>
+        </div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>training/run-background-service/create-service.html">
+            Creating a Background Service
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/run-background-service/send-request.html">
+            Sending Work Requests to the Background Service
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/run-background-service/report-status.html">
+            Reporting Work Status
+          </a>
+          </li>
+        </ul>
+      </li>
       
       <li class="nav-section">
         <div class="nav-section-header">
@@ -862,25 +884,25 @@
           <li><a href="/training/monitoring-device-state/battery-monitoring.html"
             zh-CN-lang="监控电池电量和充电状态"
             ja-lang="電池残量と充電状態の監視"
-            es-lang="Cómo controlar el nivel de batería y el estado de carga"               
+            es-lang="Cómo controlar el nivel de batería y el estado de carga"
             >Monitoring the Battery Level and Charging State</a>
           </li>
           <li><a href="/training/monitoring-device-state/docking-monitoring.html"
             zh-CN-lang="确定和监控基座对接状态和类型"
             ja-lang="ホルダーの装着状態とタイプの特定と監視"
-            es-lang="Cómo determinar y controlar el tipo de conector y el estado de la conexión"               
+            es-lang="Cómo determinar y controlar el tipo de conector y el estado de la conexión"
             >Determining and Monitoring the Docking State and Type</a>
           </li>
           <li><a href="/training/monitoring-device-state/connectivity-monitoring.html"
             zh-CN-lang="确定和监控网络连接状态"
             ja-lang="接続状態の特定と監視"
-            es-lang="Cómo determinar y controlar el estado de la conectividad"               
+            es-lang="Cómo determinar y controlar el estado de la conectividad"
             >Determining and Monitoring the Connectivity Status</a>
           </li>
           <li><a href="/training/monitoring-device-state/manifest-receivers.html"
             zh-CN-lang="根据需要操作广播接收器"
             ja-lang="オンデマンドでのブロードキャスト レシーバ操作"
-            es-lang="Cómo manipular los receptores de emisión bajo demanda"               
+            es-lang="Cómo manipular los receptores de emisión bajo demanda"
             >Manipulating Broadcast Receivers On Demand</a>
           </li>
         </ul>
@@ -1006,8 +1028,6 @@
           </li>
         </ul>
       </li>
-      
-      
       <li class="nav-section">
         <div class="nav-section-header">
           <a href="<?cs var:toroot ?>training/monetization/index.html"
@@ -1028,7 +1048,6 @@
   <!-- End best Publishing -->
 
 </ul><!-- nav -->
-
 <script type="text/javascript">
 <!--
     buildToggleLists();
diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java
index 2907f10..10cdab0 100644
--- a/drm/java/android/drm/DrmManagerClient.java
+++ b/drm/java/android/drm/DrmManagerClient.java
@@ -29,6 +29,8 @@
 import android.provider.MediaStore;
 import android.util.Log;
 
+import dalvik.system.CloseGuard;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -52,10 +54,15 @@
      */
     public static final int ERROR_UNKNOWN = -2000;
 
+    /** {@hide} */
+    public static final int INVALID_SESSION = -1;
+
     HandlerThread mInfoThread;
     HandlerThread mEventThread;
     private static final String TAG = "DrmManagerClient";
 
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
     static {
         // Load the respective library
         System.loadLibrary("drmframework_jni");
@@ -110,7 +117,7 @@
 
     private int mUniqueId;
     private int mNativeContext;
-    private boolean mReleased;
+    private volatile boolean mReleased;
     private Context mContext;
     private InfoHandler mInfoHandler;
     private EventHandler mEventHandler;
@@ -244,17 +251,22 @@
      */
     public DrmManagerClient(Context context) {
         mContext = context;
-        mReleased = false;
         createEventThreads();
 
         // save the unique id
         mUniqueId = _initialize();
+        mCloseGuard.open("release");
     }
 
-    protected void finalize() {
-        if (!mReleased) {
-            Log.w(TAG, "You should have called release()");
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
             release();
+        } finally {
+            super.finalize();
         }
     }
 
@@ -266,11 +278,9 @@
      * {@link DrmManagerClient} is no longer usable since it has lost all of its required resource.
      */
     public void release() {
-        if (mReleased) {
-            Log.w(TAG, "You have already called release()");
-            return;
-        }
+        if (mReleased) return;
         mReleased = true;
+
         if (mEventHandler != null) {
             mEventThread.quit();
             mEventThread = null;
@@ -285,6 +295,7 @@
         mOnInfoListener = null;
         mOnErrorListener = null;
         _release(mUniqueId);
+        mCloseGuard.close();
     }
 
     /**
diff --git a/drm/java/android/drm/DrmOutputStream.java b/drm/java/android/drm/DrmOutputStream.java
new file mode 100644
index 0000000..2e1b756
--- /dev/null
+++ b/drm/java/android/drm/DrmOutputStream.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.drm;
+
+import static android.drm.DrmConvertedStatus.STATUS_OK;
+
+import java.io.File;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.net.UnknownServiceException;
+import java.util.Arrays;
+
+import libcore.io.IoUtils;
+import libcore.util.SneakyThrow;
+
+/**
+ * Stream that applies a {@link DrmManagerClient} transformation to data before
+ * writing to disk, similar to a {@link FilterOutputStream}.
+ *
+ * @hide
+ */
+public class DrmOutputStream extends OutputStream {
+
+    private final DrmManagerClient mClient;
+
+    private int mSessionId;
+    private RandomAccessFile mOutput;
+
+    public DrmOutputStream(DrmManagerClient client, File file, String mimeType) throws IOException {
+        mClient = client;
+        mOutput = new RandomAccessFile(file, "rw");
+
+        try {
+            mSessionId = mClient.openConvertSession(mimeType);
+            if (mSessionId == DrmManagerClient.INVALID_SESSION) {
+                throw new UnknownServiceException("Failed to open DRM session for " + mimeType);
+            }
+        } catch (Throwable thrown) {
+            IoUtils.closeQuietly(mOutput);
+            SneakyThrow.sneakyThrow(thrown);
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        try {
+            final DrmConvertedStatus status = mClient.closeConvertSession(mSessionId);
+            if (status.statusCode == STATUS_OK) {
+                mOutput.seek(status.offset);
+                mOutput.write(status.convertedData);
+            } else {
+                throw new IOException("Unexpected DRM status: " + status.statusCode);
+            }
+        } finally {
+            try {
+                mOutput.getFD().sync();
+            } finally {
+                mOutput.close();
+                mOutput = null;
+            }
+        }
+    }
+
+    @Override
+    public void write(byte[] buffer, int offset, int count) throws IOException {
+        Arrays.checkOffsetAndCount(buffer.length, offset, count);
+
+        final byte[] exactBuffer;
+        if (count == buffer.length) {
+            exactBuffer = buffer;
+        } else {
+            exactBuffer = new byte[count];
+            System.arraycopy(buffer, offset, exactBuffer, 0, count);
+        }
+
+        final DrmConvertedStatus status = mClient.convertData(mSessionId, exactBuffer);
+        if (status.statusCode == STATUS_OK) {
+            mOutput.write(status.convertedData);
+        } else {
+            throw new IOException("Unexpected DRM status: " + status.statusCode);
+        }
+    }
+
+    @Override
+    public void write(int oneByte) throws IOException {
+        write(new byte[] { (byte) oneByte });
+    }
+}
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index b320e4b..e0470dc 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -247,7 +247,7 @@
 
     } else {
         st = SurfaceTexture_getSurfaceTexture(_env, sur);
-        window = new SurfaceTextureClient(st);
+        window = new SurfaceTextureClient(st->getBufferQueue());
     }
 
     rsContextSetSurface(con, width, height, window.get());
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index fc2cd9e..a730065 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1530,7 +1530,8 @@
     if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
     if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
     if (version != o.version) diffs |= CONFIG_VERSION;
-    if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;
+    if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) diffs |= CONFIG_LAYOUTDIR;
+    if ((screenLayout & ~MASK_LAYOUTDIR) != (o.screenLayout & ~MASK_LAYOUTDIR)) diffs |= CONFIG_SCREEN_LAYOUT;
     if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;
     if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE;
     if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE;
diff --git a/media/mca/filterfw/jni/jni_gl_frame.cpp b/media/mca/filterfw/jni/jni_gl_frame.cpp
index 61340f9..b55bc5d 100644
--- a/media/mca/filterfw/jni/jni_gl_frame.cpp
+++ b/media/mca/filterfw/jni/jni_gl_frame.cpp
@@ -221,10 +221,10 @@
   if (frame && bitmap) {
     uint8_t* pixels;
     const int result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void**>(&pixels));
-    if (result == ANDROID_BITMAP_RESUT_SUCCESS) {
+    if (result == ANDROID_BITMAP_RESULT_SUCCESS) {
       const bool success = frame->WriteData(pixels, size);
       return ToJBool(success &&
-                     AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESUT_SUCCESS);
+                     AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESULT_SUCCESS);
     }
   }
   return JNI_FALSE;
@@ -237,9 +237,9 @@
   if (frame && bitmap) {
     uint8_t* pixels;
     const int result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void**>(&pixels));
-    if (result == ANDROID_BITMAP_RESUT_SUCCESS) {
+    if (result == ANDROID_BITMAP_RESULT_SUCCESS) {
       frame->CopyDataTo(pixels, frame->Size());
-      return (AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESUT_SUCCESS);
+      return (AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESULT_SUCCESS);
     }
   }
   return JNI_FALSE;
diff --git a/media/mca/filterfw/jni/jni_native_frame.cpp b/media/mca/filterfw/jni/jni_native_frame.cpp
index 1dfa3e6..c8f2352 100644
--- a/media/mca/filterfw/jni/jni_native_frame.cpp
+++ b/media/mca/filterfw/jni/jni_native_frame.cpp
@@ -178,7 +178,7 @@
 
     Pixel* src_ptr;
     const int result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void**>(&src_ptr));
-    if (result == ANDROID_BITMAP_RESUT_SUCCESS) {
+    if (result == ANDROID_BITMAP_RESULT_SUCCESS) {
       // Create destination pointers
       uint8_t* dst_ptr = reinterpret_cast<uint8_t*>(frame->MutableData());
       const uint8_t* end_ptr = dst_ptr + frame->Size();
@@ -207,7 +207,7 @@
           ALOGE("Unsupported bytes-per-pixel %d in setBitmap!", bytes_per_sample);
           break;
       }
-      return (AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESUT_SUCCESS);
+      return (AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESULT_SUCCESS);
     }
   }
   return JNI_FALSE;
@@ -222,7 +222,7 @@
   if (frame && bitmap) {
     Pixel* dst_ptr;
     const int result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void**>(&dst_ptr));
-    if (result == ANDROID_BITMAP_RESUT_SUCCESS) {
+    if (result == ANDROID_BITMAP_RESULT_SUCCESS) {
       // Make sure frame size matches bitmap size
       if ((size / 4) != (frame->Size() / bytes_per_sample)) {
         ALOGE("Size mismatch in native getBitmap()!");
@@ -259,7 +259,7 @@
           ALOGE("Unsupported bytes-per-pixel %d in getBitmap!", bytes_per_sample);
           break;
       }
-      return (AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESUT_SUCCESS);
+      return (AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESULT_SUCCESS);
     }
   }
   return JNI_FALSE;
diff --git a/native/graphics/jni/bitmap.cpp b/native/graphics/jni/bitmap.cpp
index 51a631f..eaa2cbe 100644
--- a/native/graphics/jni/bitmap.cpp
+++ b/native/graphics/jni/bitmap.cpp
@@ -52,7 +52,7 @@
                 break;
         }
     }
-    return ANDROID_BITMAP_RESUT_SUCCESS;
+    return ANDROID_BITMAP_RESULT_SUCCESS;
 }
 
 int AndroidBitmap_lockPixels(JNIEnv* env, jobject jbitmap, void** addrPtr) {
@@ -75,7 +75,7 @@
     if (addrPtr) {
         *addrPtr = addr;
     }
-    return ANDROID_BITMAP_RESUT_SUCCESS;
+    return ANDROID_BITMAP_RESULT_SUCCESS;
 }
 
 int AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap) {
@@ -95,6 +95,6 @@
     bm->notifyPixelsChanged();
 
     bm->unlockPixels();
-    return ANDROID_BITMAP_RESUT_SUCCESS;
+    return ANDROID_BITMAP_RESULT_SUCCESS;
 }
 
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 282ea8a..82627c0 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -73,6 +73,8 @@
     <integer name="def_lockscreen_sounds_enabled">1</integer>
     <string name="def_lock_sound" translatable="false">/system/media/audio/ui/Lock.ogg</string>
     <string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string>
+    <string name="def_wireless_charging_started_sound" translatable="false">/system/media/audio/ui/WirelessChargingStarted.ogg</string>
+
     <bool name="def_lockscreen_disabled">false</bool>
     <bool name="def_device_provisioned">false</bool>
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 2c8c4a2..fd0b79ff 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -71,7 +71,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 94;
+    private static final int DATABASE_VERSION = 95;
 
     private Context mContext;
     private int mUserHandle;
@@ -1505,6 +1505,25 @@
             upgradeVersion = 94;
         }
 
+        if (upgradeVersion == 94) {
+            // Add wireless charging started sound setting
+            if (mUserHandle == UserHandle.USER_OWNER) {
+                db.beginTransaction();
+                SQLiteStatement stmt = null;
+                try {
+                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
+                            + " VALUES(?,?);");
+                    loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND,
+                            R.string.def_wireless_charging_started_sound);
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                    if (stmt != null) stmt.close();
+                }
+            }
+            upgradeVersion = 95;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
@@ -2188,6 +2207,8 @@
                     R.string.def_car_dock_sound);
             loadStringSetting(stmt, Settings.Global.CAR_UNDOCK_SOUND,
                     R.string.def_car_undock_sound);
+            loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND,
+                    R.string.def_wireless_charging_started_sound);
 
             loadSetting(stmt, Settings.Global.SET_INSTALL_LOCATION, 0);
             loadSetting(stmt, Settings.Global.DEFAULT_INSTALL_LOCATION,
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index c454bb1..fff1aa0 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -157,14 +157,14 @@
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm ustawiony na <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Wyłączono transmisję danych 2G/3G"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Wyłączono transmisję danych 4G"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Wyłączono komórkową transmisję danych"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Transmisja danych została wyłączona"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Wyłączono transmisję danych"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Osiągnięto określony limit wykorzystania transmisji danych."\n\n"Jeśli ponownie włączysz przesyłanie danych, operator może naliczyć opłaty."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Ustawiony limit transmisji danych został osiągnięty."\n\n"Jeśli ponownie włączysz przesyłanie danych, operator może naliczyć dodatkowe opłaty."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Włącz transmisję danych"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Brak internetu"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: połączono"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Wyszukiwanie sygnału GPS"</string>
-    <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja ustawiona według GPS"</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja z GPSa"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"O aplikacji"</string>
     <string name="close_universe" msgid="3736513750241754348">"Zamknij"</string>
diff --git a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java
index f436cb4..305ee37 100644
--- a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java
+++ b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java
@@ -27,10 +27,10 @@
 import android.test.ServiceTestCase;
 import android.util.Log;
 
-import com.android.internal.telephony.IccUtils;
 import com.android.internal.telephony.IWapPushManager;
 import com.android.internal.telephony.WapPushManagerParams;
 import com.android.internal.telephony.WspTypeDecoder;
+import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.util.HexDump;
 import com.android.smspush.WapPushManager;
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index ba4b996..024c247 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -58,15 +58,6 @@
 import android.os.UserHandle;
 import android.os.Vibrator;
 import android.provider.Settings;
-
-import com.android.internal.R;
-import com.android.internal.policy.PolicyManager;
-import com.android.internal.policy.impl.keyguard.KeyguardViewManager;
-import com.android.internal.policy.impl.keyguard.KeyguardViewMediator;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.telephony.ITelephony;
-import com.android.internal.widget.PointerLocationView;
-
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
@@ -82,43 +73,68 @@
 import android.view.InputEvent;
 import android.view.InputEventReceiver;
 import android.view.KeyCharacterMap;
+import android.view.KeyCharacterMap.FallbackAction;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
-import android.view.WindowManagerGlobal;
-import android.view.WindowOrientationListener;
 import android.view.Surface;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.Window;
 import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.view.WindowManagerPolicy;
+import android.view.WindowOrientationListener;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+
+import com.android.internal.R;
+import com.android.internal.policy.PolicyManager;
+import com.android.internal.policy.impl.keyguard.KeyguardViewManager;
+import com.android.internal.policy.impl.keyguard.KeyguardViewMediator;
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.telephony.ITelephony;
+import com.android.internal.widget.PointerLocationView;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
-import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
-import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
-import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
 import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_HIDDEN_NAV_CONSUMER;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
+import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
 import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
 import static android.view.WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
@@ -126,33 +142,17 @@
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 import static android.view.WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
 import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
-import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
-import android.view.WindowManagerPolicy;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
-import android.view.KeyCharacterMap.FallbackAction;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
 
 /**
  * WindowManagerPolicy implementation for the Android phone UI.  This
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 88f5533..91ac1de 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -602,12 +602,12 @@
         mHandler = new Handler(this);
         mIWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService(Context.WINDOW_SERVICE));
-        mCaller = new HandlerCaller(context, new HandlerCaller.Callback() {
+        mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() {
             @Override
             public void executeMessage(Message msg) {
                 handleMessage(msg);
             }
-        });
+        }, true /*asyncHandler*/);
         mWindowManagerService = windowManager;
         mHardKeyboardListener = new HardKeyboardListener();
 
diff --git a/core/java/com/android/internal/widget/LockSettingsService.java b/services/java/com/android/server/LockSettingsService.java
similarity index 98%
rename from core/java/com/android/internal/widget/LockSettingsService.java
rename to services/java/com/android/server/LockSettingsService.java
index 4ecbd16..e20a21f 100644
--- a/core/java/com/android/internal/widget/LockSettingsService.java
+++ b/services/java/com/android/server/LockSettingsService.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.widget;
+package com.android.server;
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
@@ -32,6 +32,9 @@
 import android.text.TextUtils;
 import android.util.Slog;
 
+import com.android.internal.widget.ILockSettings;
+import com.android.internal.widget.LockPatternUtils;
+
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
diff --git a/services/java/com/android/server/NativeDaemonEvent.java b/services/java/com/android/server/NativeDaemonEvent.java
index f11ae1d..2095152 100644
--- a/services/java/com/android/server/NativeDaemonEvent.java
+++ b/services/java/com/android/server/NativeDaemonEvent.java
@@ -223,8 +223,8 @@
                 current++;  // skip the trailing quote
             }
             // unescape stuff within the word
-            word.replace("\\\\", "\\");
-            word.replace("\\\"", "\"");
+            word = word.replace("\\\\", "\\");
+            word = word.replace("\\\"", "\"");
 
             if (DEBUG_ROUTINE) Slog.e(LOGTAG, "found '" + word + "'");
             parsed.add(word);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 55885e6..a7b502a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -16,12 +16,10 @@
 
 package com.android.server;
 
-import android.accounts.AccountManagerService;
 import android.app.ActivityManagerNative;
 import android.bluetooth.BluetoothAdapter;
 import android.content.ComponentName;
 import android.content.ContentResolver;
-import android.content.ContentService;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.IPackageManager;
@@ -32,13 +30,11 @@
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.RemoteException;
-import android.os.SchedulingPolicyService;
 import android.os.ServiceManager;
 import android.os.StrictMode;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
-import android.server.search.SearchManagerService;
 import android.service.dreams.DreamService;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
@@ -48,20 +44,23 @@
 
 import com.android.internal.os.BinderInternal;
 import com.android.internal.os.SamplingProfilerIntegration;
-import com.android.internal.widget.LockSettingsService;
 import com.android.server.accessibility.AccessibilityManagerService;
+import com.android.server.accounts.AccountManagerService;
 import com.android.server.am.ActivityManagerService;
 import com.android.server.am.BatteryStatsService;
+import com.android.server.content.ContentService;
 import com.android.server.display.DisplayManagerService;
 import com.android.server.dreams.DreamManagerService;
 import com.android.server.input.InputManagerService;
 import com.android.server.net.NetworkPolicyManagerService;
 import com.android.server.net.NetworkStatsService;
+import com.android.server.os.SchedulingPolicyService;
 import com.android.server.pm.Installer;
 import com.android.server.pm.PackageManagerService;
 import com.android.server.pm.UserManagerService;
 import com.android.server.power.PowerManagerService;
 import com.android.server.power.ShutdownThread;
+import com.android.server.search.SearchManagerService;
 import com.android.server.usb.UsbService;
 import com.android.server.wm.WindowManagerService;
 
diff --git a/core/java/android/accounts/AccountAuthenticatorCache.java b/services/java/com/android/server/accounts/AccountAuthenticatorCache.java
similarity index 95%
rename from core/java/android/accounts/AccountAuthenticatorCache.java
rename to services/java/com/android/server/accounts/AccountAuthenticatorCache.java
index f937cde..7552368 100644
--- a/core/java/android/accounts/AccountAuthenticatorCache.java
+++ b/services/java/com/android/server/accounts/AccountAuthenticatorCache.java
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
-package android.accounts;
+package com.android.server.accounts;
 
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorDescription;
+import android.accounts.IAccountAuthenticator;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.RegisteredServicesCache;
diff --git a/core/java/android/accounts/AccountManagerService.java b/services/java/com/android/server/accounts/AccountManagerService.java
similarity index 99%
rename from core/java/android/accounts/AccountManagerService.java
rename to services/java/com/android/server/accounts/AccountManagerService.java
index 2b1a2b2..150df9e 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/services/java/com/android/server/accounts/AccountManagerService.java
@@ -14,9 +14,19 @@
  * limitations under the License.
  */
 
-package android.accounts;
+package com.android.server.accounts;
 
 import android.Manifest;
+import android.accounts.Account;
+import android.accounts.AccountAndUser;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorDescription;
+import android.accounts.GrantCredentialsPermissionActivity;
+import android.accounts.IAccountAuthenticator;
+import android.accounts.IAccountAuthenticatorResponse;
+import android.accounts.IAccountManager;
+import android.accounts.IAccountManagerResponse;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.Notification;
diff --git a/core/java/android/accounts/IAccountAuthenticatorCache.java b/services/java/com/android/server/accounts/IAccountAuthenticatorCache.java
similarity index 96%
rename from core/java/android/accounts/IAccountAuthenticatorCache.java
rename to services/java/com/android/server/accounts/IAccountAuthenticatorCache.java
index 06c2106..bb09687 100644
--- a/core/java/android/accounts/IAccountAuthenticatorCache.java
+++ b/services/java/com/android/server/accounts/IAccountAuthenticatorCache.java
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package android.accounts;
+package com.android.server.accounts;
 
+import android.accounts.AuthenticatorDescription;
 import android.content.pm.RegisteredServicesCache;
 import android.content.pm.RegisteredServicesCacheListener;
 import android.os.Handler;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 60b208d..1cd370a 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -115,6 +115,7 @@
 import android.os.StrictMode;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.UpdateLock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.format.Time;
@@ -191,6 +192,7 @@
     static final boolean DEBUG_POWER = localLOGV || false;
     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
     static final boolean DEBUG_MU = localLOGV || false;
+    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
     static final boolean VALIDATE_TOKENS = false;
     static final boolean SHOW_ACTIVITY_START_TIME = true;
     
@@ -827,6 +829,12 @@
     long mLastWriteTime = 0;
 
     /**
+     * Used to retain an update lock when the foreground activity is in
+     * immersive mode.
+     */
+    final UpdateLock mUpdateLock = new UpdateLock("immersive");
+
+    /**
      * Set to true after the system has finished booting.
      */
     boolean mBooted = false;
@@ -895,6 +903,7 @@
     static final int REPORT_USER_SWITCH_MSG = 34;
     static final int CONTINUE_USER_SWITCH_MSG = 35;
     static final int USER_SWITCH_TIMEOUT_MSG = 36;
+    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1356,6 +1365,21 @@
                 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
                 break;
             }
+            case IMMERSIVE_MODE_LOCK_MSG: {
+                final boolean nextState = (msg.arg1 != 0);
+                if (mUpdateLock.isHeld() != nextState) {
+                    if (DEBUG_IMMERSIVE) {
+                        final ActivityRecord r = (ActivityRecord) msg.obj;
+                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
+                    }
+                    if (nextState) {
+                        mUpdateLock.acquire();
+                    } else {
+                        mUpdateLock.release();
+                    }
+                }
+                break;
+            }
             }
         }
     };
@@ -1824,9 +1848,20 @@
             if (r != null) {
                 mWindowManager.setFocusedApp(r.appToken, true);
             }
+            applyUpdateLockStateLocked(r);
         }
     }
 
+    final void applyUpdateLockStateLocked(ActivityRecord r) {
+        // Modifications to the UpdateLock state are done on our handler, outside
+        // the activity manager's locks.  The new state is determined based on the
+        // state *now* of the relevant activity record.  The object is passed to
+        // the handler solely for logging detail, not to be consulted/modified.
+        final boolean nextState = r != null && r.immersive;
+        mHandler.sendMessage(
+                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
+    }
+
     private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
         // put it on the LRU to keep track of when it should be exited.
         int lrui = mLruProcesses.indexOf(app);
@@ -7423,11 +7458,19 @@
 
     public void setImmersive(IBinder token, boolean immersive) {
         synchronized(this) {
-            ActivityRecord r = mMainStack.isInStackLocked(token);
+            final ActivityRecord r = mMainStack.isInStackLocked(token);
             if (r == null) {
                 throw new IllegalArgumentException();
             }
             r.immersive = immersive;
+
+            // update associated state if we're frontmost
+            if (r == mFocusedActivity) {
+                if (DEBUG_IMMERSIVE) {
+                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
+                }
+                applyUpdateLockStateLocked(r);
+            }
         }
     }
 
@@ -12329,7 +12372,7 @@
                 }
                 newConfig.seq = mConfigurationSeq;
                 mConfiguration = newConfig;
-                Slog.i(TAG, "Config changed: " + newConfig);
+                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
 
                 final Configuration configCopy = new Configuration(mConfiguration);
                 
diff --git a/core/java/android/content/ContentService.java b/services/java/com/android/server/content/ContentService.java
similarity index 98%
rename from core/java/android/content/ContentService.java
rename to services/java/com/android/server/content/ContentService.java
index 8bac888..3b92338 100644
--- a/core/java/android/content/ContentService.java
+++ b/services/java/com/android/server/content/ContentService.java
@@ -14,10 +14,19 @@
  * limitations under the License.
  */
 
-package android.content;
+package com.android.server.content;
 
+import android.Manifest;
 import android.accounts.Account;
 import android.app.ActivityManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.IContentService;
+import android.content.ISyncStatusObserver;
+import android.content.PeriodicSync;
+import android.content.SyncAdapterType;
+import android.content.SyncInfo;
+import android.content.SyncStatusInfo;
 import android.database.IContentObserver;
 import android.database.sqlite.SQLiteException;
 import android.net.Uri;
@@ -30,7 +39,6 @@
 import android.os.UserHandle;
 import android.util.Log;
 import android.util.SparseIntArray;
-import android.Manifest;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/core/java/android/content/SyncManager.java b/services/java/com/android/server/content/SyncManager.java
similarity index 98%
rename from core/java/android/content/SyncManager.java
rename to services/java/com/android/server/content/SyncManager.java
index e428968..cd66cf2 100644
--- a/core/java/android/content/SyncManager.java
+++ b/services/java/com/android/server/content/SyncManager.java
@@ -14,18 +14,32 @@
  * limitations under the License.
  */
 
-package android.content;
+package com.android.server.content;
 
 import android.accounts.Account;
 import android.accounts.AccountAndUser;
 import android.accounts.AccountManager;
-import android.accounts.AccountManagerService;
 import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
-import android.content.SyncStorageEngine.OnSyncRequestListener;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ISyncAdapter;
+import android.content.ISyncContext;
+import android.content.ISyncStatusObserver;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.SyncActivityTooManyDeletes;
+import android.content.SyncAdapterType;
+import android.content.SyncAdaptersCache;
+import android.content.SyncInfo;
+import android.content.SyncResult;
+import android.content.SyncStatusInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
@@ -55,11 +69,12 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Pair;
-import android.util.Slog;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.accounts.AccountManagerService;
+import com.android.server.content.SyncStorageEngine.OnSyncRequestListener;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 import com.google.android.collect.Sets;
diff --git a/core/java/android/content/SyncOperation.java b/services/java/com/android/server/content/SyncOperation.java
similarity index 98%
rename from core/java/android/content/SyncOperation.java
rename to services/java/com/android/server/content/SyncOperation.java
index a4c2cff..eaad982 100644
--- a/core/java/android/content/SyncOperation.java
+++ b/services/java/com/android/server/content/SyncOperation.java
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
-package android.content;
+package com.android.server.content;
 
 import android.accounts.Account;
 import android.content.pm.PackageManager;
+import android.content.ContentResolver;
 import android.os.Bundle;
 import android.os.SystemClock;
 
diff --git a/core/java/android/content/SyncQueue.java b/services/java/com/android/server/content/SyncQueue.java
similarity index 98%
rename from core/java/android/content/SyncQueue.java
rename to services/java/com/android/server/content/SyncQueue.java
index c09703c..951e92c 100644
--- a/core/java/android/content/SyncQueue.java
+++ b/services/java/com/android/server/content/SyncQueue.java
@@ -14,14 +14,15 @@
  * limitations under the License.
  */
 
-package android.content;
+package com.android.server.content;
 
 import android.accounts.Account;
 import android.content.pm.PackageManager;
 import android.content.pm.RegisteredServicesCache;
+import android.content.SyncAdapterType;
+import android.content.SyncAdaptersCache;
 import android.content.pm.RegisteredServicesCache.ServiceInfo;
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.Pair;
diff --git a/core/java/android/content/SyncStorageEngine.java b/services/java/com/android/server/content/SyncStorageEngine.java
similarity index 98%
rename from core/java/android/content/SyncStorageEngine.java
rename to services/java/com/android/server/content/SyncStorageEngine.java
index 8d9b8e0..5b8d26f 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/services/java/com/android/server/content/SyncStorageEngine.java
@@ -14,18 +14,16 @@
  * limitations under the License.
  */
 
-package android.content;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.FastXmlSerializer;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
+package com.android.server.content;
 
 import android.accounts.Account;
 import android.accounts.AccountAndUser;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ISyncStatusObserver;
+import android.content.PeriodicSync;
+import android.content.SyncInfo;
+import android.content.SyncStatusInfo;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteException;
@@ -39,9 +37,17 @@
 import android.os.RemoteException;
 import android.util.AtomicFile;
 import android.util.Log;
+import android.util.Pair;
 import android.util.SparseArray;
 import android.util.Xml;
-import android.util.Pair;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.FastXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -50,9 +56,9 @@
 import java.util.Calendar;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Random;
 import java.util.TimeZone;
-import java.util.List;
 
 /**
  * Singleton that tracks the sync data and overall sync
@@ -107,9 +113,6 @@
 
     public static final long NOT_IN_BACKOFF_MODE = -1;
 
-    public static final Intent SYNC_CONNECTION_SETTING_CHANGED_INTENT =
-            new Intent("com.android.sync.SYNC_CONN_STATUS_CHANGED");
-
     // TODO: i18n -- grab these out of resources.
     /** String names for the sync source types. */
     public static final String[] SOURCES = { "SERVER",
@@ -710,7 +713,7 @@
                     for (int i = 0, N = authority.periodicSyncs.size(); i < N; i++) {
                         Pair<Bundle, Long> syncInfo = authority.periodicSyncs.get(i);
                         final Bundle existingExtras = syncInfo.first;
-                        if (equals(existingExtras, extras)) {
+                        if (PeriodicSync.syncExtrasEquals(existingExtras, extras)) {
                             if (syncInfo.second == period) {
                                 return;
                             }
@@ -734,7 +737,7 @@
                     int i = 0;
                     while (iterator.hasNext()) {
                         Pair<Bundle, Long> syncInfo = iterator.next();
-                        if (equals(syncInfo.first, extras)) {
+                        if (PeriodicSync.syncExtrasEquals(syncInfo.first, extras)) {
                             iterator.remove();
                             changed = true;
                             // if we removed an entry from the periodicSyncs array also
@@ -800,7 +803,7 @@
                     new Bundle());
         }
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
-        mContext.sendBroadcast(SYNC_CONNECTION_SETTING_CHANGED_INTENT);
+        mContext.sendBroadcast(ContentResolver.ACTION_SYNC_CONN_STATUS_CHANGED);
     }
 
     public boolean getMasterSyncAutomatically(int userId) {
@@ -1095,24 +1098,6 @@
         return id;
     }
 
-    public static boolean equals(Bundle b1, Bundle b2) {
-        if (b1.size() != b2.size()) {
-            return false;
-        }
-        if (b1.isEmpty()) {
-            return true;
-        }
-        for (String key : b1.keySet()) {
-            if (!b2.containsKey(key)) {
-                return false;
-            }
-            if (!b1.get(key).equals(b2.get(key))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
     public void stopSyncEvent(long historyId, long elapsedTime, String resultMessage,
             long downstreamActivity, long upstreamActivity) {
         synchronized (mAuthorities) {
diff --git a/services/java/com/android/server/dreams/DreamManagerService.java b/services/java/com/android/server/dreams/DreamManagerService.java
index 7e4a554..c9e0da5 100644
--- a/services/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/java/com/android/server/dreams/DreamManagerService.java
@@ -25,6 +25,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
@@ -38,6 +39,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
 
 import libcore.util.Objects;
 
@@ -279,7 +282,37 @@
         String names = Settings.Secure.getStringForUser(mContext.getContentResolver(),
                 Settings.Secure.SCREENSAVER_COMPONENTS,
                 userId);
-        return names == null ? null : componentsFromString(names);
+        ComponentName[] components = componentsFromString(names);
+
+        // first, ensure components point to valid services
+        List<ComponentName> validComponents = new ArrayList<ComponentName>();
+        if (components != null) {
+            for (ComponentName component : components) {
+                if (serviceExists(component)) {
+                    validComponents.add(component);
+                } else {
+                    Slog.w(TAG, "Dream " + component + " does not exist");
+                }
+            }
+        }
+
+        // fallback to the default dream component if necessary
+        if (validComponents.isEmpty()) {
+            ComponentName defaultDream = getDefaultDreamComponent();
+            if (defaultDream != null) {
+                Slog.w(TAG, "Falling back to default dream " + defaultDream);
+                validComponents.add(defaultDream);
+            }
+        }
+        return validComponents.toArray(new ComponentName[validComponents.size()]);
+    }
+
+    private boolean serviceExists(ComponentName name) {
+        try {
+            return name != null && mContext.getPackageManager().getServiceInfo(name, 0) != null;
+        } catch (NameNotFoundException e) {
+            return false;
+        }
     }
 
     private void startDreamLocked(final ComponentName name,
@@ -352,6 +385,9 @@
     }
 
     private static ComponentName[] componentsFromString(String names) {
+        if (names == null) {
+            return null;
+        }
         String[] namesArray = names.split(",");
         ComponentName[] componentNames = new ComponentName[namesArray.length];
         for (int i = 0; i < namesArray.length; i++) {
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index b839331..b09390c 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -425,11 +425,9 @@
     private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            synchronized (mRulesLock) {
-                // screen-related broadcasts are protected by system, no need
-                // for permissions check.
-                mHandler.obtainMessage(MSG_SCREEN_ON_CHANGED).sendToTarget();
-            }
+            // screen-related broadcasts are protected by system, no need
+            // for permissions check.
+            mHandler.obtainMessage(MSG_SCREEN_ON_CHANGED).sendToTarget();
         }
     };
 
diff --git a/core/java/android/os/SchedulingPolicyService.java b/services/java/com/android/server/os/SchedulingPolicyService.java
similarity index 96%
rename from core/java/android/os/SchedulingPolicyService.java
rename to services/java/com/android/server/os/SchedulingPolicyService.java
index a3fede6..c0123bf 100644
--- a/core/java/android/os/SchedulingPolicyService.java
+++ b/services/java/com/android/server/os/SchedulingPolicyService.java
@@ -14,13 +14,12 @@
  * limitations under the License.
  */
 
-package android.os;
+package com.android.server.os;
 
-import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Binder;
+import android.os.ISchedulingPolicyService;
 import android.os.Process;
-import android.util.Log;
 
 /**
  * The implementation of the scheduling policy service interface.
diff --git a/services/java/com/android/server/pm/Installer.java b/services/java/com/android/server/pm/Installer.java
index 71a6a01..02a2c1b 100644
--- a/services/java/com/android/server/pm/Installer.java
+++ b/services/java/com/android/server/pm/Installer.java
@@ -290,27 +290,6 @@
         return execute(builder.toString());
     }
 
-    /**
-     * Clone all the package data directories from srcUserId to targetUserId. If copyData is true,
-     * some of the data is also copied, otherwise just empty directories are created with the
-     * correct access rights.
-     * @param srcUserId user to copy the data directories from
-     * @param targetUserId user to copy the data directories to
-     * @param copyData whether the data itself is to be copied. If false, empty directories are
-     * created.
-     * @return success/error code
-     */
-    public int cloneUserData(int srcUserId, int targetUserId, boolean copyData) {
-        StringBuilder builder = new StringBuilder("cloneuserdata");
-        builder.append(' ');
-        builder.append(srcUserId);
-        builder.append(' ');
-        builder.append(targetUserId);
-        builder.append(' ');
-        builder.append(copyData ? '1' : '0');
-        return execute(builder.toString());
-    }
-
     public boolean ping() {
         if (execute("ping") < 0) {
             return false;
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index fd649a1..2238f17 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -6353,6 +6353,18 @@
                                 pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath,
                                         flags, lowThreshold);
                             }
+                            /*
+                             * The cache free must have deleted the file we
+                             * downloaded to install.
+                             *
+                             * TODO: fix the "freeCache" call to not delete
+                             *       the file we care about.
+                             */
+                            if (pkgLite.recommendedInstallLocation
+                                    == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
+                                pkgLite.recommendedInstallLocation
+                                    = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
+                            }
                         }
                     }
                 } finally {
diff --git a/services/java/com/android/server/power/Notifier.java b/services/java/com/android/server/power/Notifier.java
index 5e05693..d99d523 100644
--- a/services/java/com/android/server/power/Notifier.java
+++ b/services/java/com/android/server/power/Notifier.java
@@ -23,6 +23,10 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.media.AudioManager;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
 import android.os.BatteryStats;
 import android.os.Handler;
 import android.os.Looper;
@@ -32,6 +36,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.WorkSource;
+import android.provider.Settings;
 import android.util.EventLog;
 import android.util.Slog;
 import android.view.WindowManagerPolicy;
@@ -64,6 +69,7 @@
 
     private static final int MSG_USER_ACTIVITY = 1;
     private static final int MSG_BROADCAST = 2;
+    private static final int MSG_WIRELESS_CHARGING_STARTED = 3;
 
     private final Object mLock = new Object();
 
@@ -312,6 +318,20 @@
         }
     }
 
+    /**
+     * Called when wireless charging has started so as to provide user feedback.
+     */
+    public void onWirelessChargingStarted() {
+        if (DEBUG) {
+            Slog.d(TAG, "onWirelessChargingStarted");
+        }
+
+        mSuspendBlocker.acquire();
+        Message msg = mHandler.obtainMessage(MSG_WIRELESS_CHARGING_STARTED);
+        msg.setAsynchronous(true);
+        mHandler.sendMessage(msg);
+    }
+
     private void updatePendingBroadcastLocked() {
         if (!mBroadcastInProgress
                 && mActualPowerState != POWER_STATE_UNKNOWN
@@ -473,6 +493,23 @@
         }
     };
 
+    private void playWirelessChargingStartedSound() {
+        final String soundPath = Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.WIRELESS_CHARGING_STARTED_SOUND);
+        if (soundPath != null) {
+            final Uri soundUri = Uri.parse("file://" + soundPath);
+            if (soundUri != null) {
+                final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
+                if (sfx != null) {
+                    sfx.setStreamType(AudioManager.STREAM_SYSTEM);
+                    sfx.play();
+                }
+            }
+        }
+
+        mSuspendBlocker.release();
+    }
+
     private final class NotifierHandler extends Handler {
         public NotifierHandler(Looper looper) {
             super(looper, null, true /*async*/);
@@ -488,6 +525,10 @@
                 case MSG_BROADCAST:
                     sendNextBroadcast();
                     break;
+
+                case MSG_WIRELESS_CHARGING_STARTED:
+                    playWirelessChargingStartedSound();
+                    break;
             }
         }
     }
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 7f83c17..ec82290 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -238,11 +238,20 @@
     // is actually on or actually off or whatever was requested.
     private boolean mDisplayReady;
 
-    // True if holding a wake-lock to block suspend of the CPU.
+    // The suspend blocker used to keep the CPU alive when an application has acquired
+    // a wake lock.
+    private final SuspendBlocker mWakeLockSuspendBlocker;
+
+    // True if the wake lock suspend blocker has been acquired.
     private boolean mHoldingWakeLockSuspendBlocker;
 
-    // The suspend blocker used to keep the CPU alive when wake locks have been acquired.
-    private final SuspendBlocker mWakeLockSuspendBlocker;
+    // The suspend blocker used to keep the CPU alive when the display is on, the
+    // display is getting ready or there is user activity (in which case the display
+    // must be on).
+    private final SuspendBlocker mDisplaySuspendBlocker;
+
+    // True if the display suspend blocker has been acquired.
+    private boolean mHoldingDisplaySuspendBlocker;
 
     // The screen on blocker used to keep the screen from turning on while the lock
     // screen is coming up.
@@ -368,11 +377,13 @@
 
     public PowerManagerService() {
         synchronized (mLock) {
-            mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService");
-            mWakeLockSuspendBlocker.acquire();
+            mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
+            mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
+            mDisplaySuspendBlocker.acquire();
+            mHoldingDisplaySuspendBlocker = true;
+
             mScreenOnBlocker = new ScreenOnBlockerImpl();
             mDisplayBlanker = new DisplayBlankerImpl();
-            mHoldingWakeLockSuspendBlocker = true;
             mWakefulness = WAKEFULNESS_AWAKE;
         }
 
@@ -653,17 +664,21 @@
 
     private void releaseWakeLockInternal(IBinder lock, int flags) {
         synchronized (mLock) {
-            if (DEBUG_SPEW) {
-                Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
-                        + ", flags=0x" + Integer.toHexString(flags));
-            }
-
             int index = findWakeLockIndexLocked(lock);
             if (index < 0) {
+                if (DEBUG_SPEW) {
+                    Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
+                            + " [not found], flags=0x" + Integer.toHexString(flags));
+                }
                 return;
             }
 
             WakeLock wakeLock = mWakeLocks.get(index);
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
+                        + " [" + wakeLock.mTag + "], flags=0x" + Integer.toHexString(flags));
+            }
+
             mWakeLocks.remove(index);
             notifyWakeLockReleasedLocked(wakeLock);
             wakeLock.mLock.unlinkToDeath(wakeLock, 0);
@@ -681,7 +696,8 @@
     private void handleWakeLockDeath(WakeLock wakeLock) {
         synchronized (mLock) {
             if (DEBUG_SPEW) {
-                Slog.d(TAG, "handleWakeLockDeath: lock=" + Objects.hashCode(wakeLock.mLock));
+                Slog.d(TAG, "handleWakeLockDeath: lock=" + Objects.hashCode(wakeLock.mLock)
+                        + " [" + wakeLock.mTag + "]");
             }
 
             int index = mWakeLocks.indexOf(wakeLock);
@@ -733,10 +749,19 @@
         synchronized (mLock) {
             int index = findWakeLockIndexLocked(lock);
             if (index < 0) {
+                if (DEBUG_SPEW) {
+                    Slog.d(TAG, "updateWakeLockWorkSourceInternal: lock=" + Objects.hashCode(lock)
+                            + " [not found], ws=" + ws);
+                }
                 throw new IllegalArgumentException("Wake lock not active");
             }
 
             WakeLock wakeLock = mWakeLocks.get(index);
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "updateWakeLockWorkSourceInternal: lock=" + Objects.hashCode(lock)
+                        + " [" + wakeLock.mTag + "], ws=" + ws);
+            }
+
             if (!wakeLock.hasSameWorkSource(ws)) {
                 notifyWakeLockReleasedLocked(wakeLock);
                 wakeLock.updateWorkSource(ws);
@@ -1150,6 +1175,16 @@
                 }
                 userActivityNoUpdateLocked(
                         now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
+
+                // Tell the notifier whether wireless charging has started so that
+                // it can provide feedback to the user.  Refer to
+                // shouldWakeUpWhenPluggedOrUnpluggedLocked for justification of the
+                // heuristics used here.
+                if (!wasPowered && mIsPowered
+                        && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
+                        && mBatteryLevel < WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) {
+                    mNotifier.onWirelessChargingStarted();
+                }
             }
         }
     }
@@ -1709,29 +1744,30 @@
      * This function must have no other side-effects.
      */
     private void updateSuspendBlockerLocked() {
-        boolean wantCpu = isCpuNeededLocked();
-        if (wantCpu != mHoldingWakeLockSuspendBlocker) {
-            mHoldingWakeLockSuspendBlocker = wantCpu;
-            if (wantCpu) {
-                if (DEBUG) {
-                    Slog.d(TAG, "updateSuspendBlockerLocked: Acquiring suspend blocker.");
-                }
-                mWakeLockSuspendBlocker.acquire();
-            } else {
-                if (DEBUG) {
-                    Slog.d(TAG, "updateSuspendBlockerLocked: Releasing suspend blocker.");
-                }
-                mWakeLockSuspendBlocker.release();
-            }
-        }
-    }
-
-    private boolean isCpuNeededLocked() {
-        return !mBootCompleted
-                || mWakeLockSummary != 0
-                || mUserActivitySummary != 0
+        final boolean needWakeLockSuspendBlocker = (mWakeLockSummary != 0);
+        final boolean needDisplaySuspendBlocker = (mUserActivitySummary != 0
                 || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
-                || !mDisplayReady;
+                || !mDisplayReady || !mBootCompleted);
+
+        // First acquire suspend blockers if needed.
+        if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
+            mWakeLockSuspendBlocker.acquire();
+            mHoldingWakeLockSuspendBlocker = true;
+        }
+        if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) {
+            mDisplaySuspendBlocker.acquire();
+            mHoldingDisplaySuspendBlocker = true;
+        }
+
+        // Then release suspend blockers if needed.
+        if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
+            mWakeLockSuspendBlocker.release();
+            mHoldingWakeLockSuspendBlocker = false;
+        }
+        if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) {
+            mDisplaySuspendBlocker.release();
+            mHoldingDisplaySuspendBlocker = false;
+        }
     }
 
     @Override // Binder call
@@ -2201,6 +2237,7 @@
                     + TimeUtils.formatUptime(mLastUserActivityTimeNoChangeLights));
             pw.println("  mDisplayReady=" + mDisplayReady);
             pw.println("  mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
+            pw.println("  mHoldingDisplaySuspendBlocker=" + mHoldingDisplaySuspendBlocker);
 
             pw.println();
             pw.println("Settings and Configuration:");
@@ -2496,6 +2533,9 @@
             synchronized (this) {
                 mReferenceCount += 1;
                 if (mReferenceCount == 1) {
+                    if (DEBUG_SPEW) {
+                        Slog.d(TAG, "Acquiring suspend blocker \"" + mName + "\".");
+                    }
                     nativeAcquireSuspendBlocker(mName);
                 }
             }
@@ -2506,6 +2546,9 @@
             synchronized (this) {
                 mReferenceCount -= 1;
                 if (mReferenceCount == 0) {
+                    if (DEBUG_SPEW) {
+                        Slog.d(TAG, "Releasing suspend blocker \"" + mName + "\".");
+                    }
                     nativeReleaseSuspendBlocker(mName);
                 } else if (mReferenceCount < 0) {
                     Log.wtf(TAG, "Suspend blocker \"" + mName
diff --git a/core/java/android/server/search/SearchManagerService.java b/services/java/com/android/server/search/SearchManagerService.java
similarity index 99%
rename from core/java/android/server/search/SearchManagerService.java
rename to services/java/com/android/server/search/SearchManagerService.java
index 46f2723..132ae79 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/services/java/com/android/server/search/SearchManagerService.java
@@ -14,10 +14,7 @@
  * limitations under the License.
  */
 
-package android.server.search;
-
-import com.android.internal.content.PackageMonitor;
-import com.android.internal.util.IndentingPrintWriter;
+package com.android.server.search;
 
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
@@ -45,6 +42,9 @@
 import android.util.Slog;
 import android.util.SparseArray;
 
+import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.IndentingPrintWriter;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.List;
diff --git a/core/java/android/server/search/Searchables.java b/services/java/com/android/server/search/Searchables.java
similarity index 99%
rename from core/java/android/server/search/Searchables.java
rename to services/java/com/android/server/search/Searchables.java
index a0095d6..0ffbb7d 100644
--- a/core/java/android/server/search/Searchables.java
+++ b/services/java/com/android/server/search/Searchables.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.server.search;
+package com.android.server.search;
 
 import android.app.AppGlobals;
 import android.app.SearchManager;
diff --git a/services/java/com/android/server/wm/AppTransition.java b/services/java/com/android/server/wm/AppTransition.java
index a956a80..92fd68b 100644
--- a/services/java/com/android/server/wm/AppTransition.java
+++ b/services/java/com/android/server/wm/AppTransition.java
@@ -110,8 +110,8 @@
         return mAppTransitionReady;
     }
 
-    void setReady(boolean ready) {
-        mAppTransitionReady = ready;
+    void setReady() {
+        mAppTransitionReady = true;
     }
 
     boolean isRunning() {
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index 49f8c0e..34513a1 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -129,7 +129,7 @@
             if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
                 mService.setInputMethodAnimLayerAdjustment(adj);
             }
-            if (w == mAnimator.mWallpaperTarget && mAnimator.mLowerWallpaperTarget == null) {
+            if (w == mService.mWallpaperTarget && mService.mLowerWallpaperTarget == null) {
                 mService.setWallpaperAnimLayerAdjustmentLocked(adj);
             }
         }
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index 3ec6d26..275c9bf 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -30,7 +30,6 @@
 import android.view.WindowManager;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 
 /**
  * Version of WindowToken that is specifically for a particular application (or
@@ -42,7 +41,7 @@
 
     // All of the windows and child windows that are included in this
     // application token.  Note this list is NOT sorted!
-    final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
+    final WindowList allAppWindows = new WindowList();
     final AppWindowAnimator mAppAnimator;
 
     final WindowAnimator mAnimator;
diff --git a/services/java/com/android/server/wm/DisplayMagnificationMediator.java b/services/java/com/android/server/wm/DisplayMagnificationMediator.java
index 8621c5c..0e3a6e1 100644
--- a/services/java/com/android/server/wm/DisplayMagnificationMediator.java
+++ b/services/java/com/android/server/wm/DisplayMagnificationMediator.java
@@ -183,8 +183,6 @@
             displayState.mMagnificationSpec.initialize(spec.scale, spec.offsetX,
                     spec.offsetY);
             spec.recycle();
-        }
-        synchronized (mWindowManagerService.mLayoutToAnim) {
             mWindowManagerService.scheduleAnimationLocked();
         }
     }
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 73293b0..74f51d7 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -9,8 +9,7 @@
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_MAY_CHANGE;
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_FORCE_HIDING_CHANGED;
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
-
-import static com.android.server.wm.WindowManagerService.H.UPDATE_ANIM_PARAMETERS;
+import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_ACTION_PENDING;
 
 import android.content.Context;
 import android.os.Debug;
@@ -25,9 +24,8 @@
 import android.view.WindowManagerPolicy;
 import android.view.animation.Animation;
 
-import com.android.server.wm.WindowManagerService.AppWindowAnimParams;
+import com.android.server.wm.WindowManagerService.DisplayContentsIterator;
 import com.android.server.wm.WindowManagerService.LayoutFields;
-import com.android.server.wm.WindowManagerService.LayoutToAnimatorParams;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -49,9 +47,6 @@
 
     int mAdjResult;
 
-    // Layout changes for individual Displays. Indexed by displayId.
-    SparseIntArray mPendingLayoutChanges = new SparseIntArray();
-
     /** Time of current animation step. Reset on each iteration */
     long mCurrentTime;
 
@@ -59,10 +54,10 @@
      * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
     private int mAnimTransactionSequence;
 
-    // Window currently running an animation that has requested it be detached
-    // from the wallpaper.  This means we need to ensure the wallpaper is
-    // visible behind it in case it animates in a way that would allow it to be
-    // seen. If multiple windows satisfy this, use the lowest window.
+    /** Window currently running an animation that has requested it be detached
+     * from the wallpaper.  This means we need to ensure the wallpaper is
+     * visible behind it in case it animates in a way that would allow it to be
+     * seen. If multiple windows satisfy this, use the lowest window. */
     WindowState mWindowDetachedWallpaper = null;
 
     WindowStateAnimator mUniverseBackground = null;
@@ -73,28 +68,6 @@
     SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators =
             new SparseArray<WindowAnimator.DisplayContentsAnimator>();
 
-    static final int WALLPAPER_ACTION_PENDING = 1;
-    int mPendingActions;
-
-    WindowState mWallpaperTarget = null;
-    AppWindowAnimator mWpAppAnimator = null;
-    WindowState mLowerWallpaperTarget = null;
-    WindowState mUpperWallpaperTarget = null;
-
-    ArrayList<AppWindowAnimator> mAppAnimators = new ArrayList<AppWindowAnimator>();
-
-    ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
-
-    /** Parameters being passed from this into mService. */
-    static class AnimatorToLayoutParams {
-        boolean mUpdateQueued;
-        int mBulkUpdateParams;
-        SparseIntArray mPendingLayoutChanges;
-        WindowState mWindowDetachedWallpaper;
-    }
-    /** Do not modify unless holding mService.mWindowMap or this and mAnimToLayout in that order */
-    final AnimatorToLayoutParams mAnimToLayout = new AnimatorToLayoutParams();
-
     boolean mInitialized = false;
 
     // forceHiding states.
@@ -122,13 +95,9 @@
         mAnimationRunnable = new Runnable() {
             @Override
             public void run() {
-                // TODO(cmautner): When full isolation is achieved for animation, the first lock
-                // goes away and only the WindowAnimator.this remains.
-                synchronized(mService.mWindowMap) {
-                    synchronized(WindowAnimator.this) {
-                        copyLayoutToAnimParamsLocked();
-                        animateLocked();
-                    }
+                synchronized (mService.mWindowMap) {
+                    mService.mAnimationScheduled = false;
+                    animateLocked();
                 }
             }
         };
@@ -162,117 +131,17 @@
         mDisplayContentsAnimators.delete(displayId);
     }
 
-    /** Locked on mAnimToLayout */
-    void updateAnimToLayoutLocked() {
-        final AnimatorToLayoutParams animToLayout = mAnimToLayout;
-        synchronized (animToLayout) {
-            animToLayout.mBulkUpdateParams = mBulkUpdateParams;
-            animToLayout.mPendingLayoutChanges = mPendingLayoutChanges.clone();
-            animToLayout.mWindowDetachedWallpaper = mWindowDetachedWallpaper;
-
-            if (!animToLayout.mUpdateQueued) {
-                animToLayout.mUpdateQueued = true;
-                mService.mH.sendMessage(mService.mH.obtainMessage(UPDATE_ANIM_PARAMETERS));
-            }
-        }
+    AppWindowAnimator getWallpaperAppAnimator() {
+        return mService.mWallpaperTarget == null
+                ? null : mService.mWallpaperTarget.mAppToken == null
+                        ? null : mService.mWallpaperTarget.mAppToken.mAppAnimator;
     }
 
-    /** Copy all WindowManagerService params into local params here. Locked on 'this'. */
-    private void copyLayoutToAnimParamsLocked() {
-        final LayoutToAnimatorParams layoutToAnim = mService.mLayoutToAnim;
-        synchronized(layoutToAnim) {
-            layoutToAnim.mAnimationScheduled = false;
+    void hideWallpapersLocked(final WindowState w) {
+        final WindowState wallpaperTarget = mService.mWallpaperTarget;
+        final WindowState lowerWallpaperTarget = mService.mLowerWallpaperTarget;
+        final ArrayList<WindowToken> wallpaperTokens = mService.mWallpaperTokens;
 
-            if (!layoutToAnim.mParamsModified) {
-                return;
-            }
-            layoutToAnim.mParamsModified = false;
-
-            if ((layoutToAnim.mChanges & LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED) != 0) {
-                layoutToAnim.mChanges &= ~LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED;
-                mWallpaperTokens = new ArrayList<WindowToken>(layoutToAnim.mWallpaperTokens);
-            }
-
-            if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) {
-                if (mWallpaperTarget != layoutToAnim.mWallpaperTarget
-                        || mLowerWallpaperTarget != layoutToAnim.mLowerWallpaperTarget
-                        || mUpperWallpaperTarget != layoutToAnim.mUpperWallpaperTarget) {
-                    Slog.d(TAG, "Pulling anim wallpaper: target=" + layoutToAnim.mWallpaperTarget
-                            + " lower=" + layoutToAnim.mLowerWallpaperTarget + " upper="
-                            + layoutToAnim.mUpperWallpaperTarget);
-                }
-            }
-            mWallpaperTarget = layoutToAnim.mWallpaperTarget;
-            mWpAppAnimator = mWallpaperTarget == null
-                    ? null : mWallpaperTarget.mAppToken == null
-                            ? null : mWallpaperTarget.mAppToken.mAppAnimator;
-            mLowerWallpaperTarget = layoutToAnim.mLowerWallpaperTarget;
-            mUpperWallpaperTarget = layoutToAnim.mUpperWallpaperTarget;
-
-            // Set the new DimAnimator params.
-            final int numDisplays = mDisplayContentsAnimators.size();
-            for (int i = 0; i < numDisplays; i++) {
-                final int displayId = mDisplayContentsAnimators.keyAt(i);
-                DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
-
-                displayAnimator.mWinAnimators.clear();
-                final WinAnimatorList winAnimators = layoutToAnim.mWinAnimatorLists.get(displayId);
-                if (winAnimators != null) {
-                    displayAnimator.mWinAnimators.addAll(winAnimators);
-                }
-
-                DimAnimator.Parameters dimParams = layoutToAnim.mDimParams.get(displayId);
-                if (dimParams == null) {
-                    displayAnimator.mDimParams = null;
-                } else {
-                    final WindowStateAnimator newWinAnimator = dimParams.mDimWinAnimator;
-
-                    // Only set dim params on the highest dimmed layer.
-                    final WindowStateAnimator existingDimWinAnimator =
-                            displayAnimator.mDimParams == null ?
-                                    null : displayAnimator.mDimParams.mDimWinAnimator;
-                    // Don't turn on for an unshown surface, or for any layer but the highest
-                    // dimmed layer.
-                    if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null
-                            || !existingDimWinAnimator.mSurfaceShown
-                            || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
-                        displayAnimator.mDimParams = new DimAnimator.Parameters(dimParams);
-                    }
-                }
-            }
-
-            mAppAnimators.clear();
-            final int N = layoutToAnim.mAppWindowAnimParams.size();
-            for (int i = 0; i < N; i++) {
-                final AppWindowAnimParams params = layoutToAnim.mAppWindowAnimParams.get(i);
-                AppWindowAnimator appAnimator = params.mAppAnimator;
-                appAnimator.mAllAppWinAnimators.clear();
-                appAnimator.mAllAppWinAnimators.addAll(params.mWinAnimators);
-                mAppAnimators.add(appAnimator);
-            }
-        }
-    }
-
-    void hideWallpapersLocked(final WindowState w, boolean fromAnimator) {
-        // There is an issue where this function can be called either from
-        // the animation or the layout side of the window manager.  The problem
-        // is that if it is called from the layout side, we may not yet have
-        // propagated the current layout wallpaper state over into the animation
-        // state.  If that is the case, we can do bad things like hide the
-        // wallpaper when we had just made it shown because the animation side
-        // doesn't yet see that there is now a wallpaper target.  As a temporary
-        // work-around, we tell the function here which side of the window manager
-        // is calling so it can use the right state.
-        if (fromAnimator) {
-            hideWallpapersLocked(w, mWallpaperTarget, mLowerWallpaperTarget, mWallpaperTokens);
-        } else {
-            hideWallpapersLocked(w, mService.mWallpaperTarget,
-                    mService.mLowerWallpaperTarget, mService.mWallpaperTokens);
-        }
-    }
-
-    void hideWallpapersLocked(final WindowState w, final WindowState wallpaperTarget,
-            final WindowState lowerWallpaperTarget, final ArrayList<WindowToken> wallpaperTokens) {
         if ((wallpaperTarget == w && lowerWallpaperTarget == null) || wallpaperTarget == null) {
             final int numTokens = wallpaperTokens.size();
             for (int i = numTokens - 1; i >= 0; i--) {
@@ -299,9 +168,10 @@
 
     private void updateAppWindowsLocked() {
         int i;
-        final int NAT = mAppAnimators.size();
+        final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
+        final int NAT = appTokens.size();
         for (i=0; i<NAT; i++) {
-            final AppWindowAnimator appAnimator = mAppAnimators.get(i);
+            final AppWindowAnimator appAnimator = appTokens.get(i).mAppAnimator;
             final boolean wasAnimating = appAnimator.animation != null
                     && appAnimator.animation != AppWindowAnimator.sDummyAnimation;
             if (appAnimator.stepAnimationLocked(mCurrentTime)) {
@@ -335,15 +205,14 @@
     private void updateWindowsLocked(final int displayId) {
         ++mAnimTransactionSequence;
 
-        final WinAnimatorList winAnimatorList =
-                getDisplayContentsAnimatorLocked(displayId).mWinAnimators;
+        final WindowList windows = mService.getWindowListLocked(displayId);
         ArrayList<WindowStateAnimator> unForceHiding = null;
         boolean wallpaperInUnForceHiding = false;
         mForceHiding = KEYGUARD_NOT_SHOWN;
 
-        for (int i = winAnimatorList.size() - 1; i >= 0; i--) {
-            WindowStateAnimator winAnimator = winAnimatorList.get(i);
-            WindowState win = winAnimator.mWin;
+        for (int i = windows.size() - 1; i >= 0; i--) {
+            WindowState win = windows.get(i);
+            WindowStateAnimator winAnimator = win.mWinAnimator;
             final int flags = winAnimator.mAttrFlags;
 
             if (winAnimator.mSurface != null) {
@@ -355,13 +224,13 @@
                             ", nowAnimating=" + nowAnimating);
                 }
 
-                if (wasAnimating && !winAnimator.mAnimating && mWallpaperTarget == win) {
+                if (wasAnimating && !winAnimator.mAnimating && mService.mWallpaperTarget == win) {
                     mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
                     setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
                             WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
                     if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
                         mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 2",
-                            mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY));
+                                getPendingLayoutChanges(Display.DEFAULT_DISPLAY));
                     }
                 }
 
@@ -375,7 +244,7 @@
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
                         if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
                             mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 3",
-                                mPendingLayoutChanges.get(displayId));
+                                    getPendingLayoutChanges(displayId));
                         }
                         mService.mFocusMayChange = true;
                     }
@@ -438,7 +307,7 @@
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
                         if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
                             mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 4",
-                                mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY));
+                                    getPendingLayoutChanges(Display.DEFAULT_DISPLAY));
                         }
                     }
                 }
@@ -448,11 +317,11 @@
             if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) {
                 if (atoken == null || atoken.allDrawn) {
                     if (winAnimator.performShowLocked()) {
-                        mPendingLayoutChanges.put(displayId,
+                        setPendingLayoutChanges(displayId,
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
                         if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
                             mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5",
-                                mPendingLayoutChanges.get(displayId));
+                                    getPendingLayoutChanges(displayId));
                         }
                     }
                 }
@@ -486,21 +355,21 @@
     private void updateWallpaperLocked(int displayId) {
         final DisplayContentsAnimator displayAnimator =
                 getDisplayContentsAnimatorLocked(displayId);
-        final WinAnimatorList winAnimatorList = displayAnimator.mWinAnimators;
+        final WindowList windows = mService.getWindowListLocked(displayId);
         WindowStateAnimator windowAnimationBackground = null;
         int windowAnimationBackgroundColor = 0;
         WindowState detachedWallpaper = null;
         final DimSurface windowAnimationBackgroundSurface =
                 displayAnimator.mWindowAnimationBackgroundSurface;
 
-        for (int i = winAnimatorList.size() - 1; i >= 0; i--) {
-            WindowStateAnimator winAnimator = winAnimatorList.get(i);
+        for (int i = windows.size() - 1; i >= 0; i--) {
+            final WindowState win = windows.get(i);
+            WindowStateAnimator winAnimator = win.mWinAnimator;
             if (winAnimator.mSurface == null) {
                 continue;
             }
 
             final int flags = winAnimator.mAttrFlags;
-            final WindowState win = winAnimator.mWin;
 
             // If this window is animating, make a note that we have
             // an animating window and take care of a request to run
@@ -559,11 +428,11 @@
             // don't cause the wallpaper to suddenly disappear.
             int animLayer = windowAnimationBackground.mAnimLayer;
             WindowState win = windowAnimationBackground.mWin;
-            if (mWallpaperTarget == win
-                    || mLowerWallpaperTarget == win || mUpperWallpaperTarget == win) {
-                final int N = winAnimatorList.size();
+            if (mService.mWallpaperTarget == win || mService.mLowerWallpaperTarget == win
+                    || mService.mUpperWallpaperTarget == win) {
+                final int N = windows.size();
                 for (int i = 0; i < N; i++) {
-                    WindowStateAnimator winAnimator = winAnimatorList.get(i);
+                    WindowStateAnimator winAnimator = windows.get(i).mWinAnimator;
                     if (winAnimator.mIsWallpaper) {
                         animLayer = winAnimator.mAnimLayer;
                         break;
@@ -586,10 +455,13 @@
     /** See if any windows have been drawn, so they (and others associated with them) can now be
      *  shown. */
     private void testTokenMayBeDrawnLocked() {
-        final int NT = mAppAnimators.size();
+        // See if any windows have been drawn, so they (and others
+        // associated with them) can now be shown.
+        final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
+        final int NT = appTokens.size();
         for (int i=0; i<NT; i++) {
-            AppWindowAnimator appAnimator = mAppAnimators.get(i);
-            AppWindowToken wtoken = appAnimator.mAppToken;
+            AppWindowToken wtoken = appTokens.get(i);
+            AppWindowAnimator appAnimator = wtoken.mAppAnimator;
             final boolean allDrawn = wtoken.allDrawn;
             if (allDrawn != appAnimator.allDrawn) {
                 appAnimator.allDrawn = allDrawn;
@@ -611,7 +483,7 @@
                         setAppLayoutChanges(appAnimator,
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM,
                                 "testTokenMayBeDrawnLocked");
- 
+
                         // We can now show all of the drawn windows!
                         if (!mService.mOpeningApps.contains(wtoken)) {
                             mAnimating |= appAnimator.showAllWindowsLocked();
@@ -634,7 +506,6 @@
             return;
         }
 
-        mPendingLayoutChanges.clear();
         mCurrentTime = SystemClock.uptimeMillis();
         mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
         boolean wasAnimating = mAnimating;
@@ -671,10 +542,10 @@
                 // associated with exiting/removed apps
                 performAnimationsLocked(displayId);
 
-                final WinAnimatorList winAnimatorList = displayAnimator.mWinAnimators;
-                final int N = winAnimatorList.size();
+                final WindowList windows = mService.getWindowListLocked(displayId);
+                final int N = windows.size();
                 for (int j = 0; j < N; j++) {
-                    winAnimatorList.get(j).prepareSurfaceLocked(true);
+                    windows.get(j).mWinAnimator.prepareSurfaceLocked(true);
                 }
             }
 
@@ -712,21 +583,30 @@
                     TAG, "<<< CLOSE TRANSACTION animateLocked");
         }
 
-        for (int i = mPendingLayoutChanges.size() - 1; i >= 0; i--) {
-            if ((mPendingLayoutChanges.valueAt(i)
-                    & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
-                mPendingActions |= WALLPAPER_ACTION_PENDING;
+        boolean hasPendingLayoutChanges = false;
+        DisplayContentsIterator iterator = mService.new DisplayContentsIterator();
+        while (iterator.hasNext()) {
+            final DisplayContent displayContent = iterator.next();
+            final int pendingChanges = getPendingLayoutChanges(displayContent.getDisplayId());
+            if ((pendingChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
+                mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
+            }
+            if (pendingChanges != 0) {
+                hasPendingLayoutChanges = true;
             }
         }
 
-        if (mBulkUpdateParams != 0 || mPendingLayoutChanges.size() > 0) {
-            updateAnimToLayoutLocked();
+        boolean doRequest = false;
+        if (mBulkUpdateParams != 0) {
+            doRequest = mService.copyAnimToLayoutParamsLocked();
+        }
+
+        if (hasPendingLayoutChanges || doRequest) {
+            mService.requestTraversalLocked();
         }
 
         if (mAnimating) {
-            synchronized (mService.mLayoutToAnim) {
-                mService.scheduleAnimationLocked();
-            }
+            mService.scheduleAnimationLocked();
         } else if (wasAnimating) {
             mService.requestTraversalLocked();
         }
@@ -734,7 +614,7 @@
             Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating
                 + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams)
                 + " mPendingLayoutChanges(DEFAULT_DISPLAY)="
-                + Integer.toHexString(mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY)));
+                + Integer.toHexString(getPendingLayoutChanges(Display.DEFAULT_DISPLAY)));
         }
     }
 
@@ -777,51 +657,16 @@
         final String subPrefix = "  " + prefix;
         final String subSubPrefix = "  " + subPrefix;
 
-        boolean needSep = false;
-        if (mAppAnimators.size() > 0) {
-            needSep = true;
-            pw.println("  App Animators:");
-            for (int i=mAppAnimators.size()-1; i>=0; i--) {
-                AppWindowAnimator anim = mAppAnimators.get(i);
-                pw.print(prefix); pw.print("App Animator #"); pw.print(i);
-                        pw.print(' '); pw.print(anim);
-                if (dumpAll) {
-                    pw.println(':');
-                    anim.dump(pw, subPrefix, dumpAll);
-                } else {
-                    pw.println();
-                }
-            }
-        }
-        if (mWallpaperTokens.size() > 0) {
-            if (needSep) {
-                pw.println();
-            }
-            needSep = true;
-            pw.print(prefix); pw.println("Wallpaper tokens:");
-            for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
-                WindowToken token = mWallpaperTokens.get(i);
-                pw.print(prefix); pw.print("Wallpaper #"); pw.print(i);
-                        pw.print(' '); pw.print(token);
-                if (dumpAll) {
-                    pw.println(':');
-                    token.dump(pw, subPrefix);
-                } else {
-                    pw.println();
-                }
-            }
-        }
-
-        if (needSep) {
-            pw.println();
-        }
         for (int i = 0; i < mDisplayContentsAnimators.size(); i++) {
             pw.print(prefix); pw.print("DisplayContentsAnimator #");
                     pw.print(mDisplayContentsAnimators.keyAt(i));
                     pw.println(":");
             DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
-            for (int j=0; j<displayAnimator.mWinAnimators.size(); j++) {
-                WindowStateAnimator wanim = displayAnimator.mWinAnimators.get(j);
+            final WindowList windows =
+                    mService.getWindowListLocked(mDisplayContentsAnimators.keyAt(i));
+            final int N = windows.size();
+            for (int j = 0; j < N; j++) {
+                WindowStateAnimator wanim = windows.get(j).mWinAnimator;
                 pw.print(subPrefix); pw.print("Window #"); pw.print(j);
                         pw.print(": "); pw.println(wanim);
             }
@@ -867,48 +712,34 @@
                     pw.print(Integer.toHexString(mBulkUpdateParams));
                     pw.println(bulkUpdateParamsToString(mBulkUpdateParams));
         }
-        if (mPendingActions != 0) {
-            pw.print(prefix); pw.print("mPendingActions=0x");
-                    pw.println(Integer.toHexString(mPendingActions));
-        }
         if (mWindowDetachedWallpaper != null) {
             pw.print(prefix); pw.print("mWindowDetachedWallpaper=");
                 pw.println(mWindowDetachedWallpaper);
         }
-        pw.print(prefix); pw.print("mWallpaperTarget="); pw.println(mWallpaperTarget);
-        pw.print(prefix); pw.print("mWpAppAnimator="); pw.println(mWpAppAnimator);
-        if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
-            pw.print(prefix); pw.print("mLowerWallpaperTarget=");
-                    pw.println(mLowerWallpaperTarget);
-            pw.print(prefix); pw.print("mUpperWallpaperTarget=");
-                    pw.println(mUpperWallpaperTarget);
-        }
         if (mUniverseBackground != null) {
             pw.print(prefix); pw.print("mUniverseBackground="); pw.print(mUniverseBackground);
                     pw.print(" mAboveUniverseLayer="); pw.println(mAboveUniverseLayer);
         }
     }
 
-    void clearPendingActions() {
-        synchronized (this) {
-            mPendingActions = 0;
-        }
+    int getPendingLayoutChanges(final int displayId) {
+        return mService.getDisplayContentLocked(displayId).pendingLayoutChanges;
     }
 
     void setPendingLayoutChanges(final int displayId, final int changes) {
-        mPendingLayoutChanges.put(displayId, mPendingLayoutChanges.get(displayId) | changes);
+        mService.getDisplayContentLocked(displayId).pendingLayoutChanges |= changes;
     }
 
     void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) {
         // Used to track which displays layout changes have been done.
         SparseIntArray displays = new SparseIntArray();
-        for (int i = appAnimator.mAllAppWinAnimators.size() - 1; i >= 0; i--) {
-            WindowStateAnimator winAnimator = appAnimator.mAllAppWinAnimators.get(i);
-            final int displayId = winAnimator.mWin.mDisplayContent.getDisplayId();
+        WindowList windows = appAnimator.mAppToken.allAppWindows;
+        for (int i = windows.size() - 1; i >= 0; i--) {
+            final int displayId = windows.get(i).getDisplayId();
             if (displays.indexOfKey(displayId) < 0) {
                 setPendingLayoutChanges(displayId, changes);
                 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
-                    mService.debugLayoutRepeats(s, mPendingLayoutChanges.get(displayId));
+                    mService.debugLayoutRepeats(s, getPendingLayoutChanges(displayId));
                 }
                 // Keep from processing this display again.
                 displays.put(displayId, changes);
@@ -916,6 +747,27 @@
         }
     }
 
+    void setDimParamsLocked(int displayId, DimAnimator.Parameters dimParams) {
+        DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId);
+        if (dimParams == null) {
+            displayAnimator.mDimParams = null;
+        } else {
+            final WindowStateAnimator newWinAnimator = dimParams.mDimWinAnimator;
+
+            // Only set dim params on the highest dimmed layer.
+            final WindowStateAnimator existingDimWinAnimator =
+                    displayAnimator.mDimParams == null ?
+                            null : displayAnimator.mDimParams.mDimWinAnimator;
+            // Don't turn on for an unshown surface, or for any layer but the highest
+            // dimmed layer.
+            if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null
+                    || !existingDimWinAnimator.mSurfaceShown
+                    || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
+                displayAnimator.mDimParams = new DimAnimator.Parameters(dimParams);
+            }
+        }
+    }
+
     private DisplayContentsAnimator getDisplayContentsAnimatorLocked(int displayId) {
         DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId);
         if (displayAnimator == null) {
@@ -934,7 +786,6 @@
     }
 
     private class DisplayContentsAnimator {
-        WinAnimatorList mWinAnimators = new WinAnimatorList();
         DimAnimator mDimAnimator = null;
         DimAnimator.Parameters mDimParams = null;
         DimSurface mWindowAnimationBackgroundSurface = null;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 9041a9b..653f075 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -40,6 +40,8 @@
 import static android.view.WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.policy.PolicyManager;
 import com.android.internal.policy.impl.PhoneWindowManager;
@@ -125,7 +127,6 @@
 import android.view.InputEvent;
 import android.view.InputEventReceiver;
 import android.view.KeyEvent;
-import android.view.MagnificationSpec;
 import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.SurfaceSession;
@@ -522,7 +523,7 @@
     WindowState mLowerWallpaperTarget = null;
     // If non-null, we are in the middle of animating from one wallpaper target
     // to another, and this is the higher one in Z-order.
-    private WindowState mUpperWallpaperTarget = null;
+    WindowState mUpperWallpaperTarget = null;
     int mWallpaperAnimLayerAdjustment;
     float mLastWallpaperX = -1;
     float mLastWallpaperY = -1;
@@ -566,11 +567,11 @@
         static final int SET_FORCE_HIDING_CHANGED           = 1 << 2;
         static final int SET_ORIENTATION_CHANGE_COMPLETE    = 1 << 3;
         static final int SET_TURN_ON_SCREEN                 = 1 << 4;
+        static final int SET_WALLPAPER_ACTION_PENDING       = 1 << 5;
 
         boolean mWallpaperForceHidingChanged = false;
         boolean mWallpaperMayChange = false;
         boolean mOrientationChangeComplete = true;
-        int mAdjResult = 0;
         private Session mHoldScreen = null;
         private boolean mObscured = false;
         boolean mDimming = false;
@@ -579,6 +580,7 @@
         private float mButtonBrightness = -1;
         private long mUserActivityTimeout = -1;
         private boolean mUpdateRotation = false;
+        boolean mWallpaperActionPending = false;
 
         private static final int DISPLAY_CONTENT_UNKNOWN = 0;
         private static final int DISPLAY_CONTENT_MIRROR = 1;
@@ -603,27 +605,7 @@
         }
     }
 
-    static class LayoutToAnimatorParams {
-        boolean mParamsModified;
-
-        static final long WALLPAPER_TOKENS_CHANGED = 1 << 0;
-        long mChanges;
-
-        boolean mAnimationScheduled;
-        SparseArray<WinAnimatorList> mWinAnimatorLists = new SparseArray<WinAnimatorList>();
-        WindowState mWallpaperTarget;
-        WindowState mLowerWallpaperTarget;
-        WindowState mUpperWallpaperTarget;
-        SparseArray<DimAnimator.Parameters> mDimParams = new SparseArray<DimAnimator.Parameters>();
-        ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
-        ArrayList<AppWindowAnimParams> mAppWindowAnimParams = new ArrayList<AppWindowAnimParams>();
-    }
-    /** Params from WindowManagerService to WindowAnimator. Do not modify or read without first
-     * locking on either mWindowMap or mAnimator and then on mLayoutToAnim */
-    final LayoutToAnimatorParams mLayoutToAnim = new LayoutToAnimatorParams();
-
-    /** The lowest wallpaper target with a detached wallpaper animation on it. */
-    WindowState mWindowDetachedWallpaper = null;
+    boolean mAnimationScheduled;
 
     /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
      * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
@@ -703,9 +685,6 @@
      */
     boolean mInTouchMode = true;
 
-    // Temp regions for intermediary calculations.
-    private final Region mTempRegion = new Region();
-
     private ViewServer mViewServer;
     private ArrayList<WindowChangeListener> mWindowChangeListeners =
         new ArrayList<WindowChangeListener>();
@@ -1562,7 +1541,6 @@
 
     int adjustWallpaperWindowsLocked() {
         mInnerFields.mWallpaperMayChange = false;
-        int changed = 0;
         boolean targetChanged = false;
 
         // TODO(multidisplay): Wallpapers on main screen only.
@@ -1592,7 +1570,7 @@
                 continue;
             }
             topCurW = null;
-            if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
+            if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
                 // If this window's app token is hidden and not animating,
                 // it is of no interest to us.
                 if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
@@ -1601,10 +1579,10 @@
                     continue;
                 }
             }
-            if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": readyfordisplay="
-                    + w.isReadyForDisplay() + " mDrawState=" + w.mWinAnimator.mDrawState);
-            if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
-                    && (mWallpaperTarget == w || w.isDrawnLw())) {
+            if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen="
+                    + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
+            if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isOnScreen()
+                    && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
                 if (DEBUG_WALLPAPER) Slog.v(TAG,
                         "Found wallpaper target: #" + i + "=" + w);
                 foundW = w;
@@ -1618,7 +1596,7 @@
                     continue;
                 }
                 break;
-            } else if (w == mWindowDetachedWallpaper) {
+            } else if (w == mAnimator.mWindowDetachedWallpaper) {
                 windowDetachedI = i;
             }
         }
@@ -1630,27 +1608,6 @@
             foundI = windowDetachedI;
         }
 
-        if (mAppTransition.isTransitionSet()) {
-            // If we are currently waiting for an app transition, and either
-            // the current target or the next target are involved with it,
-            // then hold off on doing anything with the wallpaper.
-            // Note that we are checking here for just whether the target
-            // is part of an app token...  which is potentially overly aggressive
-            // (the app token may not be involved in the transition), but good
-            // enough (we'll just wait until whatever transition is pending
-            // executes).
-            if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
-                if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                        "Wallpaper not changing: waiting for app anim in current target");
-                return 0;
-            }
-            if (foundW != null && foundW.mAppToken != null) {
-                if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                        "Wallpaper not changing: waiting for app anim in found target");
-                return 0;
-            }
-        }
-
         if (mWallpaperTarget != foundW
                 && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) {
             if (DEBUG_WALLPAPER_LIGHT) {
@@ -1668,12 +1625,8 @@
             // Now what is happening...  if the current and new targets are
             // animating, then we are in our super special mode!
             if (foundW != null && oldW != null) {
-                boolean oldAnim = oldW.mWinAnimator.mAnimation != null
-                        || (oldW.mAppToken != null
-                            && oldW.mAppToken.mAppAnimator.animation != null);
-                boolean foundAnim = foundW.mWinAnimator.mAnimation != null
-                        || (foundW.mAppToken != null &&
-                            foundW.mAppToken.mAppAnimator.animation != null);
+                boolean oldAnim = oldW.isAnimatingLw();
+                boolean foundAnim = foundW.isAnimatingLw();
                 if (DEBUG_WALLPAPER_LIGHT) {
                     Slog.v(TAG, "New animation: " + foundAnim
                             + " old animation: " + oldAnim);
@@ -1725,13 +1678,7 @@
 
         } else if (mLowerWallpaperTarget != null) {
             // Is it time to stop animating?
-            boolean lowerAnimating = mLowerWallpaperTarget.mWinAnimator.mAnimation != null
-                    || (mLowerWallpaperTarget.mAppToken != null
-                            && mLowerWallpaperTarget.mAppToken.mAppAnimator.animation != null);
-            boolean upperAnimating = mUpperWallpaperTarget.mWinAnimator.mAnimation != null
-                    || (mUpperWallpaperTarget.mAppToken != null
-                            && mUpperWallpaperTarget.mAppToken.mAppAnimator.animation != null);
-            if (!lowerAnimating || !upperAnimating) {
+            if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) {
                 if (DEBUG_WALLPAPER_LIGHT) {
                     Slog.v(TAG, "No longer animating wallpaper targets!");
                 }
@@ -1807,6 +1754,7 @@
 
         // Start stepping backwards from here, ensuring that our wallpaper windows
         // are correctly placed.
+        int changed = 0;
         int curTokenIndex = mWallpaperTokens.size();
         while (curTokenIndex > 0) {
             curTokenIndex--;
@@ -2251,9 +2199,9 @@
                 addWindowToListInOrderLocked(win, true);
                 if (type == TYPE_WALLPAPER) {
                     mLastWallpaperTimeoutTime = 0;
-                    adjustWallpaperWindowsLocked();
+                    displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
-                    adjustWallpaperWindowsLocked();
+                    displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                 } else if (mWallpaperTarget != null
                         && mWallpaperTarget.mLayer >= win.mBaseLayer) {
                     // If there is currently a wallpaper being shown, and
@@ -2261,7 +2209,7 @@
                     // layer of the target window, then adjust the wallpaper.
                     // This is to avoid a new window being placed between the
                     // wallpaper and its target.
-                    adjustWallpaperWindowsLocked();
+                    displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                 }
             }
 
@@ -2495,9 +2443,11 @@
 
         if (win.mAttrs.type == TYPE_WALLPAPER) {
             mLastWallpaperTimeoutTime = 0;
-            adjustWallpaperWindowsLocked();
+            getDefaultDisplayContentLocked().pendingLayoutChanges |=
+                    WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
         } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
-            adjustWallpaperWindowsLocked();
+            getDefaultDisplayContentLocked().pendingLayoutChanges |=
+                    WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
         }
 
         if (!mInLayout) {
@@ -2817,7 +2767,7 @@
                 }
                 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
                     // To change the format, we need to re-build the surface.
-                    winAnimator.destroySurfaceLocked(false);
+                    winAnimator.destroySurfaceLocked();
                     toBeDisplayed = true;
                     surfaceChanged = true;
                 }
@@ -2898,7 +2848,7 @@
                             if (mInputMethodWindow == win) {
                                 mInputMethodWindow = null;
                             }
-                            winAnimator.destroySurfaceLocked(false);
+                            winAnimator.destroySurfaceLocked();
                         }
                         if (mMagnificationMediator != null) {
                             mMagnificationMediator.onWindowTransitionLw(win, transit);
@@ -2934,16 +2884,12 @@
                 }
             }
             if (wallpaperMayMove) {
-                if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
-                    assignLayers = true;
-                }
+                getDefaultDisplayContentLocked().pendingLayoutChanges |=
+                        WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
             }
 
             win.mDisplayContent.layoutNeeded = true;
             win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
-            if (assignLayers) {
-                assignLayersLocked(win.getWindowList());
-            }
             configChanged = updateOrientationFromAppTokensLocked(false);
             performLayoutAndPlaceSurfacesLocked();
             if (toBeDisplayed && win.mIsWallpaper) {
@@ -2997,12 +2943,12 @@
         long origId = Binder.clearCallingIdentity();
 
         try {
-            synchronized(mWindowMap) {
+            synchronized (mWindowMap) {
                 WindowState win = windowForClientLocked(session, client, false);
                 if (win == null) {
                     return;
                 }
-                win.mWinAnimator.destroyDeferredSurfaceLocked(false);
+                win.mWinAnimator.destroyDeferredSurfaceLocked();
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -3013,7 +2959,7 @@
         long origId = Binder.clearCallingIdentity();
 
         try {
-            synchronized(mWindowMap) {
+            synchronized (mWindowMap) {
                 WindowState win = windowForClientLocked(session, client, false);
                 if (win == null) {
                     return false;
@@ -3027,11 +2973,12 @@
 
     public void finishDrawingWindow(Session session, IWindow client) {
         final long origId = Binder.clearCallingIdentity();
-        synchronized(mWindowMap) {
+        synchronized (mWindowMap) {
             WindowState win = windowForClientLocked(session, client, false);
             if (win != null && win.mWinAnimator.finishDrawingLocked()) {
-                if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
-                    adjustWallpaperWindowsLocked();
+                if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
+                    getDefaultDisplayContentLocked().pendingLayoutChanges |=
+                            WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
                 }
                 win.mDisplayContent.layoutNeeded = true;
                 performLayoutAndPlaceSurfacesLocked();
@@ -3179,7 +3126,6 @@
             mTokenMap.put(token, wtoken);
             if (type == TYPE_WALLPAPER) {
                 mWallpaperTokens.add(wtoken);
-                updateLayoutToAnimWallpaperTokens();
             }
         }
     }
@@ -3231,7 +3177,6 @@
                         mExitingTokens.add(wtoken);
                     } else if (wtoken.windowType == TYPE_WALLPAPER) {
                         mWallpaperTokens.remove(wtoken);
-                        updateLayoutToAnimWallpaperTokens();
                     }
                 }
 
@@ -3700,7 +3645,7 @@
                 Slog.w(TAG, "Execute app transition: " + mAppTransition, e);
             }
             if (mAppTransition.isTransitionSet()) {
-                mAppTransition.setReady(true);
+                mAppTransition.setReady();
                 final long origId = Binder.clearCallingIdentity();
                 performLayoutAndPlaceSurfacesLocked();
                 Binder.restoreCallingIdentity(origId);
@@ -4247,6 +4192,7 @@
         }
     }
 
+    @Override
     public void removeAppToken(IBinder token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "removeAppToken()")) {
@@ -4465,6 +4411,7 @@
         return index;
     }
 
+    @Override
     public void moveAppToken(int index, IBinder token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "moveAppToken()")) {
@@ -5593,7 +5540,7 @@
                         rotation, mFxSession,
                         MAX_ANIMATION_DURATION, mTransitionAnimationScale,
                         displayInfo.logicalWidth, displayInfo.logicalHeight)) {
-                    updateLayoutToAnimationLocked();
+                    scheduleAnimationLocked();
                 }
             }
 
@@ -6641,19 +6588,17 @@
         public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
         public static final int BOOT_TIMEOUT = 23;
         public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
-        public static final int UPDATE_ANIM_PARAMETERS = 25;
-        public static final int SHOW_STRICT_MODE_VIOLATION = 26;
-        public static final int DO_ANIMATION_CALLBACK = 27;
+        public static final int SHOW_STRICT_MODE_VIOLATION = 25;
+        public static final int DO_ANIMATION_CALLBACK = 26;
 
-        public static final int DO_DISPLAY_ADDED = 28;
-        public static final int DO_DISPLAY_REMOVED = 29;
-        public static final int DO_DISPLAY_CHANGED = 30;
+        public static final int DO_DISPLAY_ADDED = 27;
+        public static final int DO_DISPLAY_REMOVED = 28;
+        public static final int DO_DISPLAY_CHANGED = 29;
 
-        public static final int CLIENT_FREEZE_TIMEOUT = 31;
+        public static final int CLIENT_FREEZE_TIMEOUT = 30;
 
         public static final int ANIMATOR_WHAT_OFFSET = 100000;
         public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1;
-        public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 2;
 
         public H() {
         }
@@ -6911,7 +6856,7 @@
                         if (mAppTransition.isTransitionSet()) {
                             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                                     "*** APP TRANSITION TIMEOUT");
-                            mAppTransition.setReady(true);
+                            mAppTransition.setReady();
                             mAppTransition.setTimeout(true);
                             mAnimatingAppTokens.clear();
                             mAnimatingAppTokens.addAll(mAppTokens);
@@ -6933,20 +6878,18 @@
 
                 case FORCE_GC: {
                     synchronized (mWindowMap) {
-                        synchronized (mAnimator) {
-                            // Since we're holding both mWindowMap and mAnimator we don't need to
-                            // hold mAnimator.mLayoutToAnim.
-                            if (mAnimator.mAnimating || mLayoutToAnim.mAnimationScheduled) {
-                                // If we are animating, don't do the gc now but
-                                // delay a bit so we don't interrupt the animation.
-                                sendEmptyMessageDelayed(H.FORCE_GC, 2000);
-                                return;
-                            }
-                            // If we are currently rotating the display, it will
-                            // schedule a new message when done.
-                            if (mDisplayFrozen) {
-                                return;
-                            }
+                        // Since we're holding both mWindowMap and mAnimator we don't need to
+                        // hold mAnimator.mLayoutToAnim.
+                        if (mAnimator.mAnimating || mAnimationScheduled) {
+                            // If we are animating, don't do the gc now but
+                            // delay a bit so we don't interrupt the animation.
+                            sendEmptyMessageDelayed(H.FORCE_GC, 2000);
+                            return;
+                        }
+                        // If we are currently rotating the display, it will
+                        // schedule a new message when done.
+                        if (mDisplayFrozen) {
+                            return;
                         }
                     }
                     Runtime.getRuntime().gc();
@@ -6960,16 +6903,14 @@
 
                 case APP_FREEZE_TIMEOUT: {
                     synchronized (mWindowMap) {
-                        synchronized (mAnimator) {
-                            Slog.w(TAG, "App freeze timeout expired.");
-                            int i = mAppTokens.size();
-                            while (i > 0) {
-                                i--;
-                                AppWindowToken tok = mAppTokens.get(i);
-                                if (tok.mAppAnimator.freezingScreen) {
-                                    Slog.w(TAG, "Force clearing freeze: " + tok);
-                                    unsetAppFreezingScreenLocked(tok, true, true);
-                                }
+                        Slog.w(TAG, "App freeze timeout expired.");
+                        int i = mAppTokens.size();
+                        while (i > 0) {
+                            i--;
+                            AppWindowToken tok = mAppTokens.get(i);
+                            if (tok.mAppAnimator.freezingScreen) {
+                                Slog.w(TAG, "Force clearing freeze: " + tok);
+                                unsetAppFreezingScreenLocked(tok, true, true);
                             }
                         }
                     }
@@ -7060,17 +7001,6 @@
                     break;
                 }
 
-                case UPDATE_ANIM_PARAMETERS: {
-                    // Used to send multiple changes from the animation side to the layout side.
-                    synchronized (mWindowMap) {
-                        if (copyAnimToLayoutParamsLocked()) {
-                            sendEmptyMessage(CLEAR_PENDING_ACTIONS);
-                            performLayoutAndPlaceSurfacesLocked();
-                        }
-                    }
-                    break;
-                }
-
                 case SHOW_STRICT_MODE_VIOLATION: {
                     showStrictModeViolation(msg.arg1, msg.arg2);
                     break;
@@ -7085,11 +7015,6 @@
                     break;
                 }
 
-                case CLEAR_PENDING_ACTIONS: {
-                    mAnimator.clearPendingActions();
-                    break;
-                }
-
                 case DO_ANIMATION_CALLBACK: {
                     try {
                         ((IRemoteCallback)msg.obj).sendResult(null);
@@ -7468,7 +7393,7 @@
                     pw.flush();
                     Slog.w(TAG, "This window was lost: " + ws);
                     Slog.w(TAG, sw.toString());
-                    ws.mWinAnimator.destroySurfaceLocked(false);
+                    ws.mWinAnimator.destroySurfaceLocked();
                 }
             }
             Slog.w(TAG, "Current app token list:");
@@ -7530,7 +7455,7 @@
             }
             if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) {
                 // Force an animation pass just to update the mDimAnimator layer.
-                updateLayoutToAnimationLocked();
+                scheduleAnimationLocked();
             }
             if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
                     + "mBase=" + w.mBaseLayer
@@ -7556,6 +7481,7 @@
             mH.removeMessages(H.DO_TRAVERSAL);
             loopCount--;
         } while (mTraversalScheduled && loopCount > 0);
+        mInnerFields.mWallpaperActionPending = false;
     }
 
     private boolean mInLayout = false;
@@ -7688,7 +7614,7 @@
             // soon won't be visible, to avoid wasting time and funky
             // changes while a window is animating away.
             final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs))
-                    || (win.isGoneForLayoutLw() && !win.isOnScreen());
+                    || win.isGoneForLayoutLw();
 
             if (DEBUG_LAYOUT && !win.mLayoutAttached) {
                 Slog.v(TAG, "1ST PASS " + win
@@ -7878,7 +7804,6 @@
                         && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
                     ? null : mWallpaperTarget;
 
-            adjustWallpaperWindowsLocked();
             mInnerFields.mWallpaperMayChange = false;
 
             // The top-most window will supply the layout params,
@@ -7892,7 +7817,18 @@
                     + ", oldWallpaper=" + oldWallpaper
                     + ", lower target=" + mLowerWallpaperTarget
                     + ", upper target=" + mUpperWallpaperTarget);
-            int foundWallpapers = 0;
+
+            boolean openingAppHasWallpaper = false;
+            boolean closingAppHasWallpaper = false;
+            final AppWindowToken lowerWallpaperAppToken;
+            final AppWindowToken upperWallpaperAppToken;
+            if (mLowerWallpaperTarget == null) {
+                lowerWallpaperAppToken = upperWallpaperAppToken = null;
+            } else {
+                lowerWallpaperAppToken = mLowerWallpaperTarget.mAppToken;
+                upperWallpaperAppToken = mUpperWallpaperTarget.mAppToken;
+            }
+
             // Do a first pass through the tokens for two
             // things:
             // (1) Determine if both the closing and opening
@@ -7906,21 +7842,19 @@
             final int NC = mClosingApps.size();
             NN = NC + mOpeningApps.size();
             for (i=0; i<NN; i++) {
-                AppWindowToken wtoken;
-                int mode;
+                final AppWindowToken wtoken;
                 if (i < NC) {
                     wtoken = mClosingApps.get(i);
-                    mode = 1;
+                    if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
+                        closingAppHasWallpaper = true;
+                    }
                 } else {
-                    wtoken = mOpeningApps.get(i-NC);
-                    mode = 2;
-                }
-                if (mLowerWallpaperTarget != null) {
-                    if (mLowerWallpaperTarget.mAppToken == wtoken
-                            || mUpperWallpaperTarget.mAppToken == wtoken) {
-                        foundWallpapers |= mode;
+                    wtoken = mOpeningApps.get(i - NC);
+                    if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
+                        openingAppHasWallpaper = true;
                     }
                 }
+
                 if (wtoken.appFullscreen) {
                     WindowState ws = wtoken.findMainWindow();
                     if (ws != null) {
@@ -7939,9 +7873,8 @@
                 }
             }
 
-            if (foundWallpapers == 3) {
-                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
-                        "Wallpaper animation!");
+            if (closingAppHasWallpaper && openingAppHasWallpaper) {
+                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
                 switch (transit) {
                     case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
                     case WindowManagerPolicy.TRANSIT_TASK_OPEN:
@@ -7954,8 +7887,7 @@
                         transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
                         break;
                 }
-                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
-                        "New transit: " + transit);
+                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit: " + transit);
             } else if ((oldWallpaper != null) && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
                 // We are transitioning from an activity with
                 // a wallpaper to one without.
@@ -8119,7 +8051,8 @@
         rebuildAppWindowListLocked();
 
         changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
-        mInnerFields.mAdjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
+        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                "Wallpaper layer changed: assigning layers + relayout");
         moveInputMethodWindowsIfNeededLocked(true);
         mInnerFields.mWallpaperMayChange = true;
         // Since the window list has been rebuilt, focus might
@@ -8130,37 +8063,6 @@
         return changes;
     }
 
-    /**
-     * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
-     *
-     * @return bitmap indicating if another pass through layout must be made.
-     */
-    private int animateAwayWallpaperLocked() {
-        int changes = 0;
-        WindowState oldWallpaper = mWallpaperTarget;
-        if (mLowerWallpaperTarget != null
-                && mLowerWallpaperTarget.mAppToken != null) {
-            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                    "wallpaperForceHiding changed with lower="
-                    + mLowerWallpaperTarget);
-            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                    "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
-                    " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
-            if (mLowerWallpaperTarget.mAppToken.hidden) {
-                // The lower target has become hidden before we
-                // actually started the animation...  let's completely
-                // re-evaluate everything.
-                mLowerWallpaperTarget = mUpperWallpaperTarget = null;
-                changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
-            }
-        }
-        mInnerFields.mAdjResult |= adjustWallpaperWindowsLocked();
-        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "****** OLD: " + oldWallpaper
-                + " NEW: " + mWallpaperTarget
-                + " LOWER: " + mLowerWallpaperTarget);
-        return changes;
-    }
-
     private void updateResizingWindows(final WindowState w) {
         final WindowStateAnimator winAnimator = w.mWinAnimator;
         if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
@@ -8184,7 +8086,9 @@
                 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
                     Slog.v(TAG, "Resize reasons: "
                             + " contentInsetsChanged=" + w.mContentInsetsChanged
+                            + " " + w.mContentInsets.toShortString()
                             + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
+                            + " " + w.mVisibleInsets.toShortString()
                             + " surfaceResized=" + winAnimator.mSurfaceResized
                             + " configChanged=" + configChanged);
                 }
@@ -8411,10 +8315,7 @@
                     if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
                         displayContent.pendingLayoutChanges);
 
-                    if (isDefaultDisplay && ((displayContent.pendingLayoutChanges
-                            & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0)
-                            && ((adjustWallpaperWindowsLocked()
-                                    & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0)) {
+                    if ((adjustWallpaperWindowsLocked() & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
                         assignLayersLocked(windows);
                         displayContent.layoutNeeded = true;
                     }
@@ -8657,11 +8558,9 @@
         if (mAppTransition.isReady()) {
             defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
             if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
-                defaultDisplay.pendingLayoutChanges);
+                    defaultDisplay.pendingLayoutChanges);
         }
 
-        mInnerFields.mAdjResult = 0;
-
         if (!mAnimator.mAnimating && mAppTransition.isRunning()) {
             // We have finished the animation of an app transition.  To do
             // this, we have delayed a lot of operations like showing and
@@ -8682,7 +8581,7 @@
             // away the wallpaper and its window -- or it may be
             // hard -- the wallpaper now needs to be shown behind
             // something that was hidden.
-            defaultDisplay.pendingLayoutChanges |= animateAwayWallpaperLocked();
+            defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
             if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
                 defaultDisplay.pendingLayoutChanges);
         }
@@ -8691,18 +8590,10 @@
         if (mInnerFields.mWallpaperMayChange) {
             if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
                     "Wallpaper may change!  Adjusting");
-            mInnerFields.mAdjResult |= adjustWallpaperWindowsLocked();
-        }
-
-        if ((mInnerFields.mAdjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
-            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                    "Wallpaper layer changed: assigning layers + relayout");
-            defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
-            assignLayersLocked(defaultWindows);
-        } else if ((mInnerFields.mAdjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
-            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                    "Wallpaper visibility changed: relayout");
-            defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
+            defaultDisplay.pendingLayoutChanges |=
+                    WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
+                    defaultDisplay.pendingLayoutChanges);
         }
 
         if (mFocusMayChange) {
@@ -8710,7 +8601,6 @@
             if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
                     false /*updateInputWindows*/)) {
                 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
-                mInnerFields.mAdjResult = 0;
             }
         }
 
@@ -8780,7 +8670,7 @@
                 if (win == mWallpaperTarget) {
                     wallpaperDestroyed = true;
                 }
-                win.mWinAnimator.destroySurfaceLocked(false);
+                win.mWinAnimator.destroySurfaceLocked();
             } while (i > 0);
             mDestroySurface.clear();
         }
@@ -8792,7 +8682,6 @@
                 mExitingTokens.remove(i);
                 if (token.windowType == TYPE_WALLPAPER) {
                     mWallpaperTokens.remove(token);
-                    updateLayoutToAnimWallpaperTokens();
                 }
             }
         }
@@ -8824,8 +8713,10 @@
             mRelayoutWhileAnimating.clear();
         }
 
-        if (wallpaperDestroyed && (adjustWallpaperWindowsLocked() != 0)) {
-            getDefaultDisplayContentLocked().layoutNeeded = true;
+        if (wallpaperDestroyed) {
+            defaultDisplay.pendingLayoutChanges |=
+                    WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+            defaultDisplay.layoutNeeded = true;
         }
 
         DisplayContentsIterator iterator = new DisplayContentsIterator();
@@ -8903,7 +8794,7 @@
         // be enabled, because the window obscured flags have changed.
         enableScreenIfNeededLocked();
 
-        updateLayoutToAnimationLocked();
+        scheduleAnimationLocked();
 
         if (DEBUG_WINDOW_TRACE) {
             Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating="
@@ -9000,82 +8891,21 @@
 
     /** Note that Locked in this case is on mLayoutToAnim */
     void scheduleAnimationLocked() {
-        final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
-        if (!layoutToAnim.mAnimationScheduled) {
-            layoutToAnim.mAnimationScheduled = true;
+        if (!mAnimationScheduled) {
+            mAnimationScheduled = true;
             mChoreographer.postCallback(
                     Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null);
         }
     }
 
-    void updateLayoutToAnimationLocked() {
-        final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
-        synchronized (layoutToAnim) {
-            // Copy local params to transfer params.
-            SparseArray<WinAnimatorList> allWinAnimatorLists = layoutToAnim.mWinAnimatorLists;
-            allWinAnimatorLists.clear();
-            DisplayContentsIterator iterator = new DisplayContentsIterator();
-            while (iterator.hasNext()) {
-                final DisplayContent displayContent = iterator.next();
-                WinAnimatorList winAnimatorList = new WinAnimatorList();
-                final WindowList windows = displayContent.getWindowList();
-                int N = windows.size();
-                for (int i = 0; i < N; i++) {
-                    final WindowStateAnimator winAnimator = windows.get(i).mWinAnimator;
-                    if (winAnimator.mSurface != null) {
-                        winAnimatorList.add(winAnimator);
-                    }
-                }
-                allWinAnimatorLists.put(displayContent.getDisplayId(), winAnimatorList);
-            }
-
-            if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) {
-                if (mWallpaperTarget != layoutToAnim.mWallpaperTarget
-                        || mLowerWallpaperTarget != layoutToAnim.mLowerWallpaperTarget
-                        || mUpperWallpaperTarget != layoutToAnim.mUpperWallpaperTarget) {
-                    Slog.d(TAG, "Pushing anim wallpaper: target=" + mWallpaperTarget
-                            + " lower=" + mLowerWallpaperTarget + " upper="
-                            + mUpperWallpaperTarget + "\n" + Debug.getCallers(5, "  "));
-                }
-            }
-            layoutToAnim.mWallpaperTarget = mWallpaperTarget;
-            layoutToAnim.mLowerWallpaperTarget = mLowerWallpaperTarget;
-            layoutToAnim.mUpperWallpaperTarget = mUpperWallpaperTarget;
-
-            final ArrayList<AppWindowAnimParams> paramList = layoutToAnim.mAppWindowAnimParams;
-            paramList.clear();
-            int N = mAnimatingAppTokens.size();
-            for (int i = 0; i < N; i++) {
-                paramList.add(new AppWindowAnimParams(mAnimatingAppTokens.get(i).mAppAnimator));
-            }
-
-            layoutToAnim.mParamsModified = true;
-            scheduleAnimationLocked();
-        }
-    }
-
-    void updateLayoutToAnimWallpaperTokens() {
-        synchronized(mLayoutToAnim) {
-            mLayoutToAnim.mWallpaperTokens = new ArrayList<WindowToken>(mWallpaperTokens);
-            mLayoutToAnim.mChanges |= LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED;
-        }
-    }
-
-    void setAnimDimParams(int displayId, DimAnimator.Parameters params) {
-        synchronized (mLayoutToAnim) {
-            mLayoutToAnim.mDimParams.put(displayId, params);
-            scheduleAnimationLocked();
-        }
-    }
-
     void startDimmingLocked(final WindowStateAnimator winAnimator, final float target,
                       final int width, final int height) {
-        setAnimDimParams(winAnimator.mWin.getDisplayId(),
+        mAnimator.setDimParamsLocked(winAnimator.mWin.getDisplayId(),
                 new DimAnimator.Parameters(winAnimator, width, height, target));
     }
 
     void stopDimmingLocked(int displayId) {
-        setAnimDimParams(displayId, null);
+        mAnimator.setDimParamsLocked(displayId, null);
     }
 
     private boolean needsLayout() {
@@ -9088,53 +8918,39 @@
         return false;
     }
 
-    private boolean copyAnimToLayoutParamsLocked() {
+    boolean copyAnimToLayoutParamsLocked() {
         boolean doRequest = false;
-        final WindowAnimator.AnimatorToLayoutParams animToLayout = mAnimator.mAnimToLayout;
-        synchronized (animToLayout) {
-            animToLayout.mUpdateQueued = false;
-            final int bulkUpdateParams = animToLayout.mBulkUpdateParams;
-            // TODO(cmautner): As the number of bits grows, use masks of bit groups to
-            //  eliminate unnecessary tests.
-            if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
-                mInnerFields.mUpdateRotation = true;
-                doRequest = true;
-            }
-            if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
-                mInnerFields.mWallpaperMayChange = true;
-                doRequest = true;
-            }
-            if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
-                mInnerFields.mWallpaperForceHidingChanged = true;
-                doRequest = true;
-            }
-            if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
-                mInnerFields.mOrientationChangeComplete = false;
-            } else {
-                mInnerFields.mOrientationChangeComplete = true;
-                if (mWindowsFreezingScreen) {
-                    doRequest = true;
-                }
-            }
-            if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
-                mTurnOnScreen = true;
-            }
 
-            SparseIntArray pendingLayouts = animToLayout.mPendingLayoutChanges;
-            final int count = pendingLayouts.size();
-            if (count > 0) {
-                doRequest = true;
-            }
-            for (int i = 0; i < count; ++i) {
-                final DisplayContent displayContent =
-                        getDisplayContentLocked(pendingLayouts.keyAt(i));
-                if (displayContent != null) {
-                    displayContent.pendingLayoutChanges |= pendingLayouts.valueAt(i);
-                }
-            }
-
-            mWindowDetachedWallpaper = animToLayout.mWindowDetachedWallpaper;
+        final int bulkUpdateParams = mAnimator.mBulkUpdateParams;
+        // TODO(cmautner): As the number of bits grows, use masks of bit groups to
+        //  eliminate unnecessary tests.
+        if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
+            mInnerFields.mUpdateRotation = true;
+            doRequest = true;
         }
+        if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
+            mInnerFields.mWallpaperMayChange = true;
+            doRequest = true;
+        }
+        if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
+            mInnerFields.mWallpaperForceHidingChanged = true;
+            doRequest = true;
+        }
+        if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
+            mInnerFields.mOrientationChangeComplete = false;
+        } else {
+            mInnerFields.mOrientationChangeComplete = true;
+            if (mWindowsFreezingScreen) {
+                doRequest = true;
+            }
+        }
+        if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
+            mTurnOnScreen = true;
+        }
+        if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_ACTION_PENDING) != 0) {
+            mInnerFields.mWallpaperActionPending = true;
+        }
+
         return doRequest;
     }
 
@@ -9298,7 +9114,7 @@
         }
         return false;
     }
-    
+
     private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
         mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
     }
@@ -9408,7 +9224,7 @@
         if (mAppTransition.isTransitionSet()) {
             mAppTransition.setAppTransition(WindowManagerPolicy.TRANSIT_UNSET);
             mAppTransition.clear();
-            mAppTransition.setReady(true);
+            mAppTransition.setReady();
         }
 
         if (PROFILE_ORIENTATION) {
@@ -9450,7 +9266,7 @@
                 + ", mClientFreezingScreen=" + mClientFreezingScreen);
             return;
         }
-        
+
         mDisplayFrozen = false;
         mH.removeMessages(H.APP_FREEZE_TIMEOUT);
         mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
@@ -9472,7 +9288,7 @@
             if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
                     mTransitionAnimationScale, displayInfo.logicalWidth,
                         displayInfo.logicalHeight)) {
-                updateLayoutToAnimationLocked();
+                scheduleAnimationLocked();
             } else {
                 screenRotationAnimation.kill();
                 screenRotationAnimation = null;
@@ -9668,14 +9484,17 @@
         return mPolicy.hasNavigationBar();
     }
 
+    @Override
     public void lockNow(Bundle options) {
         mPolicy.lockNow(options);
     }
     
+    @Override
     public boolean isSafeModeEnabled() {
         return mSafeMode;
     }
 
+    @Override
     public void showAssistant() {
         // TODO: What permission?
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
@@ -10015,31 +9834,6 @@
             pw.print("  mStartingIconInTransition="); pw.print(mStartingIconInTransition);
                     pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
             pw.println("  mLayoutToAnim:");
-            pw.print("    mParamsModified="); pw.print(mLayoutToAnim.mParamsModified);
-                    pw.print(" mAnimationScheduled="); pw.print(mLayoutToAnim.mAnimationScheduled);
-                    pw.print(" mChanges=0x");
-                    pw.println(Long.toHexString(mLayoutToAnim.mChanges));
-            pw.print("    mWallpaperTarget="); pw.println(mLayoutToAnim.mWallpaperTarget);
-            if (mLayoutToAnim.mLowerWallpaperTarget != null
-                    || mLayoutToAnim.mUpperWallpaperTarget != null) {
-                pw.print("    mLowerWallpaperTarget=");
-                        pw.println(mLayoutToAnim.mLowerWallpaperTarget);
-                pw.print("    mUpperWallpaperTarget=");
-                        pw.println(mLayoutToAnim.mUpperWallpaperTarget);
-            }
-            for (int i=0; i<mLayoutToAnim.mWinAnimatorLists.size(); i++) {
-                pw.print("    Win Animator List #");
-                        pw.print(mLayoutToAnim.mWinAnimatorLists.keyAt(i)); pw.println(":");
-                WinAnimatorList wanim = mLayoutToAnim.mWinAnimatorLists.valueAt(i);
-                for (int wi=0; wi<wanim.size(); wi++) {
-                    pw.print("      "); pw.println(wanim.get(wi));
-                }
-            }
-            for (int i=0; i<mLayoutToAnim.mWallpaperTokens.size(); i++) {
-                pw.print("    Wallpaper Token #"); pw.print(i); pw.print(": ");
-                        pw.println(mLayoutToAnim.mWallpaperTokens.get(i));
-            }
-            // XXX also need to print mDimParams and mAppWindowAnimParams.  I am lazy.
             mAppTransition.dump(pw);
         }
     }
@@ -10250,6 +10044,7 @@
     }
 
     // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
+    @Override
     public void monitor() {
         synchronized (mWindowMap) { }
     }
@@ -10391,7 +10186,16 @@
      * @return The list of WindowStates on the screen, or null if the there is no screen.
      */
     public WindowList getWindowListLocked(final Display display) {
-        final DisplayContent displayContent = getDisplayContentLocked(display.getDisplayId());
+        return getWindowListLocked(display.getDisplayId());
+    }
+
+    /**
+     * Return the list of WindowStates associated on the passed display.
+     * @param displayId The screen to return windows from.
+     * @return The list of WindowStates on the screen, or null if the there is no screen.
+     */
+    public WindowList getWindowListLocked(final int displayId) {
+        final DisplayContent displayContent = getDisplayContentLocked(displayId);
         return displayContent != null ? displayContent.getWindowList() : null;
     }
 
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 541e859..e0dad01b 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -730,7 +730,7 @@
         final AppWindowToken atoken = mAppToken;
         if (atoken != null) {
             return ((!mAttachedHidden && !atoken.hiddenRequested)
-                            || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null);
+                    || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null);
         }
         return !mAttachedHidden || mWinAnimator.mAnimation != null;
     }
@@ -788,12 +788,12 @@
     }
 
     /**
-     * Return true if this window (or a window it is attached to, but not
-     * considering its app token) is currently animating.
+     * Return true if this window or its app token is currently animating.
      */
     @Override
     public boolean isAnimatingLw() {
-        return mWinAnimator.mAnimation != null;
+        return mWinAnimator.mAnimation != null
+                || (mAppToken != null && mAppToken.mAppAnimator.animation != null);
     }
 
     @Override
@@ -811,6 +811,17 @@
      * Returns true if the window has a surface that it has drawn a
      * complete UI in to.
      */
+    public boolean isDrawFinishedLw() {
+        return mHasSurface && !mDestroying &&
+                (mWinAnimator.mDrawState == WindowStateAnimator.COMMIT_DRAW_PENDING
+                || mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW
+                || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN);
+    }
+
+    /**
+     * Returns true if the window has a surface that it has drawn a
+     * complete UI in to.
+     */
     public boolean isDrawnLw() {
         return mHasSurface && !mDestroying &&
                 (mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW
@@ -872,8 +883,8 @@
             if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow);
             mAttachedWindow.mChildWindows.remove(this);
         }
-        mWinAnimator.destroyDeferredSurfaceLocked(false);
-        mWinAnimator.destroySurfaceLocked(false);
+        mWinAnimator.destroyDeferredSurfaceLocked();
+        mWinAnimator.destroySurfaceLocked();
         mSession.windowRemovedLocked();
         try {
             mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
@@ -974,7 +985,7 @@
             mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true);
         }
         if (requestAnim) {
-            mService.updateLayoutToAnimationLocked();
+            mService.scheduleAnimationLocked();
         }
         return true;
     }
@@ -1017,7 +1028,7 @@
             }
         }
         if (requestAnim) {
-            mService.updateLayoutToAnimationLocked();
+            mService.scheduleAnimationLocked();
         }
         return true;
     }
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 3c9424a..e03e40d 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -226,7 +226,7 @@
             mAnimation.cancel();
             mAnimation = null;
             mLocalAnimating = false;
-            destroySurfaceLocked(true);
+            destroySurfaceLocked();
         }
     }
 
@@ -369,7 +369,7 @@
         final int displayId = mWin.mDisplayContent.getDisplayId();
         mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
         if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats(
-                "WindowStateAnimator", mAnimator.mPendingLayoutChanges.get(displayId));
+                "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
 
         if (mWin.mAppToken != null) {
             mWin.mAppToken.updateReportedVisibilityLocked();
@@ -413,7 +413,7 @@
             mService.mPendingRemove.add(mWin);
             mWin.mRemoveOnExit = false;
         }
-        mAnimator.hideWallpapersLocked(mWin, true);
+        mAnimator.hideWallpapersLocked(mWin);
     }
 
     void hide() {
@@ -752,7 +752,7 @@
         return mSurface;
     }
 
-    void destroySurfaceLocked(boolean fromAnimator) {
+    void destroySurfaceLocked() {
         if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) {
             mWin.mAppToken.startingDisplayed = false;
         }
@@ -802,7 +802,7 @@
                     }
                     mSurface.destroy();
                 }
-                mAnimator.hideWallpapersLocked(mWin, fromAnimator);
+                mAnimator.hideWallpapersLocked(mWin);
             } catch (RuntimeException e) {
                 Slog.w(TAG, "Exception thrown when destroying Window " + this
                     + " surface " + mSurface + " session " + mSession
@@ -816,7 +816,7 @@
         }
     }
 
-    void destroyDeferredSurfaceLocked(boolean fromAnimator) {
+    void destroyDeferredSurfaceLocked() {
         try {
             if (mPendingDestroySurface != null) {
                 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
@@ -828,7 +828,7 @@
                     WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
                 }
                 mPendingDestroySurface.destroy();
-                mAnimator.hideWallpapersLocked(mWin, fromAnimator);
+                mAnimator.hideWallpapersLocked(mWin);
             }
         } catch (RuntimeException e) {
             Slog.w(TAG, "Exception thrown when destroying Window "
@@ -849,9 +849,9 @@
 
         // Wallpapers are animated based on the "real" window they
         // are currently targeting.
-        if (mIsWallpaper && mAnimator.mLowerWallpaperTarget == null
-                && mAnimator.mWallpaperTarget != null) {
-            final WindowStateAnimator wallpaperAnimator = mAnimator.mWallpaperTarget.mWinAnimator;
+        if (mIsWallpaper && mService.mLowerWallpaperTarget == null
+                && mService.mWallpaperTarget != null) {
+            final WindowStateAnimator wallpaperAnimator = mService.mWallpaperTarget.mWinAnimator;
             if (wallpaperAnimator.mHasLocalTransformation &&
                     wallpaperAnimator.mAnimation != null &&
                     !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
@@ -860,7 +860,7 @@
                     Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
                 }
             }
-            final AppWindowAnimator wpAppAnimator = mAnimator.mWpAppAnimator;
+            final AppWindowAnimator wpAppAnimator = mAnimator.getWallpaperAppAnimator();
             if (wpAppAnimator != null && wpAppAnimator.hasTransformation
                     && wpAppAnimator.animation != null
                     && !wpAppAnimator.animation.getDetachWallpaper()) {
@@ -986,8 +986,7 @@
                     + " screen=" + (screenAnimation ?
                             screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
             return;
-        } else if (mIsWallpaper &&
-                    (mAnimator.mPendingActions & WindowAnimator.WALLPAPER_ACTION_PENDING) != 0) {
+        } else if (mIsWallpaper && mService.mInnerFields.mWallpaperActionPending) {
             return;
         }
 
@@ -1220,7 +1219,7 @@
             hide();
         } else if (w.mAttachedHidden || !w.isReadyForDisplay()) {
             hide();
-            mAnimator.hideWallpapersLocked(w, true);
+            mAnimator.hideWallpapersLocked(w);
 
             // If we are waiting for this window to handle an
             // orientation change, well, it is hidden, so
@@ -1414,7 +1413,7 @@
             if (DEBUG_SURFACE_TRACE || DEBUG_ANIM)
                 Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN in " + this);
             mDrawState = HAS_DRAWN;
-            mService.updateLayoutToAnimationLocked();
+            mService.scheduleAnimationLocked();
 
             int i = mWin.mChildWindows.size();
             while (i > 0) {
diff --git a/core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
similarity index 98%
rename from core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java
rename to services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 84c9957..00c3a67 100644
--- a/core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -14,8 +14,10 @@
  * limitations under the License.
  */
 
-package android.accounts;
+package com.android.server.accounts;
 
+import android.accounts.Account;
+import android.accounts.AuthenticatorDescription;
 import android.app.Notification;
 import android.content.Context;
 import android.content.pm.PackageManager;
diff --git a/core/tests/coretests/src/android/content/ObserverNodeTest.java b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
similarity index 94%
rename from core/tests/coretests/src/android/content/ObserverNodeTest.java
rename to services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
index 1acff9c..5b70c17 100644
--- a/core/tests/coretests/src/android/content/ObserverNodeTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
@@ -14,18 +14,19 @@
  * limitations under the License.
  */
 
-package android.content;
+package com.android.server.content;
 
 import java.util.ArrayList;
 
-import android.content.ContentService.ObserverCall;
-import android.content.ContentService.ObserverNode;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.UserHandle;
 import android.test.AndroidTestCase;
 
+import com.android.server.content.ContentService.ObserverCall;
+import com.android.server.content.ContentService.ObserverNode;
+
 public class ObserverNodeTest extends AndroidTestCase {
     static class TestObserver  extends ContentObserver {
         public TestObserver() {
diff --git a/core/tests/coretests/src/android/content/SyncOperationTest.java b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
similarity index 97%
rename from core/tests/coretests/src/android/content/SyncOperationTest.java
rename to services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
index 1fd25d2..f2772c8 100644
--- a/core/tests/coretests/src/android/content/SyncOperationTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
@@ -14,13 +14,15 @@
  * limitations under the License.
  */
 
-package android.content;
+package com.android.server;
 
 import android.accounts.Account;
 import android.os.Bundle;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.server.content.SyncOperation;
+
 /**
  * You can run those tests with:
  *
diff --git a/core/tests/coretests/src/android/content/SyncStorageEngineTest.java b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
similarity index 98%
rename from core/tests/coretests/src/android/content/SyncStorageEngineTest.java
rename to services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
index 58d2327..8b00f2c2 100644
--- a/core/tests/coretests/src/android/content/SyncStorageEngineTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
@@ -14,9 +14,14 @@
  * limitations under the License.
  */
 
-package android.content;
+package com.android.server.content;
 
 import android.accounts.Account;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.PeriodicSync;
 import android.os.Bundle;
 import android.test.AndroidTestCase;
 import android.test.RenamingDelegatingContext;
diff --git a/core/tests/coretests/src/android/app/SearchablesTest.java b/services/tests/servicestests/src/com/android/server/search/SearchablesTest.java
similarity index 99%
rename from core/tests/coretests/src/android/app/SearchablesTest.java
rename to services/tests/servicestests/src/com/android/server/search/SearchablesTest.java
index 4d3b144..79b9135 100644
--- a/core/tests/coretests/src/android/app/SearchablesTest.java
+++ b/services/tests/servicestests/src/com/android/server/search/SearchablesTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.app;
+package com.android.server.search;
 
 import android.app.SearchManager;
 import android.app.SearchableInfo;
@@ -30,7 +30,7 @@
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.os.RemoteException;
-import android.server.search.Searchables;
+import com.android.server.search.Searchables;
 import android.test.AndroidTestCase;
 import android.test.MoreAsserts;
 import android.test.mock.MockContext;
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 10ac153..80c985f 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -23,7 +23,6 @@
 public class DctConstants {
     /**
      * IDLE: ready to start data connection setup, default state
-     * INITING: state of issued setupDefaultPDP() but not finish yet
      * CONNECTING: state of issued startPppd() but not finish yet
      * SCANNING: data connection fails with one apn but other apns are available
      *           ready to start data connection on other apns (before INITING)
@@ -34,12 +33,11 @@
      *
      * getDataConnectionState() maps State to DataState
      *      FAILED or IDLE : DISCONNECTED
-     *      INITING or CONNECTING or SCANNING: CONNECTING
+     *      CONNECTING or SCANNING: CONNECTING
      *      CONNECTED : CONNECTED or DISCONNECTING
      */
     public enum State {
         IDLE,
-        INITING,
         CONNECTING,
         SCANNING,
         CONNECTED,
@@ -113,4 +111,3 @@
         "com.android.internal.telephony";
     public static String EXTRA_MESSENGER = "EXTRA_MESSENGER";
 }
-
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Contrast.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Contrast.java
index 80e0f1a..f3cf1b7 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Contrast.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Contrast.java
@@ -28,7 +28,7 @@
     }
 
     public void runTest() {
-        mScript.set_bright(50.f);
+        mScript.invoke_setBright(50.f);
         mScript.forEach_contrast(mInPixelsAllocation, mOutPixelsAllocation);
     }
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Exposure.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Exposure.java
index 6aad4be..bec53ab 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Exposure.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Exposure.java
@@ -28,7 +28,7 @@
     }
 
     public void runTest() {
-        mScript.set_bright(50.f);
+        mScript.invoke_setBright(50.f);
         mScript.forEach_exposure(mInPixelsAllocation, mOutPixelsAllocation);
     }
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/bwfilter.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/bwfilter.rs
index 80a626a..2818bf5 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/bwfilter.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/bwfilter.rs
@@ -48,6 +48,6 @@
     localMin = fmin(r,localMin);
     localMax = fmax(g,b);
     localMax = fmax(r,localMax);
-    avg =(localMin+localMax)/2;
+    avg = (localMin+localMax) * 0.5f;
     out->r = out->g = out->b = rsClamp(avg, 0, 255);
 }
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/contrast.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/contrast.rs
index 987315e..5fd7be1 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/contrast.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/contrast.rs
@@ -16,27 +16,24 @@
 
 #pragma version(1)
 #pragma rs java_package_name(com.android.rs.image)
-#pragma rs_fp_relaxed
+#pragma rs_fp_full
 
-float bright = 0.f;
+static float brightM = 0.f;
+static float brightC = 0.f;
 
-static unsigned char contrastClamp(int c)
-{
-    int N = 255;
-    c &= ~(c >> 31);
-    c -= N;
-    c &= (c >> 31);
-    c += N;
-    return  (unsigned char) c;
+void setBright(float v) {
+    brightM = pow(2.f, v / 100.f);
+    brightC = 127.f - brightM * 127.f;
 }
 
 void contrast(const uchar4 *in, uchar4 *out)
 {
-    float m =  (float)pow(2, bright/100.f);
-    float c =  127-m*127;
-
-    out->r = contrastClamp((int)(m*in->r+c));
-    out->g = contrastClamp((int)(m*in->g+c));
-    out->b = contrastClamp((int)(m*in->b+c));
-
+#if 0
+    out->r = rsClamp((int)(brightM * in->r + brightC), 0, 255);
+    out->g = rsClamp((int)(brightM * in->g + brightC), 0, 255);
+    out->b = rsClamp((int)(brightM * in->b + brightC), 0, 255);
+#else
+    float3 v = convert_float3(in->rgb) * brightM + brightC;
+    out->rgb = convert_uchar3(clamp(v, 0.f, 255.f));
+#endif
 }
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/exposure.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/exposure.rs
index d15fd87..adfae4a 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/exposure.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/exposure.rs
@@ -16,24 +16,18 @@
 
 #pragma version(1)
 #pragma rs java_package_name(com.android.rs.image)
-#pragma rs_fp_relaxed
+#pragma rs_fp_full
 
-float bright = 0.f;
+static float bright = 0.f;
 
-static unsigned char contrastClamp(int c)
-{
-    int N = 255;
-    c &= ~(c >> 31);
-    c -= N;
-    c &= (c >> 31);
-    c += N;
-    return  (unsigned char) c;
+void setBright(float v) {
+    bright = 255.f / (255.f - v);
 }
 
 void exposure(const uchar4 *in, uchar4 *out)
 {
-    int m = 255 - bright;
-    out->r = contrastClamp((255 * in->r)/m);
-    out->g = contrastClamp((255 * in->g)/m);
-    out->b = contrastClamp((255 * in->b)/m);
+    out->r = rsClamp((int)(bright * in->r), 0, 255);
+    out->g = rsClamp((int)(bright * in->g), 0, 255);
+    out->b = rsClamp((int)(bright * in->b), 0, 255);
 }
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/Android.mk b/tests/RenderScriptTests/ImageProcessing2/Android.mk
index e05a518..dc6c0d8 100644
--- a/tests/RenderScriptTests/ImageProcessing2/Android.mk
+++ b/tests/RenderScriptTests/ImageProcessing2/Android.mk
@@ -27,6 +27,7 @@
 LOCAL_PACKAGE_NAME := ImageProcessing2
 LOCAL_SDK_VERSION := 8
 LOCAL_RENDERSCRIPT_TARGET_API := 17
+LOCAL_RENDERSCRIPT_COMPATIBILITY := 17
 LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE := $(TOPDIR)external/clang/lib/Headers \
                                         $(TOPDIR)frameworks/rs/scriptc
 
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
index 7662007..8645ae5 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
@@ -84,6 +84,7 @@
         unitTests.add(new UT_alloc(this, mRes, mCtx));
         unitTests.add(new UT_refcount(this, mRes, mCtx));
         unitTests.add(new UT_foreach(this, mRes, mCtx));
+        unitTests.add(new UT_foreach_bounds(this, mRes, mCtx));
         unitTests.add(new UT_noroot(this, mRes, mCtx));
         unitTests.add(new UT_atomic(this, mRes, mCtx));
         unitTests.add(new UT_struct(this, mRes, mCtx));
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach_bounds.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach_bounds.java
new file mode 100644
index 0000000..bda055b
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach_bounds.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+
+public class UT_foreach_bounds extends UnitTest {
+    private Resources mRes;
+    private Allocation A;
+
+    protected UT_foreach_bounds(RSTestCore rstc, Resources res, Context ctx) {
+        super(rstc, "ForEach (bounds)", ctx);
+        mRes = res;
+    }
+
+    private void initializeGlobals(RenderScript RS, ScriptC_foreach_bounds s) {
+        Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
+        int X = 5;
+        int Y = 7;
+        s.set_dimX(X);
+        s.set_dimY(Y);
+        typeBuilder.setX(X).setY(Y);
+        A = Allocation.createTyped(RS, typeBuilder.create());
+        s.bind_a(A);
+        s.set_s(s);
+        s.set_ain(A);
+        s.set_aout(A);
+        s.set_xStart(2);
+        s.set_xEnd(5);
+        s.set_yStart(3);
+        s.set_yEnd(6);
+        s.forEach_zero(A);
+
+        return;
+    }
+
+    public void run() {
+        RenderScript pRS = RenderScript.create(mCtx);
+        ScriptC_foreach_bounds s = new ScriptC_foreach_bounds(pRS);
+        pRS.setMessageHandler(mRsMessage);
+        initializeGlobals(pRS, s);
+        s.invoke_foreach_bounds_test();
+        pRS.finish();
+        waitForMessage();
+        pRS.destroy();
+    }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach_bounds.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach_bounds.rs
new file mode 100644
index 0000000..ddf17f8
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach_bounds.rs
@@ -0,0 +1,71 @@
+#include "shared.rsh"
+
+int *a;
+int dimX;
+int dimY;
+int xStart = 0;
+int xEnd = 0;
+int yStart = 0;
+int yEnd = 0;
+
+rs_script s;
+rs_allocation ain;
+rs_allocation aout;
+
+void root(int *out, uint32_t x, uint32_t y) {
+    *out = x + y * dimX;
+}
+
+int __attribute__((kernel)) zero() {
+    return 0;
+}
+
+static bool test_root_output() {
+    bool failed = false;
+    int i, j;
+
+    for (j = 0; j < dimY; j++) {
+        for (i = 0; i < dimX; i++) {
+            rsDebug("i: ", i);
+            rsDebug("j: ", j);
+            rsDebug("a[j][i]: ", a[i + j * dimX]);
+            if (i < xStart || i >= xEnd || j < yStart || j >= yEnd) {
+                _RS_ASSERT(a[i + j * dimX] == 0);
+            } else {
+                _RS_ASSERT(a[i + j * dimX] == (i + j * dimX));
+            }
+        }
+    }
+
+    if (failed) {
+        rsDebug("test_root_output FAILED", 0);
+    }
+    else {
+        rsDebug("test_root_output PASSED", 0);
+    }
+
+    return failed;
+}
+
+void foreach_bounds_test() {
+    static bool failed = false;
+
+    rs_script_call_t rssc = {0};
+    rssc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
+    rssc.xStart = xStart;
+    rssc.xEnd = xEnd;
+    rssc.yStart = yStart;
+    rssc.yEnd = yEnd;
+
+    rsForEach(s, ain, aout, NULL, 0, &rssc);
+
+    failed |= test_root_output();
+
+    if (failed) {
+        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+    }
+    else {
+        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+    }
+}
+