Merge "Audio: Flag volume adjustments from hardware keys."
diff --git a/api/current.txt b/api/current.txt
index 7bac613..4e51621 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15145,7 +15145,7 @@
     method public void setPropertyString(java.lang.String, java.lang.String);
     field public static final int EVENT_KEY_EXPIRED = 3; // 0x3
     field public static final int EVENT_KEY_REQUIRED = 2; // 0x2
-    field public static final int EVENT_PROVISION_REQUIRED = 1; // 0x1
+    field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
     field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5
     field public static final int EVENT_VENDOR_DEFINED = 4; // 0x4
     field public static final int KEY_TYPE_OFFLINE = 2; // 0x2
@@ -32918,6 +32918,7 @@
     method public boolean getTitleOptionalHint();
     method public int getType();
     method public abstract void invalidate();
+    method public void invalidateContentRect();
     method public boolean isTitleOptional();
     method public abstract void setCustomView(android.view.View);
     method public abstract void setSubtitle(java.lang.CharSequence);
@@ -32938,6 +32939,11 @@
     method public abstract boolean onPrepareActionMode(android.view.ActionMode, android.view.Menu);
   }
 
+  public static abstract class ActionMode.Callback2 implements android.view.ActionMode.Callback {
+    ctor public ActionMode.Callback2();
+    method public void onGetContentRect(android.view.ActionMode, android.view.View, android.graphics.Rect);
+  }
+
   public abstract class ActionProvider {
     ctor public ActionProvider(android.content.Context);
     method public boolean hasSubMenu();
@@ -37444,6 +37450,7 @@
     method public void goBack();
     method public void goBackOrForward(int);
     method public void goForward();
+    method public void insertVisualStateCallback(long, android.webkit.WebView.VisualStateCallback);
     method public void invokeZoomPicker();
     method public boolean isPrivateBrowsingEnabled();
     method public void loadData(java.lang.String, java.lang.String, java.lang.String);
@@ -37518,6 +37525,11 @@
     method public abstract deprecated void onNewPicture(android.webkit.WebView, android.graphics.Picture);
   }
 
+  public static abstract class WebView.VisualStateCallback {
+    ctor public WebView.VisualStateCallback();
+    method public abstract void onComplete(long);
+  }
+
   public class WebView.WebViewTransport {
     ctor public WebView.WebViewTransport();
     method public synchronized android.webkit.WebView getWebView();
@@ -37529,6 +37541,7 @@
     method public void doUpdateVisitedHistory(android.webkit.WebView, java.lang.String, boolean);
     method public void onFormResubmission(android.webkit.WebView, android.os.Message, android.os.Message);
     method public void onLoadResource(android.webkit.WebView, java.lang.String);
+    method public void onPageCommitVisible(android.webkit.WebView, java.lang.String);
     method public void onPageFinished(android.webkit.WebView, java.lang.String);
     method public void onPageStarted(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
     method public void onReceivedClientCertRequest(android.webkit.WebView, android.webkit.ClientCertRequest);
diff --git a/api/system-current.txt b/api/system-current.txt
index 89c0460e..d0dd852 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -16334,7 +16334,7 @@
     method public void unprovisionDevice();
     field public static final int EVENT_KEY_EXPIRED = 3; // 0x3
     field public static final int EVENT_KEY_REQUIRED = 2; // 0x2
-    field public static final int EVENT_PROVISION_REQUIRED = 1; // 0x1
+    field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
     field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5
     field public static final int EVENT_VENDOR_DEFINED = 4; // 0x4
     field public static final int KEY_TYPE_OFFLINE = 2; // 0x2
@@ -35274,6 +35274,7 @@
     method public boolean getTitleOptionalHint();
     method public int getType();
     method public abstract void invalidate();
+    method public void invalidateContentRect();
     method public boolean isTitleOptional();
     method public abstract void setCustomView(android.view.View);
     method public abstract void setSubtitle(java.lang.CharSequence);
@@ -35294,6 +35295,11 @@
     method public abstract boolean onPrepareActionMode(android.view.ActionMode, android.view.Menu);
   }
 
+  public static abstract class ActionMode.Callback2 implements android.view.ActionMode.Callback {
+    ctor public ActionMode.Callback2();
+    method public void onGetContentRect(android.view.ActionMode, android.view.View, android.graphics.Rect);
+  }
+
   public abstract class ActionProvider {
     ctor public ActionProvider(android.content.Context);
     method public boolean hasSubMenu();
@@ -39876,6 +39882,7 @@
     method public void goBack();
     method public void goBackOrForward(int);
     method public void goForward();
+    method public void insertVisualStateCallback(long, android.webkit.WebView.VisualStateCallback);
     method public void invokeZoomPicker();
     method public boolean isPrivateBrowsingEnabled();
     method public void loadData(java.lang.String, java.lang.String, java.lang.String);
@@ -39980,6 +39987,11 @@
     method public void super_setLayoutParams(android.view.ViewGroup.LayoutParams);
   }
 
+  public static abstract class WebView.VisualStateCallback {
+    ctor public WebView.VisualStateCallback();
+    method public abstract void onComplete(long);
+  }
+
   public class WebView.WebViewTransport {
     ctor public WebView.WebViewTransport();
     method public synchronized android.webkit.WebView getWebView();
@@ -39991,6 +40003,7 @@
     method public void doUpdateVisitedHistory(android.webkit.WebView, java.lang.String, boolean);
     method public void onFormResubmission(android.webkit.WebView, android.os.Message, android.os.Message);
     method public void onLoadResource(android.webkit.WebView, java.lang.String);
+    method public void onPageCommitVisible(android.webkit.WebView, java.lang.String);
     method public void onPageFinished(android.webkit.WebView, java.lang.String);
     method public void onPageStarted(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
     method public void onReceivedClientCertRequest(android.webkit.WebView, android.webkit.ClientCertRequest);
@@ -40137,6 +40150,7 @@
     method public abstract void goBackOrForward(int);
     method public abstract void goForward();
     method public abstract void init(java.util.Map<java.lang.String, java.lang.Object>, boolean);
+    method public abstract void insertVisualStateCallback(long, android.webkit.WebView.VisualStateCallback);
     method public abstract void invokeZoomPicker();
     method public abstract boolean isPaused();
     method public abstract boolean isPrivateBrowsingEnabled();
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2ed8c44..f685475 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2790,6 +2790,31 @@
     /** {@hide} */
     public static final String ACTION_MASTER_CLEAR = "android.intent.action.MASTER_CLEAR";
 
+    /**
+     * Broadcast action: report that a settings element is being restored from backup.  The intent
+     * contains three extras: EXTRA_SETTING_NAME is a string naming the restored setting,
+     * EXTRA_SETTING_NEW_VALUE is the value being restored, and EXTRA_SETTING_PREVIOUS_VALUE
+     * is the value of that settings entry prior to the restore operation.  All of these values are
+     * represented as strings.
+     *
+     * <p>This broadcast is sent only for settings provider entries known to require special handling
+     * around restore time.  These entries are found in the BROADCAST_ON_RESTORE table within
+     * the provider's backup agent implementation.
+     *
+     * @see #EXTRA_SETTING_NAME
+     * @see #EXTRA_SETTING_PREVIOUS_VALUE
+     * @see #EXTRA_SETTING_NEW_VALUE
+     * {@hide}
+     */
+    public static final String ACTION_SETTING_RESTORED = "android.os.action.SETTING_RESTORED";
+
+    /** {@hide} */
+    public static final String EXTRA_SETTING_NAME = "setting_name";
+    /** {@hide} */
+    public static final String EXTRA_SETTING_PREVIOUS_VALUE = "previous_value";
+    /** {@hide} */
+    public static final String EXTRA_SETTING_NEW_VALUE = "new_value";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Standard intent categories (see addCategory()).
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index 367a078..b5a019d 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -292,6 +292,10 @@
                     Log.e(TAG, "configureOutputs - null outputs are not allowed");
                     return BAD_VALUE;
                 }
+                if (!output.isValid()) {
+                    Log.e(TAG, "configureOutputs - invalid output surfaces are not allowed");
+                    return BAD_VALUE;
+                }
                 StreamConfigurationMap streamConfigurations = mStaticCharacteristics.
                         get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
 
@@ -522,7 +526,7 @@
      * @return the width and height of the surface
      *
      * @throws NullPointerException if the {@code surface} was {@code null}
-     * @throws IllegalStateException if the {@code surface} was invalid
+     * @throws BufferQueueAbandonedException if the {@code surface} was invalid
      */
     public static Size getSurfaceSize(Surface surface) throws BufferQueueAbandonedException {
         checkNotNull(surface);
diff --git a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
index 7e0c01b..4b7cfbf 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
@@ -60,7 +60,7 @@
             case CameraBinderDecorator.NO_ERROR: {
                 return CameraBinderDecorator.NO_ERROR;
             }
-            case CameraBinderDecorator.ENODEV: {
+            case CameraBinderDecorator.BAD_VALUE: {
                 throw new BufferQueueAbandonedException();
             }
         }
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index ff74c59..691798f 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -498,6 +498,10 @@
             return;
         }
         for(Surface s : surfaces) {
+            if (s == null || !s.isValid()) {
+                Log.w(TAG, "Jpeg surface is invalid, skipping...");
+                continue;
+            }
             try {
                 LegacyCameraDevice.setSurfaceFormat(s, LegacyMetadataMapper.HAL_PIXEL_FORMAT_BLOB);
             } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index e303f61..de970cb 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -364,6 +364,12 @@
     public static final int GO_TO_SLEEP_REASON_HDMI = 5;
 
     /**
+     * Go to sleep reason code: Going to sleep due to the sleep button being pressed.
+     * @hide
+     */
+    public static final int GO_TO_SLEEP_REASON_SLEEP_BUTTON = 6;
+
+    /**
      * Go to sleep flag: Skip dozing state and directly go to full sleep.
      * @hide
      */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4c452aa..3813277 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5374,6 +5374,7 @@
             ACCESSIBILITY_SCRIPT_INJECTION,
             BACKUP_AUTO_RESTORE,
             ENABLED_ACCESSIBILITY_SERVICES,
+            ENABLED_NOTIFICATION_LISTENERS,
             TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
             TOUCH_EXPLORATION_ENABLED,
             ACCESSIBILITY_ENABLED,
@@ -5398,6 +5399,9 @@
             WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,            // moved to global
             WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,               // moved to global
             WIFI_NUM_OPEN_NETWORKS_KEPT,                        // moved to global
+            SELECTED_SPELL_CHECKER,
+            SELECTED_SPELL_CHECKER_SUBTYPE,
+            SPELL_CHECKER_ENABLED,
             MOUNT_PLAY_NOTIFICATION_SND,
             MOUNT_UMS_AUTOSTART,
             MOUNT_UMS_PROMPT,
diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java
index a018138..9f202a9 100644
--- a/core/java/android/view/ActionMode.java
+++ b/core/java/android/view/ActionMode.java
@@ -18,6 +18,7 @@
 
 
 import android.annotation.StringRes;
+import android.graphics.Rect;
 
 /**
  * Represents a contextual mode of the user interface. Action modes can be used to provide
@@ -197,6 +198,15 @@
     public abstract void invalidate();
 
     /**
+     * Invalidate the content rect associated to this ActionMode. This only makes sense for
+     * action modes that support dynamic positioning on the screen, and provides a more efficient
+     * way to reposition it without invalidating the whole action mode.
+     *
+     * @see Callback2#onGetContentRect(ActionMode, View, Rect) .
+     */
+    public void invalidateContentRect() {}
+
+    /**
      * Finish and close this action mode. The action mode's {@link ActionMode.Callback} will
      * have its {@link Callback#onDestroyActionMode(ActionMode)} method called.
      */
@@ -298,4 +308,31 @@
          */
         public void onDestroyActionMode(ActionMode mode);
     }
-}
\ No newline at end of file
+
+    /**
+     * Extension of {@link ActionMode.Callback} to provide content rect information. This is
+     * required for ActionModes with dynamic positioning such as the ones with type
+     * {@link ActionMode#TYPE_FLOATING} to ensure the positioning doesn't obscure app content. If
+     * an app fails to provide a subclass of this class, a default implementation will be used.
+     */
+    public static abstract class Callback2 implements ActionMode.Callback {
+
+        /**
+         * Called when an ActionMode needs to be positioned on screen, potentially occluding view
+         * content. Note this may be called on a per-frame basis.
+         *
+         * @param mode The ActionMode that requires positioning.
+         * @param view The View that originated the ActionMode, in whose coordinates the Rect should
+         *          be provided.
+         * @param outRect The Rect to be populated with the content position.
+         */
+        public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
+            if (view != null) {
+                outRect.set(0, 0, view.getWidth(), view.getHeight());
+            } else {
+                outRect.set(0, 0, 0, 0);
+            }
+        }
+
+    }
+}
diff --git a/core/java/android/view/PhoneWindow.java b/core/java/android/view/PhoneWindow.java
index c6c1481..543021e 100644
--- a/core/java/android/view/PhoneWindow.java
+++ b/core/java/android/view/PhoneWindow.java
@@ -2670,17 +2670,13 @@
         @Override
         public ActionMode startActionModeForChild(View originalView,
                 ActionMode.Callback callback) {
-            // originalView can be used here to be sure that we don't obscure
-            // relevant content with the context mode UI.
-            return startActionMode(callback);
+            return startActionModeForChild(originalView, callback, ActionMode.TYPE_PRIMARY);
         }
 
         @Override
         public ActionMode startActionModeForChild(
                 View child, ActionMode.Callback callback, int type) {
-            // originalView can be used here to be sure that we don't obscure
-            // relevant content with the context mode UI.
-            return startActionMode(callback, type);
+            return startActionMode(child, callback, type);
         }
 
         @Override
@@ -2690,7 +2686,12 @@
 
         @Override
         public ActionMode startActionMode(ActionMode.Callback callback, int type) {
-            ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
+            return startActionMode(this, callback, type);
+        }
+
+        private ActionMode startActionMode(
+                View originatingView, ActionMode.Callback callback, int type) {
+            ActionMode.Callback2 wrappedCallback = new ActionModeCallback2Wrapper(callback);
             ActionMode mode = null;
             if (getCallback() != null && !isDestroyed()) {
                 try {
@@ -3292,12 +3293,12 @@
         }
 
         /**
-         * Clears out internal reference when the action mode is destroyed.
+         * Clears out internal references when the action mode is destroyed.
          */
-        private class ActionModeCallbackWrapper implements ActionMode.Callback {
-            private ActionMode.Callback mWrapped;
+        private class ActionModeCallback2Wrapper extends ActionMode.Callback2 {
+            private final ActionMode.Callback mWrapped;
 
-            public ActionModeCallbackWrapper(ActionMode.Callback wrapped) {
+            public ActionModeCallback2Wrapper(ActionMode.Callback wrapped) {
                 mWrapped = wrapped;
             }
 
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index e1942be..a75e8a7 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -573,7 +573,7 @@
         if (other.mType != mType) {
             throw new IllegalArgumentException("Not same type.");
         }
-        if (!mBoundsInScreen.equals(mBoundsInScreen)) {
+        if (!mBoundsInScreen.equals(other.mBoundsInScreen)) {
             return true;
         }
         if (mLayer != other.mLayer) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 67ad642..6711a6b 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -364,6 +364,20 @@
     }
 
     /**
+     * Callback interface supplied to {@link #insertVisualStateCallback} for receiving
+     * notifications about the visual state.
+     */
+    public static abstract class VisualStateCallback {
+        /**
+         * Invoked when the visual state is ready to be drawn in the next {@link #onDraw}.
+         *
+         * @param requestId the id supplied to the corresponding {@link #insertVisualStateCallback}
+         * request
+         */
+        public abstract void onComplete(long requestId);
+    }
+
+    /**
      * Interface to listen for new pictures as they change.
      *
      * @deprecated This interface is now obsolete.
@@ -1144,6 +1158,60 @@
     }
 
     /**
+     * Inserts a {@link VisualStateCallback}.
+     *
+     * <p>Updates to the the DOM are reflected asynchronously such that when the DOM is updated the
+     * subsequent {@link WebView#onDraw} invocation might not reflect those updates. The
+     * {@link VisualStateCallback} provides a mechanism to notify the caller when the contents of
+     * the DOM at the current time are ready to be drawn the next time the {@link WebView} draws.
+     * By current time we mean the time at which this API was called. The next draw after the
+     * callback completes is guaranteed to reflect all the updates to the DOM applied before the
+     * current time, but it may also contain updates applied after the current time.</p>
+     *
+     * <p>The state of the DOM covered by this API includes the following:
+     * <ul>
+     * <li>primitive HTML elements (div, img, span, etc..)</li>
+     * <li>images</li>
+     * <li>CSS animations</li>
+     * <li>WebGL</li>
+     * <li>canvas</li>
+     * </ul>
+     * It does not include the state of:
+     * <ul>
+     * <li>the video tag</li>
+     * </ul></p>
+     *
+     * <p>To guarantee that the {@link WebView} will successfully render the first frame
+     * after the {@link VisualStateCallback#onComplete} method has been called a set of conditions
+     * must be met:
+     * <ul>
+     * <li>If the {@link WebView}'s visibility is set to {@link View#VISIBLE VISIBLE} then
+     * the {@link WebView} must be attached to the view hierarchy.</li>
+     * <li>If the {@link WebView}'s visibility is set to {@link View#INVISIBLE INVISIBLE}
+     * then the {@link WebView} must be attached to the view hierarchy and must be made
+     * {@link View#VISIBLE VISIBLE} from the {@link VisualStateCallback#onComplete} method.</li>
+     * <li>If the {@link WebView}'s visibility is set to {@link View#GONE GONE} then the
+     * {@link WebView} must be attached to the view hierarchy and its
+     * {@link AbsoluteLayout.LayoutParams LayoutParams}'s width and height need to be set to fixed
+     * values and must be made {@link View#VISIBLE VISIBLE} from the
+     * {@link VisualStateCallback#onComplete} method.</li>
+     * </ul></p>
+     *
+     * <p>When using this API it is also recommended to enable pre-rasterization if the
+     * {@link WebView} is offscreen to avoid flickering. See WebSettings#setOffscreenPreRaster for
+     * more details and do consider its caveats.</p>
+     *
+     * @param requestId an id that will be returned in the callback to allow callers to match
+     * requests with callbacks.
+     * @param callback the callback to be invoked.
+     */
+    public void insertVisualStateCallback(long requestId, VisualStateCallback callback) {
+        checkThread();
+        if (TRACE) Log.d(LOGTAG, "insertVisualStateCallback");
+        mProvider.insertVisualStateCallback(requestId, callback);
+    }
+
+    /**
      * Clears this WebView so that onDraw() will draw nothing but white background,
      * and onMeasure() will return 0 if MeasureSpec is not MeasureSpec.EXACTLY.
      * @deprecated Use WebView.loadUrl("about:blank") to reliably reset the view state
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 34b8cf6..53c7e04 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -83,6 +83,32 @@
     }
 
     /**
+     * Notify the host application that the page commit is visible.
+     *
+     * <p>This is the earliest point at which we can guarantee that the contents of the previously
+     * loaded page will not longer be drawn in the next {@link WebView#onDraw}. The next draw will
+     * render the {@link WebView#setBackgroundColor background color} of the WebView or some of the
+     * contents from the committed page already. This callback may be useful when reusing
+     * {@link WebView}s to ensure that no stale content is shown. This method is only called for
+     * the main frame.</p>
+     *
+     * <p>This method is called when the state of the DOM at the point at which the
+     * body of the HTTP response (commonly the string of html) had started loading will be visible.
+     * If you set a background color for the page in the HTTP response body this will most likely
+     * be visible and perhaps some other elements. At that point no other resources had usually
+     * been loaded, so you can expect images for example to not be visible. If you want
+     * a finer level of granularity consider calling {@link WebView#insertVisualStateCallback}
+     * directly.</p>
+     *
+     * <p>Please note that all the conditions and recommendations presented in
+     * {@link WebView#insertVisualStateCallback} also apply to this API.<p>
+     *
+     * @param url the url of the committed page
+     */
+    public void onPageCommitVisible(WebView view, String url) {
+    }
+
+    /**
      * Notify the host application of a resource request and allow the
      * application to return the data.  If the return value is null, the WebView
      * will continue to load the resource as usual.  Otherwise, the return
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index 0cdb875..fa2ce1b 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -40,6 +40,8 @@
 import android.view.inputmethod.InputConnection;
 import android.webkit.WebView.HitTestResult;
 import android.webkit.WebView.PictureListener;
+import android.webkit.WebView.VisualStateCallback;
+
 
 import java.io.BufferedWriter;
 import java.io.File;
@@ -146,6 +148,8 @@
 
     public boolean pageDown(boolean bottom);
 
+    public void insertVisualStateCallback(long requestId, VisualStateCallback callback);
+
     public void clearView();
 
     public Picture capturePicture();
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index 2bf02f1..7ae7d0f 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -23,7 +23,6 @@
 
 import com.android.internal.R;
 import com.android.internal.view.ActionBarPolicy;
-import com.android.internal.view.ActionModeWrapper;
 import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.view.menu.MenuPopupHelper;
 import com.android.internal.view.menu.SubMenuBuilder;
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 29326d3a..57fcf57 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -120,18 +120,6 @@
                 & ApplicationInfo.FLAG_SYSTEM) != 0;
     }
 
-    /**
-     * @deprecated Use {@link #isSystemImeThatHasSubtypeOf(InputMethodInfo, Context, boolean,
-     * Locale, boolean, String)} instead.
-     */
-    @Deprecated
-    public static boolean isSystemImeThatHasEnglishKeyboardSubtype(InputMethodInfo imi) {
-        if (!isSystemIme(imi)) {
-            return false;
-        }
-        return containsSubtypeOf(imi, ENGLISH_LOCALE.getLanguage(), SUBTYPE_MODE_KEYBOARD);
-    }
-
     public static boolean isSystemImeThatHasSubtypeOf(final InputMethodInfo imi,
             final Context context, final boolean checkDefaultAttribute,
             @Nullable final Locale requiredLocale, final boolean checkCountry,
@@ -382,35 +370,6 @@
                 .build();
     }
 
-    /**
-     * @deprecated Use {@link #isSystemImeThatHasSubtypeOf(InputMethodInfo, Context, boolean,
-     * Locale, boolean, String)} instead.
-     */
-    @Deprecated
-    public static boolean isValidSystemDefaultIme(
-            boolean isSystemReady, InputMethodInfo imi, Context context) {
-        if (!isSystemReady) {
-            return false;
-        }
-        if (!isSystemIme(imi)) {
-            return false;
-        }
-        if (imi.getIsDefaultResourceId() != 0) {
-            try {
-                if (imi.isDefault(context) && containsSubtypeOf(
-                        imi, context.getResources().getConfiguration().locale.getLanguage(),
-                        SUBTYPE_MODE_ANY)) {
-                    return true;
-                }
-            } catch (Resources.NotFoundException ex) {
-            }
-        }
-        if (imi.getSubtypeCount() == 0) {
-            Slog.w(TAG, "Found no subtypes in a system IME: " + imi.getPackageName());
-        }
-        return false;
-    }
-
     public static Locale constructLocaleFromString(String localeStr) {
         if (TextUtils.isEmpty(localeStr)) {
             return null;
@@ -459,25 +418,6 @@
         return false;
     }
 
-    /**
-     * @deprecated Use {@link #containsSubtypeOf(InputMethodInfo, Locale, boolean, String)} instead.
-     */
-    @Deprecated
-    public static boolean containsSubtypeOf(InputMethodInfo imi, String language, String mode) {
-        final int N = imi.getSubtypeCount();
-        for (int i = 0; i < N; ++i) {
-            final InputMethodSubtype subtype = imi.getSubtypeAt(i);
-            if (!subtype.getLocale().startsWith(language)) {
-                continue;
-            }
-            if (mode == SUBTYPE_MODE_ANY || TextUtils.isEmpty(mode) ||
-                    mode.equalsIgnoreCase(subtype.getMode())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     public static ArrayList<InputMethodSubtype> getSubtypes(InputMethodInfo imi) {
         ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
         final int subtypeCount = imi.getSubtypeCount();
@@ -510,12 +450,15 @@
         while (i > 0) {
             i--;
             final InputMethodInfo imi = enabledImes.get(i);
-            if (InputMethodUtils.isSystemImeThatHasEnglishKeyboardSubtype(imi)
-                    && !imi.isAuxiliaryIme()) {
+            if (imi.isAuxiliaryIme()) {
+                continue;
+            }
+            if (InputMethodUtils.isSystemIme(imi)
+                    && containsSubtypeOf(imi, ENGLISH_LOCALE, false /* checkCountry */,
+                            SUBTYPE_MODE_KEYBOARD)) {
                 return imi;
             }
-            if (firstFoundSystemIme < 0 && InputMethodUtils.isSystemIme(imi)
-                    && !imi.isAuxiliaryIme()) {
+            if (firstFoundSystemIme < 0 && InputMethodUtils.isSystemIme(imi)) {
                 firstFoundSystemIme = i;
             }
         }
diff --git a/core/java/com/android/internal/view/ActionModeWrapper.java b/core/java/com/android/internal/view/ActionModeWrapper.java
deleted file mode 100644
index d98617d..0000000
--- a/core/java/com/android/internal/view/ActionModeWrapper.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2015 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.internal.view;
-
-import android.content.Context;
-import android.view.ActionMode;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-
-import com.android.internal.view.menu.MenuBuilder;
-
-/**
- * ActionMode implementation that wraps several actions modes and creates them on the fly depending
- * on the ActionMode type chosen by the client.
- */
-public class ActionModeWrapper extends ActionMode {
-
-    /**
-     * Interface to defer the ActionMode creation until the type is chosen.
-     */
-    public interface ActionModeProvider {
-        /**
-         * Create the desired ActionMode, that will immediately be used as the current active mode
-         * in the decorator.
-         *
-         * @param callback The {@link ActionMode.Callback} to be used.
-         * @param menuBuilder The {@link MenuBuilder} that should be used by the created
-         *      {@link ActionMode}. This will already have been populated.
-         * @return A new {@link ActionMode} ready to be used that uses menuBuilder as its menu.
-         */
-        ActionMode createActionMode(ActionMode.Callback callback, MenuBuilder menuBuilder);
-    }
-
-    private ActionMode mActionMode;
-    private final Context mContext;
-    private MenuBuilder mMenu;
-    private final ActionMode.Callback mCallback;
-    private boolean mTypeLocked = false;
-
-    private CharSequence mTitle;
-    private CharSequence mSubtitle;
-    private View mCustomView;
-    
-    private final ActionModeProvider mActionModeProvider;
-
-    public ActionModeWrapper(
-            Context context, ActionMode.Callback callback, ActionModeProvider actionModeProvider) {
-        mContext = context;
-        mMenu = new MenuBuilder(context).setDefaultShowAsAction(
-                MenuItem.SHOW_AS_ACTION_IF_ROOM);
-        mCallback = callback;
-        mActionModeProvider = actionModeProvider;
-    }
-
-    @Override
-    public void setTitle(CharSequence title) {
-        if (mActionMode != null) {
-            mActionMode.setTitle(title);
-        } else {
-            mTitle = title;
-        }
-    }
-
-    @Override
-    public void setTitle(int resId) {
-        if (mActionMode != null) {
-            mActionMode.setTitle(resId);
-        } else {
-            mTitle = resId != 0 ? mContext.getString(resId) : null;
-        }
-    }
-
-    @Override
-    public void setSubtitle(CharSequence subtitle) {
-        if (mActionMode != null) {
-            mActionMode.setSubtitle(subtitle);
-        } else {
-            mSubtitle = subtitle;
-        }
-    }
-
-    @Override
-    public void setSubtitle(int resId) {
-        if (mActionMode != null) {
-            mActionMode.setSubtitle(resId);
-        } else {
-            mSubtitle = resId != 0 ? mContext.getString(resId) : null;
-        }
-    }
-
-    @Override
-    public void setCustomView(View view) {
-        if (mActionMode != null) {
-            mActionMode.setCustomView(view);
-        } else {
-            mCustomView = view;
-        }
-    }
-
-    public ActionMode getWrappedActionMode() {
-        return mActionMode;
-    }
-
-    /**
-     * Set the current type as final and create the necessary ActionMode. After this call, any
-     * changes to the ActionMode type will be ignored.
-     */
-    public void lockType() {
-        mTypeLocked = true;
-        switch (getType()) {
-            case ActionMode.TYPE_PRIMARY:
-            default:
-                mActionMode = mActionModeProvider.createActionMode(mCallback, mMenu);
-                break;
-            case ActionMode.TYPE_FLOATING:
-                // Not implemented yet.
-                break;
-        }
-
-        if (mActionMode == null) {
-            return;
-        }
-
-        mActionMode.setTitle(mTitle);
-        mActionMode.setSubtitle(mSubtitle);
-        if (mCustomView != null) {
-            mActionMode.setCustomView(mCustomView);
-        }
-
-        mTitle = null;
-        mSubtitle = null;
-        mCustomView = null;
-    }
-
-    @Override
-    public void setType(int type) {
-        if (!mTypeLocked) {
-            super.setType(type);
-        } else {
-            throw new IllegalStateException(
-                    "You can't change the ActionMode's type after onCreateActionMode.");
-        }
-    }
-
-    @Override
-    public void invalidate() {
-        if (mActionMode != null) {
-            mActionMode.invalidate();
-        }
-    }
-
-    @Override
-    public void finish() {
-        if (mActionMode != null) {
-            mActionMode.finish();
-        } else {
-            mCallback.onDestroyActionMode(this);
-        }
-    }
-
-    @Override
-    public Menu getMenu() {
-        return mMenu;
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        if (mActionMode != null) {
-            return mActionMode.getTitle();
-        }
-        return mTitle;
-    }
-
-    @Override
-    public CharSequence getSubtitle() {
-        if (mActionMode != null) {
-            return mActionMode.getSubtitle();
-        }
-        return mSubtitle;
-    }
-
-    @Override
-    public View getCustomView() {
-        if (mActionMode != null) {
-            return mActionMode.getCustomView();
-        }
-        return mCustomView;
-    }
-
-    @Override
-    public MenuInflater getMenuInflater() {
-        return new MenuInflater(mContext);
-    }
-
-}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 441af15..2327899 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -649,9 +649,9 @@
     /*
      * JIT related options.
      */
-    parseRuntimeOption("dalvik.vm.usejit", usejitOptsBuf, "-Xusejit:");
-    parseRuntimeOption("dalvik.vm.jitcodecachesize", jitcodecachesizeOptsBuf, "-Xjitcodecachesize:");
-    parseRuntimeOption("dalvik.vm.jitthreshold", jitthresholdOptsBuf, "-Xjitthreshold:");
+    parseRuntimeOption("debug.dalvik.vm.usejit", usejitOptsBuf, "-Xusejit:");
+    parseRuntimeOption("debug.dalvik.vm.jitcodecachesize", jitcodecachesizeOptsBuf, "-Xjitcodecachesize:");
+    parseRuntimeOption("debug.dalvik.vm.jitthreshold", jitthresholdOptsBuf, "-Xjitthreshold:");
 
     property_get("ro.config.low_ram", propBuf, "");
     if (strcmp(propBuf, "true") == 0) {
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
index 87896df..afdfd8f 100644
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
@@ -373,8 +373,7 @@
         return NULL;
     }
     if (anw == NULL) {
-        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
-                "Surface had no valid native window.");
+        ALOGE("%s: Surface had no valid native window.", __FUNCTION__);
         return NULL;
     }
     return anw;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ed4776b..4d6b5f6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -90,6 +90,8 @@
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_HOST_RESTORED" />
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_RESTORED" />
 
+    <protected-broadcast android:name="android.os.action.SETTING_RESTORED" />
+
     <protected-broadcast android:name="android.backup.intent.RUN" />
     <protected-broadcast android:name="android.backup.intent.CLEAR" />
     <protected-broadcast android:name="android.backup.intent.INIT" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a781786..37c9598 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -664,6 +664,12 @@
     -->
     <integer name="config_triplePressOnPowerBehavior">0</integer>
 
+    <!-- Control the behavior when the user presses the sleep button.
+            0 - Go to sleep (doze)
+            1 - Go to sleep (doze) and go home
+    -->
+    <integer name="config_shortPressOnSleepBehavior">0</integer>
+
     <!-- Package name for default keyguard appwidget [DO NOT TRANSLATE] -->
     <string name="widget_default_package_name" translatable="false"></string>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 20ec563..0617503 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -367,6 +367,7 @@
   <java-symbol type="integer" name="config_shortPressOnPowerBehavior" />
   <java-symbol type="integer" name="config_toastDefaultGravity" />
   <java-symbol type="integer" name="config_triplePressOnPowerBehavior" />
+  <java-symbol type="integer" name="config_shortPressOnSleepBehavior" />
   <java-symbol type="integer" name="config_wifi_framework_scan_interval" />
   <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
   <java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 824a7ad..18ffe12 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -443,6 +443,7 @@
     @Override
     public void close() {
         setOnImageAvailableListener(null, null);
+        if (mSurface != null) mSurface.release();
         nativeClose();
     }
 
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index d7752b9..6b37a34 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -254,6 +254,9 @@
      * This event type indicates that the app needs to request a certificate from
      * the provisioning server.  The request message data is obtained using
      * {@link #getProvisionRequest}
+     *
+     * @deprecated Handle provisioning via {@link android.media.NotProvisionedException}
+     * instead.
      */
     public static final int EVENT_PROVISION_REQUIRED = 1;
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index eac83d8..7f826ef 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -793,7 +793,7 @@
         }
 
         // Figure out the white list and redirects to the global table.
-        String[] whitelist = null;
+        final String[] whitelist;
         if (contentUri.equals(Settings.Secure.CONTENT_URI)) {
             whitelist = Settings.Secure.SETTINGS_TO_BACKUP;
         } else if (contentUri.equals(Settings.System.CONTENT_URI)) {
@@ -809,6 +809,7 @@
         Map<String, String> cachedEntries = new HashMap<String, String>();
         ContentValues contentValues = new ContentValues(2);
         SettingsHelper settingsHelper = mSettingsHelper;
+        ContentResolver cr = getContentResolver();
 
         final int whiteListSize = whitelist.length;
         for (int i = 0; i < whiteListSize; i++) {
@@ -841,14 +842,7 @@
             final Uri destination = (movedToGlobal != null && movedToGlobal.contains(key))
                     ? Settings.Global.CONTENT_URI
                     : contentUri;
-
-            // The helper doesn't care what namespace the keys are in
-            if (settingsHelper.restoreValue(key, value)) {
-                contentValues.clear();
-                contentValues.put(Settings.NameValueTable.NAME, key);
-                contentValues.put(Settings.NameValueTable.VALUE, value);
-                getContentResolver().insert(destination, contentValues);
-            }
+            settingsHelper.restoreValue(this, cr, contentValues, destination, key, value);
 
             if (DEBUG) {
                 Log.d(TAG, "Restored setting: " + destination + " : "+ key + "=" + value);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 4144c80..30786f0 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -19,7 +19,10 @@
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.backup.IBackupManager;
+import android.content.ContentResolver;
+import android.content.ContentValues;
 import android.content.Context;
+import android.content.Intent;
 import android.content.res.Configuration;
 import android.location.LocationManager;
 import android.media.AudioManager;
@@ -28,10 +31,12 @@
 import android.os.IPowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.ArraySet;
 
 import java.util.Locale;
 
@@ -41,6 +46,49 @@
     private AudioManager mAudioManager;
     private TelephonyManager mTelephonyManager;
 
+    /**
+     * A few settings elements are special in that a restore of those values needs to
+     * be post-processed by relevant parts of the OS.  A restore of any settings element
+     * mentioned in this table will therefore cause the system to send a broadcast with
+     * the {@link Intent#ACTION_SETTING_RESTORED} action, with extras naming the
+     * affected setting and supplying its pre-restore value for comparison.
+     *
+     * @see Intent#ACTION_SETTING_RESTORED
+     * @see System#SETTINGS_TO_BACKUP
+     * @see Secure#SETTINGS_TO_BACKUP
+     * @see Global#SETTINGS_TO_BACKUP
+     *
+     * {@hide}
+     */
+    private static final ArraySet<String> sBroadcastOnRestore;
+    static {
+        sBroadcastOnRestore = new ArraySet<String>(2);
+        sBroadcastOnRestore.add(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
+        sBroadcastOnRestore.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+    }
+
+    private interface SettingsLookup {
+        public String lookup(ContentResolver resolver, String name, int userHandle);
+    }
+
+    private static SettingsLookup sSystemLookup = new SettingsLookup() {
+        public String lookup(ContentResolver resolver, String name, int userHandle) {
+            return Settings.System.getStringForUser(resolver, name, userHandle);
+        }
+    };
+
+    private static SettingsLookup sSecureLookup = new SettingsLookup() {
+        public String lookup(ContentResolver resolver, String name, int userHandle) {
+            return Settings.Secure.getStringForUser(resolver, name, userHandle);
+        }
+    };
+
+    private static SettingsLookup sGlobalLookup = new SettingsLookup() {
+        public String lookup(ContentResolver resolver, String name, int userHandle) {
+            return Settings.Global.getStringForUser(resolver, name, userHandle);
+        }
+    };
+
     public SettingsHelper(Context context) {
         mContext = context;
         mAudioManager = (AudioManager) context
@@ -58,24 +106,67 @@
      * some cases the data will be written by the call to the appropriate API,
      * and in some cases the property value needs to be modified before setting.
      */
-    public boolean restoreValue(String name, String value) {
-        if (Settings.System.SCREEN_BRIGHTNESS.equals(name)) {
-            setBrightness(Integer.parseInt(value));
-        } else if (Settings.System.SOUND_EFFECTS_ENABLED.equals(name)) {
-            setSoundEffects(Integer.parseInt(value) == 1);
-        } else if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
-            setGpsLocation(value);
-            return false;
-        } else if (Settings.Secure.BACKUP_AUTO_RESTORE.equals(name)) {
-            setAutoRestore(Integer.parseInt(value) == 1);
-        } else if (isAlreadyConfiguredCriticalAccessibilitySetting(name)) {
-            return false;
-        } else if (Settings.System.RINGTONE.equals(name)
-                || Settings.System.NOTIFICATION_SOUND.equals(name)) {
-            setRingtone(name, value);
-            return false;
+    public void restoreValue(Context context, ContentResolver cr, ContentValues contentValues,
+            Uri destination, String name, String value) {
+        // Will we need a post-restore broadcast for this element?
+        String oldValue = null;
+        boolean sendBroadcast = false;
+        final SettingsLookup table;
+
+        if (destination.equals(Settings.Secure.CONTENT_URI)) {
+            table = sSecureLookup;
+        } else if (destination.equals(Settings.System.CONTENT_URI)) {
+            table = sSystemLookup;
+        } else { /* must be GLOBAL; this was preflighted by the caller */
+            table = sGlobalLookup;
         }
-        return true;
+
+        if (sBroadcastOnRestore.contains(name)) {
+            oldValue = table.lookup(cr, name, UserHandle.USER_OWNER);
+            sendBroadcast = true;
+        }
+
+        try {
+            if (Settings.System.SCREEN_BRIGHTNESS.equals(name)) {
+                setBrightness(Integer.parseInt(value));
+                // fall through to the ordinary write to settings
+            } else if (Settings.System.SOUND_EFFECTS_ENABLED.equals(name)) {
+                setSoundEffects(Integer.parseInt(value) == 1);
+                // fall through to the ordinary write to settings
+            } else if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
+                setGpsLocation(value);
+                return;
+            } else if (Settings.Secure.BACKUP_AUTO_RESTORE.equals(name)) {
+                setAutoRestore(Integer.parseInt(value) == 1);
+            } else if (isAlreadyConfiguredCriticalAccessibilitySetting(name)) {
+                return;
+            } else if (Settings.System.RINGTONE.equals(name)
+                    || Settings.System.NOTIFICATION_SOUND.equals(name)) {
+                setRingtone(name, value);
+                return;
+            }
+
+            // Default case: write the restored value to settings
+            contentValues.clear();
+            contentValues.put(Settings.NameValueTable.NAME, name);
+            contentValues.put(Settings.NameValueTable.VALUE, value);
+            cr.insert(destination, contentValues);
+        } catch (Exception e) {
+            // If we fail to apply the setting, by definition nothing happened
+            sendBroadcast = false;
+        } finally {
+            // If this was an element of interest, send the "we just restored it"
+            // broadcast with the historical value now that the new value has
+            // been committed and observers kicked off.
+            if (sendBroadcast) {
+                Intent intent = new Intent(Intent.ACTION_SETTING_RESTORED)
+                        .setPackage("android").addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
+                        .putExtra(Intent.EXTRA_SETTING_NAME, name)
+                        .putExtra(Intent.EXTRA_SETTING_NEW_VALUE, value)
+                        .putExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE, oldValue);
+                context.sendBroadcastAsUser(intent, UserHandle.OWNER, null);
+            }
+        }
     }
 
     public String onBackupValue(String name, String value) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index a712d78..bb5ff1b 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -352,6 +352,7 @@
         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
         intentFilter.addAction(Intent.ACTION_USER_REMOVED);
         intentFilter.addAction(Intent.ACTION_USER_PRESENT);
+        intentFilter.addAction(Intent.ACTION_SETTING_RESTORED);
 
         mContext.registerReceiverAsUser(new BroadcastReceiver() {
             @Override
@@ -369,6 +370,15 @@
                             onUserStateChangedLocked(userState);
                         }
                     }
+                } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
+                    final String which = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
+                    if (Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES.equals(which)) {
+                        synchronized (mLock) {
+                            restoreEnabledAccessibilityServicesLocked(
+                                    intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE),
+                                    intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE));
+                        }
+                    }
                 }
             }
         }, UserHandle.ALL, intentFilter, null, null);
@@ -857,6 +867,21 @@
         }
     }
 
+    // Called only during settings restore; currently supports only the owner user
+    void restoreEnabledAccessibilityServicesLocked(String oldSetting, String newSetting) {
+        readComponentNamesFromStringLocked(oldSetting, mTempComponentNameSet, false);
+        readComponentNamesFromStringLocked(newSetting, mTempComponentNameSet, true);
+
+        UserState userState = getUserStateLocked(UserHandle.USER_OWNER);
+        userState.mEnabledServices.clear();
+        userState.mEnabledServices.addAll(mTempComponentNameSet);
+        persistComponentNamesToSettingLocked(
+                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                userState.mEnabledServices,
+                UserHandle.USER_OWNER);
+        onUserStateChangedLocked(userState);
+    }
+
     private InteractionBridge getInteractionBridgeLocked() {
         if (mInteractionBridge == null) {
             mInteractionBridge = new InteractionBridge();
@@ -1129,10 +1154,27 @@
             Set<ComponentName> outComponentNames) {
         String settingValue = Settings.Secure.getStringForUser(mContext.getContentResolver(),
                 settingName, userId);
-        outComponentNames.clear();
-        if (settingValue != null) {
+        readComponentNamesFromStringLocked(settingValue, outComponentNames, false);
+    }
+
+    /**
+     * Populates a set with the {@link ComponentName}s contained in a colon-delimited string.
+     *
+     * @param names The colon-delimited string to parse.
+     * @param outComponentNames The set of component names to be populated based on
+     *    the contents of the <code>names</code> string.
+     * @param doMerge If true, the parsed component names will be merged into the output
+     *    set, rather than replacing the set's existing contents entirely.
+     */
+    private void readComponentNamesFromStringLocked(String names,
+            Set<ComponentName> outComponentNames,
+            boolean doMerge) {
+        if (!doMerge) {
+            outComponentNames.clear();
+        }
+        if (names != null) {
             TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
-            splitter.setString(settingValue);
+            splitter.setString(names);
             while (splitter.hasNext()) {
                 String str = splitter.next();
                 if (str == null || str.length() <= 0) {
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 4d0868a..9ec886c 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -764,9 +764,11 @@
 
         InputMethodInfo defIm = null;
         for (InputMethodInfo imi : mMethodList) {
-            if (defIm == null) {
-                if (InputMethodUtils.isValidSystemDefaultIme(
-                        mSystemReady, imi, context)) {
+            if (defIm == null && mSystemReady) {
+                final Locale systemLocale = context.getResources().getConfiguration().locale;
+                if (InputMethodUtils.isSystemImeThatHasSubtypeOf(imi, context,
+                        true /* checkDefaultAttribute */, systemLocale, false /* checkCountry */,
+                        InputMethodUtils.SUBTYPE_MODE_ANY)) {
                     defIm = imi;
                     Slog.i(TAG, "Selected default: " + imi.getId());
                 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
index ae4006d..fd4974e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
+++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
@@ -30,10 +30,10 @@
     // will be tagged with their class names instead fot the generic tag.
     static final boolean TAG_WITH_CLASS_NAME = false;
 
-    // While debugging it is sometimes useful to have the category name of the log prepended to the
+    // While debugging it is sometimes useful to have the category name of the log appended to the
     // base log tag to make sifting through logs with the same base tag easier. By setting this
-    // constant to true, the category name of the log point will be prepended to the log tag.
-    static final boolean PREPEND_CATEGORY_NAME = false;
+    // constant to true, the category name of the log point will be appended to the log tag.
+    static final boolean APPEND_CATEGORY_NAME = false;
 
     // Default log tag for the activity manager package.
     static final String TAG_AM = "ActivityManager";
@@ -74,12 +74,17 @@
     static final boolean DEBUG_USER_LEAVING = DEBUG_ALL || false;
     static final boolean DEBUG_VISBILITY = DEBUG_ALL || false;
 
-    static final String POSTFIX_BACKUP = (PREPEND_CATEGORY_NAME) ? "_Backup" : "";
-    static final String POSTFIX_BROADCAST = (PREPEND_CATEGORY_NAME) ? "_Broadcast" : "";
-    static final String POSTFIX_CLEANUP = (PREPEND_CATEGORY_NAME) ? "_Cleanup" : "";
+    static final String POSTFIX_BACKUP = (APPEND_CATEGORY_NAME) ? "_Backup" : "";
+    static final String POSTFIX_BROADCAST = (APPEND_CATEGORY_NAME) ? "_Broadcast" : "";
+    static final String POSTFIX_CLEANUP = (APPEND_CATEGORY_NAME) ? "_Cleanup" : "";
+    static final String POSTFIX_CONFIGURATION = (APPEND_CATEGORY_NAME) ? "_Configuration" : "";
+    static final String POSTFIX_FOCUS = (APPEND_CATEGORY_NAME) ? "_Focus" : "";
+    static final String POSTFIX_IMMERSIVE = (APPEND_CATEGORY_NAME) ? "_Immersive" : "";
+    static final String POSTFIX_LRU = (APPEND_CATEGORY_NAME) ? "_LRU" : "";
     static final String POSTFIX_MU = "_MU";
-    static final String POSTFIX_SERVICE = (PREPEND_CATEGORY_NAME) ? "_Service" : "";
+    static final String POSTFIX_OOM_ADJ = (APPEND_CATEGORY_NAME) ? "_OomAdj" : "";
+    static final String POSTFIX_SERVICE = (APPEND_CATEGORY_NAME) ? "_Service" : "";
     static final String POSTFIX_SERVICE_EXECUTING =
-            (PREPEND_CATEGORY_NAME) ? "_ServiceExecuting" : "";
+            (APPEND_CATEGORY_NAME) ? "_ServiceExecuting" : "";
 
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a366c7b..dcee96a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -254,15 +254,14 @@
     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
+    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
+    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
+    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
+    private static final String TAG_LRU = TAG + POSTFIX_LRU;
     private static final String TAG_MU = TAG + POSTFIX_MU;
+    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
 
     // TODO(ogunwale): Migrate all the constants below to use ActivityManagerDebugConfig class.
-    static final boolean DEBUG_CONFIGURATION = DEBUG_ALL || false;
-    static final boolean DEBUG_FOCUS = false;
-    static final boolean DEBUG_IMMERSIVE = DEBUG_ALL || false;
-    static final boolean DEBUG_MU = DEBUG_ALL || false;
-    static final boolean DEBUG_OOM_ADJ = DEBUG_ALL || false;
-    static final boolean DEBUG_LRU = DEBUG_ALL || false;
     static final boolean DEBUG_PAUSE = DEBUG_ALL || false;
     static final boolean DEBUG_POWER = DEBUG_ALL || false;
     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
@@ -283,8 +282,6 @@
     static final boolean DEBUG_PSS = DEBUG_ALL || false;
     static final boolean DEBUG_LOCKSCREEN = DEBUG_ALL || false;
     static final boolean DEBUG_RECENTS = DEBUG_ALL || false;
-    static final boolean VALIDATE_TOKENS = false;
-    static final boolean SHOW_ACTIVITY_START_TIME = true;
 
     // Control over CPU and battery monitoring.
     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
@@ -1705,10 +1702,9 @@
             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 (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
+                            "Applying new update lock state '" + nextState
+                            + "' for " + (ActivityRecord)msg.obj);
                     if (nextState) {
                         mUpdateLock.acquire();
                     } else {
@@ -2480,15 +2476,15 @@
     }
 
     final void setFocusedActivityLocked(ActivityRecord r, String reason) {
-        if (mFocusedActivity != r) {
-            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
+        if (r != null && mFocusedActivity != r) {
+            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
             mFocusedActivity = r;
             if (r.task != null && r.task.voiceInteractor != null) {
                 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
             } else {
                 finishRunningVoiceLocked();
             }
-            if (r != null && mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
+            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
                 mWindowManager.setFocusedApp(r.appToken, true);
             }
             applyUpdateLockStateLocked(r);
@@ -2505,7 +2501,7 @@
 
     @Override
     public void setFocusedStack(int stackId) {
-        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
+        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
         synchronized (ActivityManagerService.this) {
             ActivityStack stack = mStackSupervisor.getStack(stackId);
             if (stack != null) {
@@ -2587,7 +2583,7 @@
         if (index > 0) {
             index--;
         }
-        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
+        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
                 + " in LRU list: " + app);
         mLruProcesses.add(index, app);
         return index;
@@ -2633,13 +2629,13 @@
         if (hasActivity) {
             final int N = mLruProcesses.size();
             if (N > 0 && mLruProcesses.get(N-1) == app) {
-                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
+                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
                 return;
             }
         } else {
             if (mLruProcessServiceStart > 0
                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
-                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
+                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
                 return;
             }
         }
@@ -2649,7 +2645,7 @@
         if (app.persistent && lrui >= 0) {
             // We don't care about the position of persistent processes, as long as
             // they are in the list.
-            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
+            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
             return;
         }
 
@@ -2718,27 +2714,29 @@
         int nextIndex;
         if (hasActivity) {
             final int N = mLruProcesses.size();
-            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
+            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
                 // Process doesn't have activities, but has clients with
                 // activities...  move it up, but one below the top (the top
                 // should always have a real activity).
-                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
-                mLruProcesses.add(N-1, app);
+                if (DEBUG_LRU) Slog.d(TAG_LRU,
+                        "Adding to second-top of LRU activity list: " + app);
+                mLruProcesses.add(N - 1, app);
                 // To keep it from spamming the LRU list (by making a bunch of clients),
                 // we will push down any other entries owned by the app.
                 final int uid = app.info.uid;
-                for (int i=N-2; i>mLruProcessActivityStart; i--) {
+                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
                     ProcessRecord subProc = mLruProcesses.get(i);
                     if (subProc.info.uid == uid) {
                         // We want to push this one down the list.  If the process after
                         // it is for the same uid, however, don't do so, because we don't
                         // want them internally to be re-ordered.
-                        if (mLruProcesses.get(i-1).info.uid != uid) {
-                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
-                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
+                        if (mLruProcesses.get(i - 1).info.uid != uid) {
+                            if (DEBUG_LRU) Slog.d(TAG_LRU,
+                                    "Pushing uid " + uid + " swapping at " + i + ": "
+                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
                             ProcessRecord tmp = mLruProcesses.get(i);
-                            mLruProcesses.set(i, mLruProcesses.get(i-1));
-                            mLruProcesses.set(i-1, tmp);
+                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
+                            mLruProcesses.set(i - 1, tmp);
                             i--;
                         }
                     } else {
@@ -2748,13 +2746,13 @@
                 }
             } else {
                 // Process has activities, put it at the very tipsy-top.
-                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
+                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
                 mLruProcesses.add(app);
             }
             nextIndex = mLruProcessServiceStart;
         } else if (hasService) {
             // Process has services, put it at the top of the service list.
-            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
+            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
             mLruProcesses.add(mLruProcessActivityStart, app);
             nextIndex = mLruProcessServiceStart;
             mLruProcessActivityStart++;
@@ -2765,7 +2763,7 @@
                 // If there is a client, don't allow the process to be moved up higher
                 // in the list than that client.
                 int clientIndex = mLruProcesses.lastIndexOf(client);
-                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
+                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
                         + " when updating " + app);
                 if (clientIndex <= lrui) {
                     // Don't allow the client index restriction to push it down farther in the
@@ -2776,7 +2774,7 @@
                     index = clientIndex;
                 }
             }
-            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
+            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
             mLruProcesses.add(index, app);
             nextIndex = index-1;
             mLruProcessActivityStart++;
@@ -5599,7 +5597,7 @@
             if (app.instrumentationClass != null) {
                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
             }
-            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
+            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
                     + processName + " with config " + mConfiguration);
             ApplicationInfo appInfo = app.instrumentationInfo != null
                     ? app.instrumentationInfo : app.info;
@@ -6137,8 +6135,7 @@
             int callingUid, int userId, IBinder token, String resultWho,
             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
             Bundle options) {
-        if (DEBUG_MU)
-            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
+        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
         ActivityRecord activity = null;
         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
             activity = ActivityRecord.isInStackLocked(token);
@@ -8616,8 +8613,8 @@
                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
         } catch (RemoteException ex) {
         }
-        if (DEBUG_MU)
-            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
+        if (DEBUG_MU) Slog.v(TAG_MU,
+                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
         int userId = app.userId;
         if (providers != null) {
             int N = providers.size();
@@ -8644,8 +8641,8 @@
                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
                     mProviderMap.putProviderByClass(comp, cpr);
                 }
-                if (DEBUG_MU)
-                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
+                if (DEBUG_MU) Slog.v(TAG_MU,
+                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
                 app.pubProviders.put(cpi.name, cpr);
                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
                     // Don't add this if it is a platform component that is marked
@@ -9174,10 +9171,9 @@
                     return null;
                 }
                 try {
-                    if (DEBUG_MU) {
-                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
-                                + cpr.launchingApp);
-                    }
+                    if (DEBUG_MU) Slog.v(TAG_MU,
+                            "Waiting to start provider " + cpr
+                            + " launchingApp=" + cpr.launchingApp);
                     if (conn != null) {
                         conn.waiting = true;
                     }
@@ -9299,8 +9295,7 @@
         enforceNotIsolatedCaller("publishContentProviders");
         synchronized (this) {
             final ProcessRecord r = getRecordForAppLocked(caller);
-            if (DEBUG_MU)
-                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
+            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
             if (r == null) {
                 throw new SecurityException(
                         "Unable to find app for caller " + caller
@@ -9317,8 +9312,7 @@
                     continue;
                 }
                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
-                if (DEBUG_MU)
-                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
+                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
                 if (dst != null) {
                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
                     mProviderMap.putProviderByClass(comp, dst);
@@ -10400,9 +10394,7 @@
 
             // update associated state if we're frontmost
             if (r == mFocusedActivity) {
-                if (DEBUG_IMMERSIVE) {
-                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
-                }
+                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
                 applyUpdateLockStateLocked(r);
             }
         }
@@ -10751,7 +10743,8 @@
             // This happens before any activities are started, so we can
             // change mConfiguration in-place.
             updateConfigurationLocked(configuration, null, false, true);
-            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
+            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
+                    "Initial config: " + mConfiguration);
         }
     }
 
@@ -15094,10 +15087,9 @@
             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
         }
-        if (DEBUG_MU) {
-            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
-                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
-        }
+        if (DEBUG_MU) Slog.v(TAG_MU,
+                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
+                + Integer.toHexString(flags) + ") = " + result);
         return result;
     }
 
@@ -16484,9 +16476,8 @@
             Configuration newConfig = new Configuration(mConfiguration);
             changes = newConfig.updateFrom(values);
             if (changes != 0) {
-                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
-                    Slog.i(TAG, "Updating configuration to: " + values);
-                }
+                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
+                        "Updating configuration to: " + values);
 
                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
 
@@ -16537,7 +16528,7 @@
                     ProcessRecord app = mLruProcesses.get(i);
                     try {
                         if (app.thread != null) {
-                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
+                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
                                     + app.processName + " new config " + mConfiguration);
                             app.thread.scheduleConfigurationChanged(configCopy);
                         }
@@ -17740,15 +17731,15 @@
 
         if (app.curAdj != app.setAdj) {
             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
-            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
-                TAG, "Set " + app.pid + " " + app.processName +
-                " adj " + app.curAdj + ": " + app.adjType);
+            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
+                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
+                    + app.adjType);
             app.setAdj = app.curAdj;
         }
 
         if (app.setSchedGroup != app.curSchedGroup) {
             app.setSchedGroup = app.curSchedGroup;
-            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
                     "Setting process group of " + app.processName
                     + " to " + app.curSchedGroup);
             if (app.waitingToKill != null &&
@@ -17832,7 +17823,7 @@
             }
         }
         if (app.setProcState != app.curProcState) {
-            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
                     "Proc state change of " + app.processName
                     + " to " + app.curProcState);
             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
@@ -18097,7 +18088,7 @@
                             // step that cached level.
                             app.curRawAdj = curCachedAdj;
                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
-                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
+                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
                                     + ")");
                             if (curCachedAdj != nextCachedAdj) {
@@ -18120,7 +18111,7 @@
                             // state is still as a service), which is what we want.
                             app.curRawAdj = curEmptyAdj;
                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
-                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
+                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
                                     + ")");
                             if (curEmptyAdj != nextEmptyAdj) {
@@ -18210,13 +18201,13 @@
         // We always allow the memory level to go up (better).  We only allow it to go
         // down if we are in a state where that is allowed, *and* the total number of processes
         // has gone down since last time.
-        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
-                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
-                + " last=" + mLastNumProcesses);
+        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
+                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
+                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
         if (memFactor > mLastMemoryLevel) {
             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
                 memFactor = mLastMemoryLevel;
-                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
+                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
             }
         }
         mLastMemoryLevel = memFactor;
@@ -18256,9 +18247,8 @@
                         && !app.killedByAm) {
                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
                         try {
-                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
-                                    "Trimming memory of " + app.processName
-                                    + " to " + curLevel);
+                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
+                                    "Trimming memory of " + app.processName + " to " + curLevel);
                             app.thread.scheduleTrimMemory(curLevel);
                         } catch (RemoteException e) {
                         }
@@ -18293,7 +18283,7 @@
                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
                             && app.thread != null) {
                         try {
-                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
                                     "Trimming memory of heavy-weight " + app.processName
                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
                             app.thread.scheduleTrimMemory(
@@ -18311,7 +18301,7 @@
                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
                         if (app.trimMemoryLevel < level && app.thread != null) {
                             try {
-                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
                                         "Trimming memory of bg-ui " + app.processName
                                         + " to " + level);
                                 app.thread.scheduleTrimMemory(level);
@@ -18322,7 +18312,7 @@
                     }
                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
                         try {
-                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
                                     "Trimming memory of fg " + app.processName
                                     + " to " + fgTrimLevel);
                             app.thread.scheduleTrimMemory(fgTrimLevel);
@@ -18348,7 +18338,7 @@
                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
                             && app.thread != null) {
                         try {
-                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
                                     "Trimming memory of ui hidden " + app.processName
                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
                             app.thread.scheduleTrimMemory(
@@ -18383,12 +18373,12 @@
         }
 
         if (DEBUG_OOM_ADJ) {
+            final long duration = SystemClock.uptimeMillis() - now;
             if (false) {
-                RuntimeException here = new RuntimeException("here");
-                here.fillInStackTrace();
-                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
+                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
+                        new RuntimeException("here").fillInStackTrace());
             } else {
-                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
+                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index ca2721c..d34b33b 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -76,6 +76,7 @@
 final class ActivityRecord {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_AM;
 
+    private static final boolean SHOW_ACTIVITY_START_TIME = true;
     static final boolean DEBUG_SAVED_STATE = ActivityStackSupervisor.DEBUG_SAVED_STATE;
     final public static String RECENTS_PACKAGE_NAME = "com.android.systemui.recents";
 
@@ -939,7 +940,7 @@
             final long thisTime = curTime - fullyDrawnStartTime;
             final long totalTime = stack.mFullyDrawnStartTime != 0
                     ? (curTime - stack.mFullyDrawnStartTime) : thisTime;
-            if (ActivityManagerService.SHOW_ACTIVITY_START_TIME) {
+            if (SHOW_ACTIVITY_START_TIME) {
                 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
                 EventLog.writeEvent(EventLogTags.AM_ACTIVITY_FULLY_DRAWN_TIME,
                         userId, System.identityHashCode(this), shortComponentName,
@@ -973,7 +974,7 @@
         final long thisTime = curTime - displayStartTime;
         final long totalTime = stack.mLaunchStartTime != 0
                 ? (curTime - stack.mLaunchStartTime) : thisTime;
-        if (ActivityManagerService.SHOW_ACTIVITY_START_TIME) {
+        if (SHOW_ACTIVITY_START_TIME) {
             Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching", 0);
             EventLog.writeEvent(EventLogTags.AM_ACTIVITY_LAUNCH_TIME,
                     userId, System.identityHashCode(this), shortComponentName,
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 456ed33..4bb265d 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -17,7 +17,6 @@
 package com.android.server.am;
 
 import static com.android.server.am.ActivityManagerDebugConfig.*;
-import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
 import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
 import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
 import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
@@ -26,7 +25,6 @@
 import static com.android.server.am.ActivityManagerService.DEBUG_TRANSITION;
 import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
 import static com.android.server.am.ActivityManagerService.DEBUG_VISBILITY;
-import static com.android.server.am.ActivityManagerService.VALIDATE_TOKENS;
 
 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
@@ -97,6 +95,9 @@
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_AM;
     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
+    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
+
+    private static final boolean VALIDATE_TOKENS = false;
 
     // Ticks during which we check progress while waiting for an app to launch.
     static final int LAUNCH_TICK = 500;
@@ -507,6 +508,8 @@
                 mStacks.remove(this);
                 mStacks.add(this);
             }
+            // TODO(multi-display): Focus stack currently adjusted in call to move home stack.
+            // Needs to also work if focus is moving to the non-home display.
             if (isOnHomeDisplay()) {
                 mStackSupervisor.moveHomeStack(homeStack, reason, lastFocusStack);
             }
@@ -2573,7 +2576,11 @@
                     }
                     // Move the home stack to the top if this stack is fullscreen or there is no
                     // other visible stack.
-                    mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), myReason);
+                    if (mStackSupervisor.moveHomeStackTaskToTop(
+                            task.getTaskToReturnTo(), myReason)) {
+                        // Activity focus was already adjusted. Nothing else to do...
+                        return;
+                    }
                 }
             }
 
@@ -3575,7 +3582,6 @@
                 mTaskHistory.remove(taskNdx);
                 mTaskHistory.add(top, task);
                 updateTaskMovement(task, true);
-                mWindowManager.moveTaskToTop(task.taskId);
                 return;
             }
         }
@@ -3600,12 +3606,14 @@
         // Shift all activities with this task up to the top
         // of the stack, keeping them in the same internal order.
         insertTaskAtTop(tr);
-        moveToFront(reason);
+
+        // Set focus to the top running activity of this stack.
+        ActivityRecord r = topRunningActivityLocked(null);
+        mService.setFocusedActivityLocked(r, reason);
 
         if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to front transition: task=" + tr);
         if (noAnimation) {
             mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
-            ActivityRecord r = topRunningActivityLocked(null);
             if (r != null) {
                 mNoAnimActivities.add(r);
             }
@@ -3740,12 +3748,12 @@
     final boolean ensureActivityConfigurationLocked(ActivityRecord r,
             int globalChanges) {
         if (mConfigWillChange) {
-            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                     "Skipping config check (will change): " + r);
             return true;
         }
 
-        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                 "Ensuring correct configuration: " + r);
 
         // Make sure the current stack override configuration is supported by the top task
@@ -3758,7 +3766,7 @@
                     mWindowManager.forceStackToFullscreen(mStackId, !topTask.mResizeable);
             updateOverrideConfiguration(newOverrideConfig);
             mForcedFullscreen = !prevFullscreen && mFullscreen;
-            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                     "Updated stack config to support task=" + topTask
                             + " resizeable=" + topTask.mResizeable
                             + " mForcedFullscreen=" + mForcedFullscreen
@@ -3772,14 +3780,14 @@
         if (r.configuration == newConfig
                 && r.stackConfigOverride == mOverrideConfig
                 && !r.forceNewConfig) {
-            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                     "Configuration unchanged in " + r);
             return true;
         }
 
         // We don't worry about activities that are finishing.
         if (r.finishing) {
-            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                     "Configuration doesn't matter in finishing " + r);
             r.stopFreezingScreenLocked(false);
             return true;
@@ -3813,7 +3821,7 @@
         }
         final int changes = oldConfig.diff(newConfig) | stackChanges;
         if (changes == 0 && !r.forceNewConfig) {
-            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                     "Configuration no differences in " + r);
             return true;
         }
@@ -3821,7 +3829,7 @@
         // If the activity isn't currently running, just leave the new
         // configuration and it will pick that up next time it starts.
         if (r.app == null || r.app.thread == null) {
-            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                     "Configuration doesn't matter not running " + r);
             r.stopFreezingScreenLocked(false);
             r.forceNewConfig = false;
@@ -3829,26 +3837,25 @@
         }
 
         // Figure out how to handle the changes between the configurations.
-        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
-            Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
-                    + Integer.toHexString(changes) + ", handles=0x"
-                    + Integer.toHexString(r.info.getRealConfigChanged())
-                    + ", newConfig=" + newConfig);
-        }
+        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
+                "Checking to restart " + r.info.name + ": changed=0x"
+                + Integer.toHexString(changes) + ", handles=0x"
+                + Integer.toHexString(r.info.getRealConfigChanged()) + ", newConfig=" + newConfig);
+
         if ((changes&(~r.info.getRealConfigChanged())) != 0 || r.forceNewConfig) {
             // Aha, the activity isn't handling the change, so DIE DIE DIE.
             r.configChangeFlags |= changes;
             r.startFreezingScreenLocked(r.app, globalChanges);
             r.forceNewConfig = false;
             if (r.app == null || r.app.thread == null) {
-                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                         "Config is destroying non-running " + r);
                 destroyActivityLocked(r, true, "config");
             } else if (r.state == ActivityState.PAUSING) {
                 // A little annoying: we are waiting for this activity to
                 // finish pausing.  Let's not do anything now, but just
                 // flag that it needs to be restarted when done pausing.
-                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                         "Config is skipping already pausing " + r);
                 r.configDestroy = true;
                 return true;
@@ -3857,12 +3864,12 @@
                 // and we need to restart the top, resumed activity.
                 // Instead of doing the normal handshaking, just say
                 // "restart!".
-                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                         "Config is relaunching resumed " + r);
                 relaunchActivityLocked(r, r.configChangeFlags, true);
                 r.configChangeFlags = 0;
             } else {
-                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                         "Config is relaunching non-resumed " + r);
                 relaunchActivityLocked(r, r.configChangeFlags, false);
                 r.configChangeFlags = 0;
@@ -3879,7 +3886,7 @@
         // system level configuration it last got.
         if (r.app != null && r.app.thread != null) {
             try {
-                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + r);
+                if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending new config to " + r);
                 r.app.thread.scheduleActivityConfigurationChanged(
                         r.appToken, new Configuration(mOverrideConfig));
             } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f56f65f..4bab4fd 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -17,12 +17,12 @@
 package com.android.server.am;
 
 import static android.Manifest.permission.START_ANY_ACTIVITY;
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static com.android.server.am.ActivityManagerDebugConfig.*;
-import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
-import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
 import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
 import static com.android.server.am.ActivityManagerService.DEBUG_RECENTS;
 import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
@@ -117,6 +117,8 @@
 
 public final class ActivityStackSupervisor implements DisplayListener {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
+    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
+    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
 
     static final boolean DEBUG = DEBUG_ALL || false;
     static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
@@ -441,13 +443,21 @@
         }
     }
 
-    void moveHomeStackTaskToTop(int homeStackTaskType, String reason) {
+    /** Returns true if the focus activity was adjusted to the home stack top activity. */
+    boolean moveHomeStackTaskToTop(int homeStackTaskType, String reason) {
         if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
             mWindowManager.showRecentApps();
-            return;
+            return false;
         }
-        moveHomeStack(true, reason);
+
         mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
+
+        final ActivityRecord top = mHomeStack.topRunningActivityLocked(null);
+        if (top == null) {
+            return false;
+        }
+        mService.setFocusedActivityLocked(top, reason);
+        return true;
     }
 
     boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) {
@@ -460,14 +470,13 @@
             mWindowManager.showRecentApps();
             return false;
         }
-        moveHomeStackTaskToTop(homeStackTaskType, reason);
+
         if (prev != null) {
             prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
         }
 
         ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
-        // if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) {
-        if (r != null && r.isHomeActivity()) {
+        if (r != null) {
             mService.setFocusedActivityLocked(r, reason);
             return resumeTopActivitiesLocked(mHomeStack, prev, null);
         }
@@ -908,7 +917,7 @@
                 stack = container.mStack;
             }
             stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
-            if (DEBUG_CONFIGURATION) Slog.v(TAG,
+            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                     "Starting activity when config will change = " + stack.mConfigWillChange);
 
             final long origId = Binder.clearCallingIdentity();
@@ -998,7 +1007,7 @@
                 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
                         "updateConfiguration()");
                 stack.mConfigWillChange = false;
-                if (DEBUG_CONFIGURATION) Slog.v(TAG,
+                if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                         "Updating to new configuration after starting activity.");
                 mService.updateConfigurationLocked(config, null, false, false);
             }
@@ -1575,10 +1584,11 @@
                 stack = task.stack;
                 if (stack.isOnHomeDisplay()) {
                     if (mFocusedStack != stack) {
-                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "computeStackFocus: Setting " +
-                                "focused stack to r=" + r + " task=" + task);
+                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
+                                "computeStackFocus: Setting " + "focused stack to r=" + r
+                                + " task=" + task);
                     } else {
-                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
+                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
                             "computeStackFocus: Focused stack already=" + mFocusedStack);
                     }
                 }
@@ -1594,7 +1604,7 @@
 
             if (mFocusedStack != mHomeStack && (!newTask ||
                     mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
-                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
+                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
                         "computeStackFocus: Have a focused stack=" + mFocusedStack);
                 return mFocusedStack;
             }
@@ -1603,7 +1613,7 @@
             for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
                 stack = homeDisplayStacks.get(stackNdx);
                 if (!stack.isHomeStack()) {
-                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
+                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
                             "computeStackFocus: Setting focused stack=" + stack);
                     return stack;
                 }
@@ -1611,8 +1621,8 @@
 
             // Need to create an app stack for this user.
             stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
-            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "computeStackFocus: New stack r=" + r +
-                    " stackId=" + stack.mStackId);
+            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
+                    + r + " stackId=" + stack.mStackId);
             return stack;
         }
         return mHomeStack;
@@ -1874,11 +1884,6 @@
                     if (r.task == null) {
                         r.task = intentActivity.task;
                     }
-                    targetStack = intentActivity.task.stack;
-                    targetStack.mLastPausedActivity = null;
-                    if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
-                            + " from " + intentActivity);
-                    targetStack.moveToFront("intentActivityFound");
                     if (intentActivity.task.intent == null) {
                         // This task was started because of movement of
                         // the activity based on affinity...  now that we
@@ -1886,29 +1891,31 @@
                         // base intent.
                         intentActivity.task.setIntent(r);
                     }
+                    targetStack = intentActivity.task.stack;
+                    targetStack.mLastPausedActivity = null;
                     // If the target task is not in the front, then we need
                     // to bring it to the front...  except...  well, with
                     // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
                     // to have the same behavior as if a new instance was
                     // being started, which means not bringing it to the front
                     // if the caller is not itself in the front.
-                    final ActivityStack lastStack = getLastStack();
-                    ActivityRecord curTop = lastStack == null?
-                            null : lastStack.topRunningNonDelayedActivityLocked(notTop);
+                    final ActivityStack focusStack = getFocusedStack();
+                    ActivityRecord curTop = (focusStack == null)
+                            ? null : focusStack.topRunningNonDelayedActivityLocked(notTop);
                     boolean movedToFront = false;
                     if (curTop != null && (curTop.task != intentActivity.task ||
-                            curTop.task != lastStack.topTask())) {
+                            curTop.task != focusStack.topTask())) {
                         r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
                         if (sourceRecord == null || (sourceStack.topActivity() != null &&
                                 sourceStack.topActivity().task == sourceRecord.task)) {
-                            // We really do want to push this one into the
-                            // user's face, right now.
+                            // We really do want to push this one into the user's face, right now.
                             if (launchTaskBehind && sourceRecord != null) {
                                 intentActivity.setTaskToAffiliateWith(sourceRecord.task);
                             }
                             movedHome = true;
                             targetStack.moveTaskToFrontLocked(intentActivity.task, noAnimation,
                                     options, "bringingFoundTaskToFront");
+                            movedToFront = true;
                             if ((launchFlags &
                                     (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
                                     == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
@@ -1916,9 +1923,14 @@
                                 intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
                             }
                             options = null;
-                            movedToFront = true;
                         }
                     }
+                    if (!movedToFront) {
+                        if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
+                                + " from " + intentActivity);
+                        targetStack.moveToFront("intentActivityFound");
+                    }
+
                     // If the caller has requested that the target task be
                     // reset, then do so.
                     if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
@@ -1943,15 +1955,15 @@
                         return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                     }
                     if ((launchFlags &
-                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
-                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
+                            (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
+                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
                         // The caller has requested to completely replace any
                         // existing task with its new activity.  Well that should
                         // not be too hard...
                         reuseTask = intentActivity.task;
                         reuseTask.performClearTaskLocked();
                         reuseTask.setIntent(r);
-                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
+                    } else if ((launchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                             || launchSingleInstance || launchSingleTask) {
                         // In this situation we want to remove all activities
                         // from the task up to the one being started.  In most
@@ -2120,8 +2132,8 @@
             }
             if (!movedHome) {
                 if ((launchFlags &
-                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
-                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
+                        (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
+                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
                     // Caller wants to appear on home activity, so before starting
                     // their own activity we will bring home to the front.
                     r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
diff --git a/services/core/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java
index ce63d75..0fe9231 100644
--- a/services/core/java/com/android/server/am/CompatModePackages.java
+++ b/services/core/java/com/android/server/am/CompatModePackages.java
@@ -46,7 +46,7 @@
 
 public final class CompatModePackages {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "CompatModePackages" : TAG_AM;
-    private final boolean DEBUG_CONFIGURATION = ActivityManagerService.DEBUG_CONFIGURATION;
+    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
 
     private final ActivityManagerService mService;
     private final AtomicFile mFile;
@@ -334,7 +334,7 @@
                 }
                 try {
                     if (app.thread != null) {
-                        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
+                        if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
                                 + app.processName + " new compat " + ci);
                         app.thread.updatePackageCompatibilityInfo(packageName, ci);
                     }
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index fcdd9d9..f05e6aa 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -653,6 +653,7 @@
                 return;
             } else {
                 mFocusFollowers.add(ff);
+                notifyExtPolicyCurrentFocusAsync(ff);
             }
         }
     }
@@ -672,6 +673,32 @@
     }
 
     /**
+     * @param pcb non null
+     */
+    void notifyExtPolicyCurrentFocusAsync(IAudioPolicyCallback pcb) {
+        final IAudioPolicyCallback pcb2 = pcb;
+        final Thread thread = new Thread() {
+            @Override
+            public void run() {
+                synchronized(mAudioFocusLock) {
+                    if (mFocusStack.isEmpty()) {
+                        return;
+                    }
+                    try {
+                        pcb2.notifyAudioFocusGrant(mFocusStack.peek().toAudioFocusInfo(),
+                                // top of focus stack always has focus
+                                AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Can't call notifyAudioFocusGrant() on IAudioPolicyCallback "
+                                + pcb2.asBinder(), e);
+                    }
+                }
+            }
+        };
+        thread.start();
+    }
+
+    /**
      * Called synchronized on mAudioFocusLock
      */
     void notifyExtPolicyFocusGrant_syncAf(AudioFocusInfo afi, int requestResult) {
@@ -680,7 +707,7 @@
                 // oneway
                 pcb.notifyAudioFocusGrant(afi, requestResult);
             } catch (RemoteException e) {
-                Log.e(TAG, "Can't call newAudioFocusLoser() on IAudioPolicyCallback "
+                Log.e(TAG, "Can't call notifyAudioFocusGrant() on IAudioPolicyCallback "
                         + pcb.asBinder(), e);
             }
         }
@@ -695,7 +722,7 @@
                 // oneway
                 pcb.notifyAudioFocusLoss(afi, wasDispatched);
             } catch (RemoteException e) {
-                Log.e(TAG, "Can't call newAudioFocusLoser() on IAudioPolicyCallback "
+                Log.e(TAG, "Can't call notifyAudioFocusLoss() on IAudioPolicyCallback "
                         + pcb.asBinder(), e);
             }
         }
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 0c7d71b..9ccb2ea 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -18,10 +18,12 @@
 
 import android.app.ActivityManager;
 import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -51,6 +53,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -74,6 +77,7 @@
     private final UserProfiles mUserProfiles;
     private final SettingsObserver mSettingsObserver;
     private final Config mConfig;
+    private ArraySet<String> mRestored;
 
     // contains connections to all connected services, including app services
     // and system services
@@ -91,6 +95,8 @@
     // user change).
     private int[] mLastSeenProfileIds;
 
+    private final BroadcastReceiver mRestoreReceiver;
+
     public ManagedServices(Context context, Handler handler, Object mutex,
             UserProfiles userProfiles) {
         mContext = context;
@@ -98,6 +104,24 @@
         mUserProfiles = userProfiles;
         mConfig = getConfig();
         mSettingsObserver = new SettingsObserver(handler);
+
+        mRestoreReceiver = new SettingRestoredReceiver();
+        IntentFilter filter = new IntentFilter(Intent.ACTION_SETTING_RESTORED);
+        context.registerReceiver(mRestoreReceiver, filter);
+    }
+
+    class SettingRestoredReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_SETTING_RESTORED.equals(intent.getAction())) {
+                String element = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
+                if (Objects.equals(element, mConfig.secureSettingName)) {
+                    String prevValue = intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE);
+                    String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE);
+                    settingRestored(element, prevValue, newValue, getSendingUserId());
+                }
+            }
+        }
     }
 
     abstract protected Config getConfig();
@@ -140,6 +164,31 @@
         }
     }
 
+    // By convention, restored settings are replicated to another settings
+    // entry, named similarly but with a disambiguation suffix.
+    public static final String restoredSettingName(Config config) {
+        return config.secureSettingName + ":restored";
+    }
+
+    // The OS has done a restore of this service's saved state.  We clone it to the
+    // 'restored' reserve, and then once we return and the actual write to settings is
+    // performed, our observer will do the work of maintaining the restored vs live
+    // settings data.
+    public void settingRestored(String element, String oldValue, String newValue, int userid) {
+        if (DEBUG) Slog.d(TAG, "Restored managed service setting: " + element
+                + " ovalue=" + oldValue + " nvalue=" + newValue);
+        if (mConfig.secureSettingName.equals(element)) {
+            if (element != null) {
+                mRestored = null;
+                Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                        restoredSettingName(mConfig),
+                        newValue,
+                        userid);
+                disableNonexistentServices(userid);
+            }
+        }
+    }
+
     public void onPackagesChanged(boolean queryReplace, String[] pkgList) {
         if (DEBUG) Slog.d(TAG, "onPackagesChanged queryReplace=" + queryReplace
                 + " pkgList=" + (pkgList == null ? null : Arrays.asList(pkgList))
@@ -211,8 +260,23 @@
     }
 
     private void disableNonexistentServices(int userId) {
+        final ContentResolver cr = mContext.getContentResolver();
+        boolean restoredChanged = false;
+        if (mRestored == null) {
+            String restoredSetting = Settings.Secure.getStringForUser(
+                    cr,
+                    restoredSettingName(mConfig),
+                    userId);
+            if (!TextUtils.isEmpty(restoredSetting)) {
+                if (DEBUG) Slog.d(TAG, "restored: " + restoredSetting);
+                String[] restored = restoredSetting.split(ENABLED_SERVICES_SEPARATOR);
+                mRestored = new ArraySet<String>(Arrays.asList(restored));
+            } else {
+                mRestored = new ArraySet<String>();
+            }
+        }
         String flatIn = Settings.Secure.getStringForUser(
-                mContext.getContentResolver(),
+                cr,
                 mConfig.secureSettingName,
                 userId);
         if (!TextUtils.isEmpty(flatIn)) {
@@ -228,14 +292,16 @@
                 ResolveInfo resolveInfo = installedServices.get(i);
                 ServiceInfo info = resolveInfo.serviceInfo;
 
+                ComponentName component = new ComponentName(info.packageName, info.name);
                 if (!mConfig.bindPermission.equals(info.permission)) {
                     Slog.w(TAG, "Skipping " + getCaption() + " service "
                             + info.packageName + "/" + info.name
                             + ": it does not require the permission "
                             + mConfig.bindPermission);
+                    restoredChanged |= mRestored.remove(component.flattenToString());
                     continue;
                 }
-                installed.add(new ComponentName(info.packageName, info.name));
+                installed.add(component);
             }
 
             String flatOut = "";
@@ -246,16 +312,27 @@
                     ComponentName enabledComponent = ComponentName.unflattenFromString(enabled[i]);
                     if (installed.contains(enabledComponent)) {
                         remaining.add(enabled[i]);
+                        restoredChanged |= mRestored.remove(enabled[i]);
                     }
                 }
+                remaining.addAll(mRestored);
                 flatOut = TextUtils.join(ENABLED_SERVICES_SEPARATOR, remaining);
             }
             if (DEBUG) Slog.v(TAG, "flat after: " + flatOut);
             if (!flatIn.equals(flatOut)) {
-                Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                Settings.Secure.putStringForUser(cr,
                         mConfig.secureSettingName,
                         flatOut, userId);
             }
+            if (restoredChanged) {
+                if (DEBUG) Slog.d(TAG, "restored changed; rewriting");
+                final String flatRestored = TextUtils.join(ENABLED_SERVICES_SEPARATOR,
+                        mRestored.toArray());
+                Settings.Secure.putStringForUser(cr,
+                        restoredSettingName(mConfig),
+                        flatRestored,
+                        userId);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index b789d41..dfac6cf 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -176,6 +176,9 @@
     static final int DOUBLE_TAP_HOME_NOTHING = 0;
     static final int DOUBLE_TAP_HOME_RECENT_SYSTEM_UI = 1;
 
+    static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP = 0;
+    static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME = 1;
+
     static final int APPLICATION_MEDIA_SUBLAYER = -2;
     static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
     static final int APPLICATION_PANEL_SUBLAYER = 1;
@@ -371,6 +374,7 @@
     int mLongPressOnPowerBehavior;
     int mDoublePressOnPowerBehavior;
     int mTriplePressOnPowerBehavior;
+    int mShortPressOnSleepBehavior;
     boolean mAwake;
     boolean mScreenOnEarly;
     boolean mScreenOnFully;
@@ -1057,6 +1061,20 @@
         }
     }
 
+    private void sleepPress(KeyEvent event) {
+        switch (mShortPressOnSleepBehavior) {
+            case SHORT_PRESS_SLEEP_GO_TO_SLEEP:
+                mPowerManager.goToSleep(event.getEventTime(),
+                        PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
+                break;
+            case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME:
+                launchHomeFromHotKey(false /* awakenDreams */);
+                mPowerManager.goToSleep(event.getEventTime(),
+                        PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
+                break;
+        }
+    }
+
     private int getResolvedLongPressOnPowerBehavior() {
         if (FactoryTest.isLongPressOnPowerOffEnabled()) {
             return LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
@@ -1321,6 +1339,8 @@
                 com.android.internal.R.integer.config_doublePressOnPowerBehavior);
         mTriplePressOnPowerBehavior = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_triplePressOnPowerBehavior);
+        mShortPressOnSleepBehavior = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_shortPressOnSleepBehavior);
 
         mUseTvRouting = AudioSystem.getPlatformType(mContext) == AudioSystem.PLATFORM_TELEVISION;
 
@@ -3028,11 +3048,15 @@
         }
     }
 
+    void launchHomeFromHotKey() {
+        launchHomeFromHotKey(true /* awakenFromDreams */);
+    }
+
     /**
      * A home key -> launch home action was detected.  Take the appropriate action
      * given the situation with the keyguard.
      */
-    void launchHomeFromHotKey() {
+    void launchHomeFromHotKey(final boolean awakenFromDreams) {
         if (isKeyguardShowingAndNotOccluded()) {
             // don't launch home if keyguard showing
         } else if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) {
@@ -3047,7 +3071,7 @@
                         } catch (RemoteException e) {
                         }
                         sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
-                        startDockOrHome(true /*fromHomeKey*/);
+                        startDockOrHome(true /*fromHomeKey*/, awakenFromDreams);
                     }
                 }
             });
@@ -3059,13 +3083,15 @@
             }
             if (mRecentsVisible) {
                 // Hide Recents and notify it to launch Home
-                awakenDreams();
+                if (awakenFromDreams) {
+                    awakenDreams();
+                }
                 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
                 hideRecentApps(false, true);
             } else {
                 // Otherwise, just launch Home
                 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
-                startDockOrHome(true /*fromHomeKey*/);
+                startDockOrHome(true /*fromHomeKey*/, awakenFromDreams);
             }
         }
     }
@@ -4712,12 +4738,11 @@
 
             case KeyEvent.KEYCODE_SLEEP: {
                 result &= ~ACTION_PASS_TO_USER;
+                isWakeKey = false;
                 if (!mPowerManager.isInteractive()) {
                     useHapticFeedback = false; // suppress feedback if already non-interactive
                 }
-                mPowerManager.goToSleep(event.getEventTime(),
-                        PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
-                isWakeKey = false;
+                sleepPress(event);
                 break;
             }
 
@@ -5897,8 +5922,10 @@
         return null;
     }
 
-    void startDockOrHome(boolean fromHomeKey) {
-        awakenDreams();
+    void startDockOrHome(boolean fromHomeKey, boolean awakenFromDreams) {
+        if (awakenFromDreams) {
+            awakenDreams();
+        }
 
         Intent dock = createHomeDockIntent();
         if (dock != null) {
@@ -5936,7 +5963,7 @@
             } catch (RemoteException e) {
             }
             sendCloseSystemWindows();
-            startDockOrHome(false /*fromHomeKey*/);
+            startDockOrHome(false /*fromHomeKey*/, true /* awakenFromDreams */);
         } else {
             // This code brings home to the front or, if it is already
             // at the front, puts the device to sleep.
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 66c2f5f..9e373b7 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1080,6 +1080,9 @@
                 case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON:
                     Slog.i(TAG, "Going to sleep due to power button (uid " + uid +")...");
                     break;
+                case PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON:
+                    Slog.i(TAG, "Going to sleep due to sleep button (uid " + uid +")...");
+                    break;
                 case PowerManager.GO_TO_SLEEP_REASON_HDMI:
                     Slog.i(TAG, "Going to sleep due to HDMI standby (uid " + uid +")...");
                     break;
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
index 8192b5f..4acbd1c 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
@@ -39,6 +39,8 @@
 
 import java.io.File;
 
+import static com.android.layoutlib.bridge.android.BridgeContext.getBaseContext;
+
 /**
  * Custom implementation of {@link LayoutInflater} to handle custom views.
  */
@@ -60,7 +62,12 @@
 
     protected BridgeInflater(LayoutInflater original, Context newContext) {
         super(original, newContext);
-        mProjectCallback = null;
+        newContext = getBaseContext(newContext);
+        if (newContext instanceof BridgeContext) {
+            mProjectCallback = ((BridgeContext) newContext).getProjectCallback();
+        } else {
+            mProjectCallback = null;
+        }
     }
 
     /**
@@ -154,9 +161,7 @@
     @Override
     public View inflate(int resource, ViewGroup root) {
         Context context = getContext();
-        while (context instanceof ContextThemeWrapper) {
-            context = ((ContextThemeWrapper) context).getBaseContext();
-        }
+        context = getBaseContext(context);
         if (context instanceof BridgeContext) {
             BridgeContext bridgeContext = (BridgeContext)context;
 
@@ -219,9 +224,7 @@
 
     private void setupViewInContext(View view, AttributeSet attrs) {
         Context context = getContext();
-        while (context instanceof ContextThemeWrapper) {
-            context = ((ContextThemeWrapper) context).getBaseContext();
-        }
+        context = getBaseContext(context);
         if (context instanceof BridgeContext) {
             BridgeContext bc = (BridgeContext) context;
             // get the view key
diff --git a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
index dafc96b..08a97d6 100644
--- a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
@@ -48,9 +48,7 @@
             AttributeSet attrs) {
         if (menuItem instanceof BridgeMenuItemImpl) {
             Context context = thisInflater.getContext();
-            while (context instanceof ContextThemeWrapper) {
-                context = ((ContextThemeWrapper) context).getBaseContext();
-            }
+            context = BridgeContext.getBaseContext(context);
             if (context instanceof BridgeContext) {
                 Object viewKey = BridgeInflater.getViewKeyFromParser(
                         attrs, ((BridgeContext) context), null, false);
diff --git a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
index 3915046..82ae1df 100644
--- a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
@@ -122,9 +122,7 @@
     @NonNull
     private static DisplayMetrics getMetrics(View view) {
         Context context = view.getContext();
-        while (context instanceof ContextThemeWrapper) {
-            context = ((ContextThemeWrapper) context).getBaseContext();
-        }
+        context = BridgeContext.getBaseContext(context);
         if (context instanceof BridgeContext) {
             return ((BridgeContext) context).getMetrics();
         }
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java b/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
index 8d1d0c1..bb95c4e 100644
--- a/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
@@ -19,7 +19,6 @@
 import com.android.layoutlib.bridge.android.BridgeContext;
 
 import android.content.Context;
-import android.view.ContextThemeWrapper;
 import android.view.View;
 
 /**
@@ -42,9 +41,7 @@
             CharSequence title, int showAsAction) {
         super(menu, group, id, categoryOrder, ordering, title, showAsAction);
         Context context = menu.getContext();
-        while (context instanceof ContextThemeWrapper) {
-            context = ((ContextThemeWrapper) context).getBaseContext();
-        }
+        context = BridgeContext.getBaseContext(context);
         if (context instanceof BridgeContext) {
             mContext = ((BridgeContext) context);
         }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 179a8e7..e1c58fd 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -40,6 +40,7 @@
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.IntentSender;
@@ -963,6 +964,13 @@
         return defValue;
     }
 
+    public static Context getBaseContext(Context context) {
+        while (context instanceof ContextWrapper) {
+            context = ((ContextWrapper) context).getBaseContext();
+        }
+        return context;
+    }
+
     //------------ NOT OVERRIDEN --------------------
 
     @Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
index e5023b8..ee57067 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
@@ -21,11 +21,15 @@
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.ide.common.rendering.api.SessionParams;
+import com.android.ide.common.rendering.api.StyleResourceValue;
 import com.android.layoutlib.bridge.android.BridgeContext;
 import com.android.layoutlib.bridge.impl.ResourceHelper;
 import com.android.resources.ResourceType;
 
+import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
@@ -55,7 +59,7 @@
         View contentView = getDecorContent().findViewById(contentRootId);
         if (contentView != null) {
             assert contentView instanceof FrameLayout;
-            setContentRoot(((FrameLayout) contentView));
+            setContentRoot((FrameLayout) contentView);
         } else {
             // Something went wrong. Create a new FrameLayout in the enclosing layout.
             FrameLayout contentRoot = new FrameLayout(context);
@@ -85,6 +89,27 @@
     }
 
     @Override
+    protected LayoutInflater getInflater(BridgeContext context) {
+        // Other than the resource resolution part, the code has been taken from the support
+        // library. see code from line 269 onwards in
+        // https://android.googlesource.com/platform/frameworks/support/+/android-5.1.0_r1/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateBase.java
+        Context themedContext = context;
+        RenderResources resources = context.getRenderResources();
+        ResourceValue actionBarTheme = resources.findItemInTheme("actionBarTheme", false);
+        if (actionBarTheme != null) {
+            // resolve it, if needed.
+            actionBarTheme = resources.resolveResValue(actionBarTheme);
+        }
+        if (actionBarTheme instanceof StyleResourceValue) {
+            int styleId = context.getDynamicIdByStyle(((StyleResourceValue) actionBarTheme));
+            if (styleId != 0) {
+                themedContext = new ContextThemeWrapper(context, styleId);
+            }
+        }
+        return LayoutInflater.from(themedContext);
+    }
+
+    @Override
     protected void setTitle(CharSequence title) {
         if (title != null && mWindowDecorActionBar != null) {
             Method setTitle = getMethod(mWindowActionBarClass, "setTitle", CharSequence.class);
@@ -104,8 +129,8 @@
     protected void setIcon(String icon) {
         // Do this only if the action bar doesn't already have an icon.
         if (icon != null && !icon.isEmpty() && mWindowDecorActionBar != null) {
-            if (((Boolean) invoke(getMethod(mWindowActionBarClass, "hasIcon"), mWindowDecorActionBar)
-            )) {
+            if (invoke(getMethod(mWindowActionBarClass, "hasIcon"), mWindowDecorActionBar)
+                    == Boolean.TRUE) {
                 Drawable iconDrawable = getDrawable(icon, false);
                 if (iconDrawable != null) {
                     Method setIcon = getMethod(mWindowActionBarClass, "setIcon", Drawable.class);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
index b29d25f..2a83ea1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
@@ -44,6 +44,7 @@
     private final View mDecorContent;
     private final ActionBarCallback mCallback;
 
+    @SuppressWarnings("NullableProblems")  // Should be initialized by subclasses.
     @NonNull private FrameLayout mContentRoot;
 
     public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params,
@@ -80,7 +81,7 @@
         }
 
         // Inflate action bar layout.
-        mDecorContent = LayoutInflater.from(context).inflate(layoutId, mEnclosingLayout, true);
+        mDecorContent = getInflater(context).inflate(layoutId, mEnclosingLayout, true);
 
     }
 
@@ -91,7 +92,11 @@
      */
     protected abstract ResourceValue getLayoutResource(BridgeContext context);
 
-    protected void setContentRoot(FrameLayout contentRoot) {
+    protected LayoutInflater getInflater(BridgeContext context) {
+        return LayoutInflater.from(context);
+    }
+
+    protected void setContentRoot(@NonNull FrameLayout contentRoot) {
         mContentRoot = contentRoot;
     }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index c9aa400..7c11284d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -1128,8 +1128,7 @@
             }
         } else {
             // action bar overrides title bar so only look for this one if action bar is hidden
-            boolean windowNoTitle = getBooleanThemeValue(resources,
-                    "windowNoTitle", false, !isThemeAppCompat(resources));
+            boolean windowNoTitle = getBooleanThemeValue(resources, "windowNoTitle", false, true);
 
             if (!windowNoTitle) {