Merge "Work on issue #29328569: NPE in " com.google.android.configupdater"" into nyc-dev
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index f12c284..3c7eef5 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1779,9 +1779,10 @@
 
         case START_BACKUP_AGENT_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
-            ApplicationInfo info = ApplicationInfo.CREATOR.createFromParcel(data);
+            String packageName = data.readString();
             int backupRestoreMode = data.readInt();
-            boolean success = bindBackupAgent(info, backupRestoreMode);
+            int userId = data.readInt();
+            boolean success = bindBackupAgent(packageName, backupRestoreMode, userId);
             reply.writeNoException();
             reply.writeInt(success ? 1 : 0);
             return true;
@@ -4448,13 +4449,14 @@
         return binder;
     }
 
-    public boolean bindBackupAgent(ApplicationInfo app, int backupRestoreMode)
+    public boolean bindBackupAgent(String packageName, int backupRestoreMode, int userId)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
-        app.writeToParcel(data, 0);
+        data.writeString(packageName);
         data.writeInt(backupRestoreMode);
+        data.writeInt(userId);
         mRemote.transact(START_BACKUP_AGENT_TRANSACTION, data, reply, 0);
         reply.readException();
         boolean success = reply.readInt() != 0;
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 81788da..ac21346 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -250,7 +250,7 @@
     public IBinder peekService(Intent service, String resolvedType, String callingPackage)
             throws RemoteException;
 
-    public boolean bindBackupAgent(ApplicationInfo appInfo, int backupRestoreMode)
+    public boolean bindBackupAgent(String packageName, int backupRestoreMode, int userId)
             throws RemoteException;
     public void clearPendingBackup() throws RemoteException;
     public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException;
diff --git a/core/java/android/service/quicksettings/IQSTileService.aidl b/core/java/android/service/quicksettings/IQSTileService.aidl
index bfde870..b6c830c 100644
--- a/core/java/android/service/quicksettings/IQSTileService.aidl
+++ b/core/java/android/service/quicksettings/IQSTileService.aidl
@@ -15,15 +15,10 @@
  */
 package android.service.quicksettings;
 
-import android.service.quicksettings.Tile;
-import android.service.quicksettings.IQSService;
-
 /**
  * @hide
  */
 oneway interface IQSTileService {
-    void setQSService(in IQSService service);
-    void setQSTile(in Tile tile);
     void onTileAdded();
     void onTileRemoved();
     void onStartListening();
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 4e9a075..67793fd 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -118,6 +118,16 @@
     /**
      * @hide
      */
+    public static final String EXTRA_SERVICE = "service";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_TILE = "tile";
+
+    /**
+     * @hide
+     */
     public static final String EXTRA_COMPONENT = "android.service.quicksettings.extra.COMPONENT";
 
     private final H mHandler = new H(Looper.getMainLooper());
@@ -305,18 +315,11 @@
 
     @Override
     public IBinder onBind(Intent intent) {
+        mTile = intent.getParcelableExtra(EXTRA_TILE);
+        mService = IQSService.Stub.asInterface(intent.getIBinderExtra(EXTRA_SERVICE));
+        mTile.setService(mService);
         return new IQSTileService.Stub() {
             @Override
-            public void setQSService(IQSService service) throws RemoteException {
-                mHandler.obtainMessage(H.MSG_SET_SERVICE, service).sendToTarget();
-            }
-
-            @Override
-            public void setQSTile(Tile tile) throws RemoteException {
-                mHandler.obtainMessage(H.MSG_SET_TILE, tile).sendToTarget();
-            }
-
-            @Override
             public void onTileRemoved() throws RemoteException {
                 mHandler.sendEmptyMessage(H.MSG_TILE_REMOVED);
             }
@@ -349,14 +352,12 @@
     }
 
     private class H extends Handler {
-        private static final int MSG_SET_TILE = 1;
-        private static final int MSG_START_LISTENING = 2;
-        private static final int MSG_STOP_LISTENING = 3;
-        private static final int MSG_TILE_ADDED = 4;
-        private static final int MSG_TILE_REMOVED = 5;
-        private static final int MSG_TILE_CLICKED = 6;
-        private static final int MSG_SET_SERVICE = 7;
-        private static final int MSG_UNLOCK_COMPLETE = 8;
+        private static final int MSG_START_LISTENING = 1;
+        private static final int MSG_STOP_LISTENING = 2;
+        private static final int MSG_TILE_ADDED = 3;
+        private static final int MSG_TILE_REMOVED = 4;
+        private static final int MSG_TILE_CLICKED = 5;
+        private static final int MSG_UNLOCK_COMPLETE = 6;
 
         public H(Looper looper) {
             super(looper);
@@ -365,18 +366,6 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case MSG_SET_SERVICE:
-                    mService = (IQSService) msg.obj;
-                    if (mTile != null) {
-                        mTile.setService(mService);
-                    }
-                    break;
-                case MSG_SET_TILE:
-                    mTile = (Tile) msg.obj;
-                    if (mService != null && mTile != null) {
-                        mTile.setService(mService);
-                    }
-                    break;
                 case MSG_TILE_ADDED:
                     TileService.this.onTileAdded();
                     break;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 19b1cf3..48bdcb2 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1814,6 +1814,19 @@
                             + mAttachInfo.mVisibleInsets);
                 }
 
+                // If any of the insets changed, do a forceLayout on the view so that the
+                // measure cache is cleared. We might have a pending MSG_RESIZED_REPORT
+                // that is supposed to take care of it, but since pending insets are
+                // already modified here, it won't detect the frame change after this.
+                final boolean framesChanged = overscanInsetsChanged
+                        || contentInsetsChanged
+                        || stableInsetsChanged
+                        || visibleInsetsChanged
+                        || outsetsChanged;
+                if (mAdded && mView != null && framesChanged) {
+                    forceLayout(mView);
+                }
+
                 if (!hadSurface) {
                     if (mSurface.isValid()) {
                         // If we are creating a new surface, then we need to
diff --git a/core/res/res/layout/unsupported_display_size_dialog_content.xml b/core/res/res/layout/unsupported_display_size_dialog_content.xml
new file mode 100644
index 0000000..5e5cf00
--- /dev/null
+++ b/core/res/res/layout/unsupported_display_size_dialog_content.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:paddingTop="?attr/dialogPreferredPadding"
+              android:paddingLeft="?attr/dialogPreferredPadding"
+              android:paddingRight="?attr/dialogPreferredPadding">
+
+    <CheckBox
+        android:id="@+id/ask_checkbox"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="start"
+        android:text="@string/unsupported_display_size_show" />
+</FrameLayout>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 48744b6..b55a9b22 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2768,6 +2768,11 @@
     <!-- [CHAR LIMIT=200] Compat mode dialog: hint to re-enable compat mode dialog. -->
     <string name="screen_compat_mode_hint">Re-enable this in System settings &gt; Apps &gt; Downloaded.</string>
 
+    <!-- [CHAR LIMIT=200] Unsupported display size dialog: message. Refers to "Display size" setting. -->
+    <string name="unsupported_display_size_message"><xliff:g id="app_name">%1$s</xliff:g> does not support the current Display size setting and may behave unexpectedly.</string>
+    <!-- [CHAR LIMIT=50] Unsupported display size dialog: check box label. -->
+    <string name="unsupported_display_size_show">Always show</string>
+
     <!-- Text of the alert that is displayed when an application has violated StrictMode. -->
     <string name="smv_application">The app <xliff:g id="application">%1$s</xliff:g>
         (process <xliff:g id="process">%2$s</xliff:g>) has violated its self-enforced StrictMode policy.</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7e9b57c..d154b03 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2609,4 +2609,7 @@
   <java-symbol type="array" name="config_defaultPinnerServiceFiles" />
 
   <java-symbol type="string" name="suspended_widget_accessibility" />
+
+  <java-symbol type="layout" name="unsupported_display_size_dialog_content" />
+  <java-symbol type="string" name="unsupported_display_size_message" />
 </resources>
diff --git a/docs/html/ndk/downloads/index.jd b/docs/html/ndk/downloads/index.jd
index 47d3113..954b049 100644
--- a/docs/html/ndk/downloads/index.jd
+++ b/docs/html/ndk/downloads/index.jd
@@ -332,35 +332,199 @@
 <h2 id="rel">Release Notes</h2>
 
 <p>
-  Android NDK, Revision 11c <em>(March 2016)</em>
+  Android NDK, Revision 12 <em>(June 2016)</em>
 </p>
 
 <dl>
-  <dt>
-    NDK
-  </dt>
+<dt>
+  Announcements
+</dt>
 
-  <dd>
-    <ul>
-      <li>Changes
-        <ul>
-          <li>Applied additional fixes to the {@code ndk-gdb.py} script.
-          </li>
-          <li>Added an optional package name argument to the {@code ndk-gdb}
-            command {@code --attach} option.
-            (<a href="https://github.com/android-ndk/ndk/issues/13">Issue 13</a>)
-          </li>
-          <li>Fixed invalid toolchain paths for 32-bit Windows platform.
-            (<a href="https://github.com/android-ndk/ndk/issues/45">Issue 45</a>)
-          </li>
-          <li>Fixed the relative path for the {@code ndk-which} command.
-            (<a href="https://github.com/android-ndk/ndk/issues/29">Issue 29</a>)
-          </li>
-          <li>Fixed use of cygpath for the libgcc compiler.
-            (Android <a href="http://b.android.com/195486">Issue 195486</a>)
-          </li>
-        </ul>
-      </li>
-    </ul>
-  </dd>
-</dl>
\ No newline at end of file
+<ul>
+  <li>The <code>ndk-build</code> command will default to using
+  Clang in an upcoming release. GCC will be removed in a later release.
+  </li>
+  <li>The <code>make-standalone-toolchain.sh</code> script will be removed
+  in an upcoming release. If you use this script, please plan to migrate to the
+  <code>make_standalone_toolchain.py</code> as soon as possible.
+  </li>
+</ul>
+
+<dt>
+  NDK
+</dt>
+
+<ul>
+  <li>Removed support for the armeabi-v7a-hard ABI. See the explanation in the
+  <a href=
+  "https://android.googlesource.com/platform/ndk/+/ndk-r12-release/docs/HardFloatAbi.md">
+    documentation</a>.
+  </li>
+
+  <li>Removed all sysroots for platform levels prior to Android 2.3 (API level 10).
+    We dropped support for them in NDK r11, but neglected to actually remove them.
+  </li>
+
+  <li>Updated exception handling when using c++_shared on ARM32 so that it
+    mostly works (see <a href="#known-issues">Known Issues</a>). The unwinder
+    is now linked into each linked object rather than into libc++ itself.
+  </li>
+
+  <li>Pruned the default compiler flags (<a href=
+  "https://github.com/android-ndk/ndk/issues/27">NDK Issue 27</a>). You can see
+  details of this update in <a href=
+  "https://android-review.googlesource.com/#/c/207721/5">Change 207721</a>.
+  </li>
+
+  <li>Added a Python implementation of standalone toolchains in <code>
+  build/tools/make_standalone_toolchain.py</code>. On Windows, you no longer
+  need Cygwin to use this feature. Note that the bash flavor will be removed
+  in an upcoming release, so please test the new one now.
+  </li>
+
+  <li>Configured Clang debug builds to have the <code>-fno-limit-debug-info</code>
+  option is enabled by default. This change enables better debugging with LLDB.
+  </li>
+
+  <li>Enabled the <code>--build-id</code> as a default option. This option
+  causes an identifier to be shown in native crash reports so you can easily
+  identify which version of your code was running.
+  </li>
+
+  <li>Fixed issue with <code>NDK_USE_CYGPATH</code> so that it no longer causes
+  problems with libgcc
+  (<a href="http://b.android.com/195486">Issue 195486</a>).
+  </li>
+
+  <li>Enabled the following options as default:
+  <code>-Wl,--warn-shared-textrel</code> and <code>-Wl,--fatal-warnings</code>.
+  If you have shared text relocations, your app does not load on Android 6.0
+  (API level 23) and higher. Note that this configuration has never been
+  allowed for 64-bit apps.
+  </li>
+
+  <li>Fixed a few issues so that precompiled headers work better
+    (<a href="https://github.com/android-ndk/ndk/issues/14">NDK Issue 14</a>,
+     <a href="https://github.com/android-ndk/ndk/issues/16">NDK Issue 16</a>).
+  </li>
+
+  <li>Removed unreachable ARM (non-thumb) STL libraries.
+  </li>
+
+  <li>Added Vulkan support to android-24.
+  </li>
+
+  <li>Added Choreographer API to android-24.
+  </li>
+
+  <li>Added libcamera2 APIs for devices that support the
+  <code>INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED</code> feature level or higher.
+  For more information, see the
+  <a href="{@docRoot}reference/android/hardware/camera2/CameraCharacteristics.html#INFO_SUPPORTED_HARDWARE_LEVEL">
+    <code>CameraCharacteristics</code></a> reference.
+  </li>
+
+</ul>
+
+<dt>
+  Clang
+</dt>
+
+<ul>
+  <li>Clang has been updated to 3.8svn (r256229, build 2812033). Note that
+    Clang packaged in the Windows 64-bit NDK is actually 32-bit.
+  </li>
+
+  <li>Fixed <code>__thread</code> so that it works for real this time.
+  </li>
+</ul>
+
+<dt>
+  GCC
+</dt>
+
+<ul>
+  <li>Synchronized the compiler with the ChromeOS GCC @ google/gcc-4_9 r227810.
+  </li>
+
+  <li>Backported coverage sanitizer patch from ToT (r231296).
+  </li>
+
+  <li>Fixed <code>libatomic</code> to not use ifuncs (<a href=
+  "https://github.com/android-ndk/ndk/issues/31">NDK Issue 31</a>).
+  </li>
+</ul>
+
+<dt>
+  Binutils
+</dt>
+
+<ul>
+  <li>Silenced the "Erratum 843419 found and fixed" info messages.
+  </li>
+
+  <li>Introduced option <code>--long-plt</code> to fix an internal linker error
+  when linking huge arm32 binaries.
+  </li>
+
+  <li>Fixed wrong run time stubs for <code>AArch64</code>. This problem was
+  causing jump addresses to be calculated incorrectly for very large
+  dynamic shared objects (DSOs).
+  </li>
+
+  <li>Introduced default option <code>--no-apply-dynamic</code> to work around
+  a dynamic linker bug for earlier Android releases.
+  </li>
+
+  <li>Fixed a known issue with NDK r11 where <code>dynamic_cast</code> was not
+  working with Clang, x86, stlport_static and optimization.
+  </li>
+</ul>
+
+<dt>
+  GDB
+</dt>
+
+<ul>
+  <li>Updated to GDB version 7.11. For more information about this release, see
+  <a href="https://www.gnu.org/software/gdb/news/">GDB News</a>.
+  </li>
+
+  <li>Fixed a number of bugs in the <code>ndk-gdb.py</code> script.
+  </li>
+</ul>
+
+<dt id="known-issues">
+  Known Issues
+</dt>
+
+<ul>
+  <li>The x86 <a href="http://source.android.com/devices/tech/debug/asan.html">Address
+  Sanitizer</a> (ASAN) currently does not work. For more information, see
+  <a href="https://android-review.googlesource.com/#/c/186276/">Issue 186276</a>.
+  </li>
+
+  <li>Exception unwinding with <code>c++_shared</code> does not work for ARM on
+  Android 2.3 (API level 9) or Android 4.0 (API level 14).
+  </li>
+
+  <li>Bionic headers and libraries for Android 6.0 (API level 23) and higher
+  are not yet exposed despite the presence of android-24. Those platforms still
+  have the Android 5.0 (API level 21) headers and libraries, which is consistent
+  with NDK r11.
+  </li>
+
+  <li>The RenderScript tools are not present, which is consistent with
+  NDK r11.
+  (<a href="https://github.com/android-ndk/ndk/issues/7">NDK Issue 7</a>)
+  </li>
+
+  <li>In <code>NdkCameraMetadataTags.h</code> header file, the camera metadata
+  tag enum value <code>ACAMERA_STATISTICS_LENS_SHADING_CORRECTION_MAP</code>
+  was listed by accident and will be removed in next release. Use
+  the <code>ACAMERA_STATISTICS_LENS_SHADING_MAP</code> value instead.
+  </li>
+
+</ul>
+
+</dl>
diff --git a/docs/html/ndk/downloads/revision_history.jd b/docs/html/ndk/downloads/revision_history.jd
index c5a0d48..211b64e 100644
--- a/docs/html/ndk/downloads/revision_history.jd
+++ b/docs/html/ndk/downloads/revision_history.jd
@@ -10,6 +10,44 @@
  <p>
    <a href="#" onclick="return toggleContent(this)"> <img
      src="/assets/images/styles/disclosure_down.png" class="toggle-content-img" alt=""
+   >Android NDK, Revision 11c</a> <em>(March 2016)</em>
+ </p>
+ <div class="toggle-content-toggleme">
+
+<dl>
+  <dd>
+    <ul>
+      <li>Changes
+        <ul>
+          <li>Applied additional fixes to the {@code ndk-gdb.py} script.
+          </li>
+          <li>Added an optional package name argument to the {@code ndk-gdb}
+            command {@code --attach} option.
+            (<a href="https://github.com/android-ndk/ndk/issues/13">Issue 13</a>)
+          </li>
+          <li>Fixed invalid toolchain paths for 32-bit Windows platform.
+            (<a href="https://github.com/android-ndk/ndk/issues/45">Issue 45</a>)
+          </li>
+          <li>Fixed the relative path for the {@code ndk-which} command.
+            (<a href="https://github.com/android-ndk/ndk/issues/29">Issue 29</a>)
+          </li>
+          <li>Fixed use of cygpath for the libgcc compiler.
+            (Android <a href="http://b.android.com/195486">Issue 195486</a>)
+          </li>
+        </ul>
+      </li>
+    </ul>
+  </dd>
+</dl>
+
+ </div>
+</div>
+
+<div class="toggle-content closed">
+<a name="11b"></a>
+ <p>
+   <a href="#" onclick="return toggleContent(this)"> <img
+     src="/assets/images/styles/disclosure_down.png" class="toggle-content-img" alt=""
    >Android NDK, Revision 11b</a> <em>(March 2016)</em>
  </p>
  <div class="toggle-content-toggleme">
diff --git a/docs/html/preview/support.jd b/docs/html/preview/support.jd
index b242111..ef8a652 100644
--- a/docs/html/preview/support.jd
+++ b/docs/html/preview/support.jd
@@ -280,6 +280,15 @@
   </li>
 </ul>
 
+<h4 id="">Android Auto</h4>
+
+<p>
+  The version of Google Maps included in Developer Preview 4 (9.30) crashes
+  when used with Android Auto. This issue will be fixed in the next update to
+  Google Maps (9.31), expected in the coming weeks.
+</p>
+
+
 <!-- TBA, if any
 <h4>Device-specific issues</h4>
 
diff --git a/docs/html/sdk/sdk_vars.cs b/docs/html/sdk/sdk_vars.cs
index 32fdb0a..80da297 100644
--- a/docs/html/sdk/sdk_vars.cs
+++ b/docs/html/sdk/sdk_vars.cs
@@ -1,18 +1,19 @@
 <?cs
-set:ndk.mac64_download='android-ndk-r11c-darwin-x86_64.zip' ?><?cs
-set:ndk.mac64_bytes='772428792' ?><?cs
-set:ndk.mac64_checksum='4ce8e7ed8dfe08c5fe58aedf7f46be2a97564696' ?><?cs
+set:ndk.mac64_download='android-ndk-r12-darwin-x86_64.zip' ?><?cs
+set:ndk.mac64_bytes='734014148' ?><?cs
+set:ndk.mac64_checksum='708d4025142924f7097a9f44edf0a35965706737' ?><?cs
 
-set:ndk.linux64_download='android-ndk-r11c-linux-x86_64.zip' ?><?cs
-set:ndk.linux64_bytes='794135138' ?><?cs
-set:ndk.linux64_checksum='de5ce9bddeee16fb6af2b9117e9566352aa7e279' ?><?cs
+set:ndk.linux64_download='android-ndk-r12-linux-x86_64.zip' ?><?cs
+set:ndk.linux64_bytes='755431993' ?><?cs
+set:ndk.linux64_checksum='b7e02dc733692447366a2002ad17e87714528b39' ?><?cs
 
-set:ndk.win64_download='android-ndk-r11c-windows-x86_64.zip' ?><?cs
-set:ndk.win64_bytes='771407642' ?><?cs
-set:ndk.win64_checksum='3d89deb97b3191c7e5555f1313ad35059479f071' ?><?cs
-set:ndk.win32_download='android-ndk-r11c-windows-x86.zip' ?><?cs
-set:ndk.win32_bytes='728899082' ?><?cs
-set:ndk.win32_checksum='ff939bde6cd374eecbd2c3b2ad218697f9a5038c'
+set:ndk.win64_download='android-ndk-r12-windows-x86.zip' ?><?cs
+set:ndk.win64_bytes='706332762' ?><?cs
+set:ndk.win64_checksum='37fcd7acf6012d0068a57c1524edf24b0fef69c9' ?><?cs
+
+set:ndk.win32_download='android-ndk-r12-windows-x86_64.zip' ?><?cs
+set:ndk.win32_bytes='749444245' ?><?cs
+set:ndk.win32_checksum='80d64a77aab52df867ac55cec1e976663dd3326f'
 ?>
 <?cs
 def:size_in_mb(bytes)
diff --git a/docs/html/topic/libraries/data-binding/index.jd b/docs/html/topic/libraries/data-binding/index.jd
index ca8784e..293de51 100644
--- a/docs/html/topic/libraries/data-binding/index.jd
+++ b/docs/html/topic/libraries/data-binding/index.jd
@@ -18,7 +18,7 @@
         <a href="#data_binding_layout_files">Data Binding Layout Files</a>
         <ol>
           <li>
-            <a href="#writing_expressions">Writing your first data binding
+            <a href="#writing_expressions">Writing your first set of data binding
             expressions</a>
           </li>
 
@@ -29,9 +29,16 @@
           <li>
             <a href="#binding_data">Binding Data</a>
           </li>
-
           <li>
-            <a href="#binding_events">Binding Events</a>
+            <a href="#event_handling">Event Handling</a>
+            <ol>
+              <li>
+                <a href="#method_references">Method References</a>
+              </li>
+              <li>
+                <a href="#listener_bindings">Listener Bindings</a>
+              </li>
+            </ol>
           </li>
         </ol>
       </li>
@@ -147,27 +154,34 @@
   application logic and layouts.
 </p>
 
-<p>The Data Binding Library offers both flexibility and broad compatibility
-&mdash; it's a support library, so you can use it with all Android platform
-versions back to <strong>Android 2.1</strong> (API level 7+).</p>
+<p>
+  The Data Binding Library offers both flexibility and broad compatibility —
+  it's a support library, so you can use it with all Android platform versions
+  back to <strong>Android 2.1</strong> (API level 7+).
+</p>
 
-<p>To use data binding, Android Plugin for Gradle <strong>1.5.0-alpha1</strong>
-or higher is required.</p>
+<p>
+  To use data binding, Android Plugin for Gradle <strong>1.5.0-alpha1</strong>
+  or higher is required.
+</p>
 
 <h2 id="build_environment">
   Build Environment
 </h2>
 
-<p>To get started with Data Binding, download the library from the Support
-repository in the Android SDK manager. </p>
-
 <p>
-To configure your app to use data binding, add the <code>dataBinding</code> element to your
-<code>build.gradle</code> file in the app module.
+  To get started with Data Binding, download the library from the Support
+  repository in the Android SDK manager.
 </p>
 
- <p>Use the following code snippet to configure data binding: </p>
+<p>
+  To configure your app to use data binding, add the <code>dataBinding</code>
+  element to your <code>build.gradle</code> file in the app module.
+</p>
 
+<p>
+  Use the following code snippet to configure data binding:
+</p>
 <pre>
 android {
     ....
@@ -176,13 +190,17 @@
     }
 }
 </pre>
+<p>
+  If you have an app module that depends on a library which uses data binding,
+  your app module must configure data binding in its <code>build.gradle</code>
+  file as well.
+</p>
 
-<p>If you have an app module that depends on a library which uses data binding, your app module
- must configure data binding in its <code>build.gradle</code> file as well.</p>
-
-<p>Also, make sure you are using a compatible version of Android Studio.
-<strong>Android Studio 1.3</strong> and later provides support for data binding as described in
-<a href="#studio_support">Android Studio Support for Data Binding</a>.
+<p>
+  Also, make sure you are using a compatible version of Android Studio.
+  <strong>Android Studio 1.3</strong> and later provides support for data
+  binding as described in <a href="#studio_support">Android Studio Support for
+  Data Binding</a>.
 </p>
 
 <h2 id="data_binding_layout_files">
@@ -190,7 +208,7 @@
 </h2>
 
 <h3 id="writing_expressions">
-  Writing your first data binding expressions
+  Writing your first set of data binding expressions
 </h3>
 
 <p>
@@ -223,20 +241,19 @@
   The user <strong>variable</strong> within <strong>data</strong> describes a
   property that may be used within this layout.
 </p>
-
 <pre>
 &lt;<strong>variable name="user" type="com.example.User"</strong>/&gt;
 </pre>
 <p>
   Expressions within the layout are written in the attribute properties using
-  the “<code>&commat;{}</code>” syntax. Here, the TextView’s text is set to the
-  firstName property of user:
+  the “<code>&amp;commat;{}</code>” syntax. Here, the TextView’s text is set to
+  the firstName property of user:
 </p>
 
 <pre>
 &lt;TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
-          android:text="&commat;{user.firstName}"/&gt;
+          android:text="&amp;commat;{user.firstName}"/&gt;
 </pre>
 <h3 id="data_object">
   Data Object
@@ -261,7 +278,6 @@
   to have data that is read once and never changes thereafter. It is also
   possible to use a JavaBeans objects:
 </p>
-
 <pre>
 public class User {
    private final String firstName;
@@ -280,11 +296,12 @@
 </pre>
 <p>
   From the perspective of data binding, these two classes are equivalent. The
-  expression <strong><code>&commat;{user.firstName}</code></strong> used for
-  the TextView’s <strong><code>android:text</code></strong> attribute will
+  expression <strong><code>&amp;commat;{user.firstName}</code></strong> used
+  for the TextView’s <strong><code>android:text</code></strong> attribute will
   access the <strong><code>firstName</code></strong> field in the former class
-  and the <code>getFirstName()</code> method in the latter class. Alternatively, it
-  will also be resolved to <code>firstName()</code> if that method exists.
+  and the <code>getFirstName()</code> method in the latter class.
+  Alternatively, it will also be resolved to <code>firstName()</code> if that
+  method exists.
 </p>
 
 <h3 id="binding_data">
@@ -328,16 +345,38 @@
 //or
 ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.layout.<em><strong>list_item</strong></em>, viewGroup, <strong>false</strong>);
 </pre>
-
-<h3 id="binding_events">
-  Binding Events
-</h3>
+<h3 id="event_handling">Event Handling</h3>
 <p>
-  Events may be bound to handler methods directly, similar to the way
-  <strong><code>android:onClick</code></strong> can be assigned to a method in the Activity.
-  Event attribute names are governed by the name of the listener method with a few exceptions.
-  For example, {@link android.view.View.OnLongClickListener} has a method {@link android.view.View.OnLongClickListener#onLongClick onLongClick()},
-  so the attribute for this event is <code>android:onLongClick</code>.
+Data Binding allows you to write expressions handling events that are dispatched from the views (e.g. onClick).
+Event attribute names are governed by the name of the listener method with a few exceptions.
+For example, {@link android.view.View.OnLongClickListener} has a method {@link android.view.View.OnLongClickListener#onLongClick onLongClick()},
+so the attribute for this event is <code>android:onLongClick</code>.
+There are two ways to handle an event.
+</p>
+<ul>
+  <li>
+    <a href="#method_references">Method References</a>: In your expressions, you can reference methods that conform to the signature of the listener method. When an expression evaluates to a method reference, Data Binding wraps the method reference and owner object in a listener, and sets that listener on the target view. If the expression evaluates to null, Data Binding does not create a listener and sets a null listener instead.
+  </li>
+  <li>
+    <a href="#listener_bindings">Listener Bindings</a>: These are lambda expressions that are evaluated when the event happens.
+Data Binding always creates a listener, which it sets on the view. When the event is dispatched, the listener evaluates the lambda expression.
+  </li>
+</ul>
+<h4 id="method_references">
+  Method References
+</h4>
+<p>
+  Events can be bound to handler methods directly, similar to the way
+  <strong><code>android:onClick</code></strong> can be assigned to a method in an Activity.
+  One major advantage compared to the {@code View#onClick} attribute is that the expression
+  is processed at compile time, so if the method does not exist or its signature is not
+  correct, you receive a compile time error.</p>
+<p>
+  The major difference between Method References and Listener Bindings is that
+  the actual listener implementation is created when the data is bound, not
+  when the event is triggered. If you prefer to evaluate the expression when
+  the event happens, you should use <a href="#listener_bindings">listener
+  binding</a>.
 </p>
 <p>
   To assign an event to its handler, use a normal binding expression, with the value
@@ -345,7 +384,6 @@
 </p>
 <pre>public class MyHandlers {
     public void onClickFriend(View view) { ... }
-    public void onClickEnemy(View view) { ... }
 }
 </pre>
 <p>
@@ -365,14 +403,121 @@
        &lt;TextView android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="&commat;{user.firstName}"
-           android:onClick="&commat;{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/&gt;
-       &lt;TextView android:layout_width="wrap_content"
-           android:layout_height="wrap_content"
-           android:text="&commat;{user.lastName}"
-           android:onClick="&commat;{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/&gt;
+           android:onClick="&commat;{handlers::onClickFriend}"/&gt;
    &lt;/LinearLayout&gt;
 &lt;/layout&gt;
 </pre>
+<p>
+Note that the signature of the method in the expression must exactly match the signature of the method in the
+Listener object.
+</p>
+<h4 id="listener_bindings">
+  Listener Bindings
+</h4>
+<p>
+  Listener Bindings are binding expressions that run when an event happens.
+  They are similar to method references, but they let you run arbitrary data
+  binding expressions. This feature is available with Android Gradle Plugin for Gradle
+  version 2.0 and later.
+</p>
+<p>
+  In method references, the parameters of the method must
+  match the parameters of the event listener. In Listener Bindings, only your
+  return value must match the expected return value of the listener (unless it
+  is expecting void).
+  For example, you can have a presenter class that has the following method:
+</p>
+<pre>
+public class Presenter {
+    public void onSaveClick(Task task){}
+}
+</pre>
+  Then you can bind the click event to your class as follows:
+<pre>
+  &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
+  &lt;layout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
+      &lt;data&gt;
+          &lt;variable name=&quot;task&quot; type=&quot;com.android.example.Task&quot; /&gt;
+          &lt;variable name=&quot;presenter&quot; type=&quot;com.android.example.Presenter&quot; /&gt;
+      &lt;/data&gt;
+      &lt;LinearLayout android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;match_parent&quot;&gt;
+          &lt;Button android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot;
+          android:onClick=&quot;@{() -&gt; presenter.onSaveClick(task)}&quot; /&gt;
+      &lt;/LinearLayout&gt;
+  &lt;/layout&gt;
+</pre>
+<p>
+  Listeners are represented by lambda expressions that are allowed only as root
+  elements of your expressions. When a callback is used in an expression, Data
+  Binding automatically creates the necessary listener and registers for the
+  event. When the view fires the event, Data Binding evaluates the given
+  expression. As in regular binding expressions, you still get the null and
+  thread safety of Data Binding while these listener expressions are being
+  evaluated.
+</p>
+<p>
+  Note that in the example above, we haven't defined the {@code view} parameter
+  that is passed into {@link
+  android.view.View.OnClickListener#onClick(android.view.View view)}. Listener
+  bindings provide two choices for listener parameters: you can either ignore
+  all parameters to the method or name all of them. If you prefer to name the
+  parameters, you can use them in your expression. For example, the expression
+  above could be written as:
+</p>
+<pre>
+  android:onClick=&quot;@{(view) -&gt; presenter.onSaveClick(task)}&quot;
+</pre>
+Or if you wanted to use the parameter in the expression, it could work as follows:
+<pre>
+public class Presenter {
+    public void onSaveClick(View view, Task task){}
+}
+</pre>
+<pre>
+  android:onClick=&quot;@{(theView) -&gt; presenter.onSaveClick(theView, task)}&quot;
+</pre>
+You can use a lambda expression with more than one parameter:
+<pre>
+public class Presenter {
+    public void onCompletedChanged(Task task, boolean completed){}
+}
+</pre>
+<pre>
+  &lt;CheckBox android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot;
+        android:onCheckedChanged=&quot;@{(cb, isChecked) -&gt; presenter.completeChanged(task, isChecked)}&quot; /&gt;
+</pre>
+<p>
+  If the event you are listening to returns a value whose type is not {@code
+  void}, your expressions must return the same type of value as well. For
+  example, if you want to listen for the long click event, your expression
+  should return {@code boolean}.
+</p>
+<pre>
+public class Presenter {
+    public boolean onLongClick(View view, Task task){}
+}
+</pre>
+<pre>
+  android:onLongClick=&quot;@{(theView) -&gt; presenter.onLongClick(theView, task)}&quot;
+</pre>
+<p>
+If the expression cannot be evaluated due to {@code null} objects, Data Binding returns
+the default Java value for that type. For example, {@code null} for reference types, {@code 0} for {@code int},
+{@code false} for {@code boolean}, etc.
+</p>
+<p>
+If you need to use an expression with a predicate (e.g. ternary), you can use
+{@code void} as a symbol.
+</p>
+<pre>
+  android:onClick=&quot;@{(v) -&gt; v.isVisible() ? doSomething() : void}&quot;
+</pre>
+
+<h5>Avoid Complex Listeners</h5>
+Listener expressions are very powerful and can make your code very easy to read.
+On the other hand, listeners containing complex expressions make your layouts hard to read and unmaintainable. 
+These expressions should be as simple as passing available data from your UI to your callback method. You should implement 
+any business logic inside the callback method that you invoked from the listener expression.
 
 <p>
   Some specialized click event handlers exist and they need an attribute other than
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index c984abe..f287f1b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -113,6 +113,11 @@
     }
 
     @Override
+    protected void onTileClick(QSTile<?> tile) {
+        tile.secondaryClick();
+    }
+
+    @Override
     public void onTuningChanged(String key, String newValue) {
         // No tunings for you.
         if (key.equals(QS_SHOW_BRIGHTNESS)) {
@@ -130,7 +135,7 @@
                 break;
             }
         }
-        super.setTiles(quickTiles, false);
+        super.setTiles(quickTiles, true);
     }
 
     private final Tunable mNumTiles = new Tunable() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 60c24d0..f060502 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -37,6 +37,7 @@
 import android.view.accessibility.AccessibilityManager;
 import android.widget.FrameLayout;
 import android.widget.TextView;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto;
 import com.android.systemui.R;
@@ -227,6 +228,8 @@
             });
             if (mNeedsFocus) {
                 // Wait for this to get laid out then set its focus.
+                // Ensure that tile gets laid out so we get the callback.
+                holder.mTileView.requestLayout();
                 holder.mTileView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
                     @Override
                     public void onLayoutChange(View v, int left, int top, int right, int bottom,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 23a3ca1..46e7277 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -71,17 +71,12 @@
         super(host);
         mWindowManager = WindowManagerGlobal.getWindowManagerService();
         mComponent = ComponentName.unflattenFromString(action);
+        mTile = new Tile(mComponent);
+        setTileIcon();
         mServiceManager = host.getTileServices().getTileWrapper(this);
         mService = mServiceManager.getTileService();
         mServiceManager.setTileChangeListener(this);
-        mTile = new Tile(mComponent);
         mUser = ActivityManager.getCurrentUser();
-        setTileIcon();
-        try {
-            mService.setQSTile(mTile);
-        } catch (RemoteException e) {
-            // Called through wrapper, won't happen here.
-        }
     }
 
     private void setTileIcon() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java b/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
index 3830ac5..407453c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
@@ -35,16 +35,6 @@
         return mService.asBinder();
     }
 
-    public boolean setQSTile(Tile tile) {
-        try {
-            mService.setQSTile(tile);
-            return true;
-        } catch (Exception e) {
-            Log.d(TAG, "Caught exception from TileService", e);
-            return false;
-        }
-    }
-
     public boolean onTileAdded() {
         try {
             mService.onTileAdded();
@@ -95,16 +85,6 @@
         }
     }
 
-    public boolean setQSService(IQSService service) {
-        try {
-            mService.setQSService(service);
-            return true;
-        } catch (Exception e) {
-            Log.d(TAG, "Caught exception from TileService", e);
-            return false;
-        }
-    }
-
     public boolean onUnlockComplete() {
         try {
             mService.onUnlockComplete();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index 87d6307..dd46779 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -71,23 +71,24 @@
     private Set<Integer> mQueuedMessages = new ArraySet<>();
     private QSTileServiceWrapper mWrapper;
     private boolean mListening;
-    private Tile mTile;
     private IBinder mClickBinder;
 
     private int mBindTryCount;
     private boolean mBound;
     @VisibleForTesting
     boolean mReceiverRegistered;
-    private IQSService mService;
     private boolean mUnbindImmediate;
     private TileChangeListener mChangeListener;
     // Return value from bindServiceAsUser, determines whether safe to call unbind.
     private boolean mIsBound;
 
-    public TileLifecycleManager(Handler handler, Context context, Intent intent, UserHandle user) {
+    public TileLifecycleManager(Handler handler, Context context, IQSService service,
+            Tile tile, Intent intent, UserHandle user) {
         mContext = context;
         mHandler = handler;
         mIntent = intent;
+        mIntent.putExtra(TileService.EXTRA_SERVICE, service.asBinder());
+        mIntent.putExtra(TileService.EXTRA_TILE, tile);
         mUser = user;
         if (DEBUG) Log.d(TAG, "Creating " + mIntent + " " + mUser);
     }
@@ -164,14 +165,6 @@
             service.linkToDeath(this, 0);
         } catch (RemoteException e) {
         }
-        if (!wrapper.setQSService(mService)) {
-            handleDeath();
-            return;
-        }
-        if (!wrapper.setQSTile(mTile)) {
-            handleDeath();
-            return;
-        }
         mWrapper = wrapper;
         handlePendingMessages();
     }
@@ -255,15 +248,6 @@
         }
     }
 
-    @Override
-    public void setQSTile(Tile tile) {
-        if (DEBUG) Log.d(TAG, "setQSTile " + tile);
-        mTile = tile;
-        if (mWrapper != null && !mWrapper.setQSTile(tile)) {
-            handleDeath();
-        }
-    }
-
     private boolean checkComponentState() {
         PackageManager pm = mContext.getPackageManager();
         if (!isPackageAvailable(pm) || !isComponentAvailable(pm)) {
@@ -347,14 +331,6 @@
     }
 
     @Override
-    public void setQSService(IQSService service) {
-        mService = service;
-        if (mWrapper == null || !mWrapper.setQSService(service)) {
-            handleDeath();
-        }
-    }
-
-    @Override
     public void onTileAdded() {
         if (DEBUG) Log.d(TAG, "onTileAdded");
         if (mWrapper == null || !mWrapper.onTileAdded()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
index ce9bbf4..3d030f9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
@@ -27,6 +27,7 @@
 import android.os.Handler;
 import android.os.UserHandle;
 import android.service.quicksettings.IQSTileService;
+import android.service.quicksettings.Tile;
 import android.service.quicksettings.TileService;
 import android.support.annotation.VisibleForTesting;
 import android.util.Log;
@@ -68,9 +69,10 @@
     // This defaults to true to ensure tiles start out unavailable.
     private boolean mPendingBind = true;
 
-    TileServiceManager(TileServices tileServices, Handler handler, ComponentName component) {
+    TileServiceManager(TileServices tileServices, Handler handler, ComponentName component,
+            Tile tile) {
         this(tileServices, handler, new TileLifecycleManager(handler,
-                tileServices.getContext(), new Intent().setComponent(component),
+                tileServices.getContext(), tileServices, tile, new Intent().setComponent(component),
                 new UserHandle(ActivityManager.getCurrentUser())));
     }
 
@@ -80,7 +82,6 @@
         mServices = tileServices;
         mHandler = handler;
         mStateManager = tileLifecycleManager;
-        mStateManager.setQSService(tileServices);
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index 2ab6b5f..f84c5d0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -78,7 +78,7 @@
 
     public TileServiceManager getTileWrapper(CustomTile tile) {
         ComponentName component = tile.getComponent();
-        TileServiceManager service = onCreateTileService(component);
+        TileServiceManager service = onCreateTileService(component, tile.getQsTile());
         synchronized (mServices) {
             mServices.put(tile, service);
             mTiles.put(component, tile);
@@ -86,8 +86,8 @@
         return service;
     }
 
-    protected TileServiceManager onCreateTileService(ComponentName component) {
-        return new TileServiceManager(this, mHandler, component);
+    protected TileServiceManager onCreateTileService(ComponentName component, Tile tile) {
+        return new TileServiceManager(this, mHandler, component, tile);
     }
 
     public void freeService(CustomTile tile, TileServiceManager service) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 18191cf..0de5105 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -95,14 +95,6 @@
     }
 
     @Override
-    protected void handleSecondaryClick() {
-        boolean dataEnabled = mDataController.isMobileDataSupported()
-                && mDataController.isMobileDataEnabled();
-        MetricsLogger.action(mContext, MetricsEvent.QS_CELLULAR_TOGGLE, !dataEnabled);
-        mDataController.setMobileDataEnabled(!dataEnabled);
-    }
-
-    @Override
     public CharSequence getTileLabel() {
         return mContext.getString(R.string.quick_settings_cellular_detail_title);
     }
@@ -152,8 +144,8 @@
         }
         state.contentDescription = state.contentDescription + "," + r.getString(
                 R.string.accessibility_quick_settings_open_settings, getTileLabel());
-        state.expandedAccessibilityClassName = Button.class.getName();
-        state.minimalAccessibilityClassName = Switch.class.getName();
+        state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
+                = Button.class.getName();
         state.value = mDataController.isMobileDataSupported()
                 && mDataController.isMobileDataEnabled();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 91889d3..542b258 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -134,6 +134,7 @@
             = SystemProperties.getBoolean("debug.child_notifs", true);
     public static final boolean FORCE_REMOTE_INPUT_HISTORY =
             SystemProperties.getBoolean("debug.force_remoteinput_history", false);
+    private static boolean ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT = false;
 
     protected static final int MSG_SHOW_RECENT_APPS = 1019;
     protected static final int MSG_HIDE_RECENT_APPS = 1020;
@@ -704,10 +705,13 @@
                 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), false,
                 mSettingsObserver,
                 UserHandle.USER_ALL);
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT), false,
-                mSettingsObserver,
-                UserHandle.USER_ALL);
+        if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) {
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT),
+                    false,
+                    mSettingsObserver,
+                    UserHandle.USER_ALL);
+        }
 
         mContext.getContentResolver().registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
@@ -2304,16 +2308,20 @@
         final boolean allowedByDpm = (dpmFlags
                 & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS) == 0;
 
-        final boolean remoteInput = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT,
-                0,
-                mCurrentUserId) != 0;
-        final boolean remoteInputDpm = (dpmFlags
-                & DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT) == 0;
-
-
         setShowLockscreenNotifications(show && allowedByDpm);
-        setLockScreenAllowRemoteInput(remoteInput && remoteInputDpm);
+
+        if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) {
+            final boolean remoteInput = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT,
+                    0,
+                    mCurrentUserId) != 0;
+            final boolean remoteInputDpm =
+                    (dpmFlags & DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT) == 0;
+
+            setLockScreenAllowRemoteInput(remoteInput && remoteInputDpm);
+        } else {
+            setLockScreenAllowRemoteInput(false);
+        }
     }
 
     protected abstract void setAreThereNotifications();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 68e5d0b..fa57775 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -29,6 +29,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
+import android.service.quicksettings.Tile;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
@@ -399,10 +400,11 @@
             String tileSpec = previousTiles.get(i);
             if (!tileSpec.startsWith(CustomTile.PREFIX)) continue;
             if (!newTiles.contains(tileSpec)) {
-                Intent intent = new Intent().setComponent(
-                        CustomTile.getComponentFromSpec(tileSpec));
+                ComponentName component = CustomTile.getComponentFromSpec(tileSpec);
+                Intent intent = new Intent().setComponent(component);
                 TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
-                        mContext, intent, new UserHandle(ActivityManager.getCurrentUser()));
+                        mContext, mServices, new Tile(component), intent,
+                        new UserHandle(ActivityManager.getCurrentUser()));
                 lifecycleManager.onStopListening();
                 lifecycleManager.onTileRemoved();
                 lifecycleManager.flushMessagesAndUnbind();
@@ -412,10 +414,11 @@
             String tileSpec = newTiles.get(i);
             if (!tileSpec.startsWith(CustomTile.PREFIX)) continue;
             if (!previousTiles.contains(tileSpec)) {
-                Intent intent = new Intent().setComponent(
-                        CustomTile.getComponentFromSpec(tileSpec));
+                ComponentName component = CustomTile.getComponentFromSpec(tileSpec);
+                Intent intent = new Intent().setComponent(component);
                 TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
-                        mContext, intent, new UserHandle(ActivityManager.getCurrentUser()));
+                        mContext, mServices, new Tile(component), intent,
+                        new UserHandle(ActivityManager.getCurrentUser()));
                 lifecycleManager.onTileAdded();
                 lifecycleManager.flushMessagesAndUnbind();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 43f847c2..71ef1ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -1961,8 +1961,7 @@
                 // we're ending up at the same location as we are now, lets just skip the animation
                 bottom = finalBottom;
             } else {
-                bottom = (int) (lastView.getTranslationY() + lastView.getActualHeight()
-                        - lastView.getExtraBottomPadding());
+                bottom = (int) (lastView.getTranslationY() + lastView.getActualHeight());
                 bottom = Math.min(bottom, getHeight());
             }
         } else {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
index a30f507..c93377a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
@@ -36,6 +36,8 @@
 import android.util.ArraySet;
 import android.util.Log;
 
+import org.mockito.Mockito;
+
 @SmallTest
 public class TileLifecycleManagerTests extends AndroidTestCase {
     public static final String TILE_UPDATE_BROADCAST = "com.android.systemui.tests.TILE_UPDATE";
@@ -54,8 +56,11 @@
         mThread = new HandlerThread("TestThread");
         mThread.start();
         mHandler = new Handler(mThread.getLooper());
+        ComponentName component = new ComponentName(mContext, FakeTileService.class);
         mStateManager = new TileLifecycleManager(mHandler, getContext(),
-                new Intent(mContext, FakeTileService.class), new UserHandle(UserHandle.myUserId()));
+                Mockito.mock(IQSService.class), new Tile(component),
+                new Intent().setComponent(component),
+                new UserHandle(UserHandle.myUserId()));
         mCallbacks.clear();
         getContext().registerReceiver(mReceiver, new IntentFilter(TILE_UPDATE_BROADCAST));
     }
@@ -251,16 +256,6 @@
         @Override
         public IBinder onBind(Intent intent) {
             return new IQSTileService.Stub() {
-
-                @Override
-                public void setQSService(IQSService service) {
-
-                }
-
-                @Override
-                public void setQSTile(Tile tile) throws RemoteException {
-                }
-
                 @Override
                 public void onTileAdded() throws RemoteException {
                     sendCallback("onTileAdded");
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java
index 94c98d6..de3864d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java
@@ -17,6 +17,7 @@
 
 import android.content.ComponentName;
 import android.os.Looper;
+import android.service.quicksettings.Tile;
 import android.test.suitebuilder.annotation.SmallTest;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.phone.QSTileHost;
@@ -109,7 +110,7 @@
         }
 
         @Override
-        protected TileServiceManager onCreateTileService(ComponentName component) {
+        protected TileServiceManager onCreateTileService(ComponentName component, Tile qsTile) {
             TileServiceManager manager = Mockito.mock(TileServiceManager.class);
             mManagers.add(manager);
             return manager;
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 4e0ddd6..2a30229 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -20,6 +20,7 @@
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 
+import android.annotation.UserIdInt;
 import android.app.AlarmManager;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
@@ -66,6 +67,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.storage.StorageManager;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.AtomicFile;
@@ -647,7 +649,7 @@
     }
 
     private void ensureGroupStateLoadedLocked(int userId, boolean enforceUserUnlockingOrUnlocked) {
-        if (enforceUserUnlockingOrUnlocked && !mUserManager.isUserUnlockingOrUnlocked(userId)) {
+        if (enforceUserUnlockingOrUnlocked && !isUserRunningAndUnlocked(userId)) {
             throw new IllegalStateException(
                     "User " + userId + " must be unlocked for widgets to be available");
         }
@@ -692,6 +694,10 @@
         loadGroupStateLocked(newProfileIds);
     }
 
+    private boolean isUserRunningAndUnlocked(@UserIdInt int userId) {
+        return mUserManager.isUserRunning(userId) && StorageManager.isUserKeyUnlocked(userId);
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP,
@@ -3358,7 +3364,7 @@
             if (userInfo != null && userInfo.isManagedProfile()) {
                 UserInfo parentInfo = mUserManager.getProfileParent(userId);
                 if (parentInfo != null
-                        && !mUserManager.isUserUnlockingOrUnlocked(parentInfo.getUserHandle())) {
+                        && !isUserRunningAndUnlocked(parentInfo.getUserHandle().getIdentifier())) {
                     return true;
                 }
             }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 334b228..930c151 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -2356,7 +2356,8 @@
             mConnecting = true;
             mConnectedAgent = null;
             try {
-                if (mActivityManager.bindBackupAgent(app, mode)) {
+                if (mActivityManager.bindBackupAgent(app.packageName, mode,
+                        UserHandle.USER_OWNER)) {
                     Slog.d(TAG, "awaiting agent for " + app);
 
                     // success; wait for the agent to arrive
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index dcd9b0c..7986629 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1443,6 +1443,12 @@
             boolean allowCancel) {
         boolean canceled = false;
 
+        if (mAm.isShuttingDownLocked()) {
+            Slog.w(TAG, "Not scheduling restart of crashed service " + r.shortName
+                    + " - system is shutting down");
+            return false;
+        }
+
         ServiceMap smap = getServiceMap(r.userId);
         if (smap.mServicesByName.get(r.name) != r) {
             ServiceRecord cur = smap.mServicesByName.get(r.name);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9bebef4..e984112 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -102,7 +102,6 @@
 import android.app.PendingIntent;
 import android.app.ProfilerInfo;
 import android.app.admin.DevicePolicyManager;
-import android.app.admin.DevicePolicyManagerInternal;
 import android.app.assist.AssistContent;
 import android.app.assist.AssistStructure;
 import android.app.backup.IBackupManager;
@@ -205,6 +204,7 @@
 import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.DebugUtils;
+import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Pair;
@@ -1513,6 +1513,7 @@
     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
     static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
+    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1523,6 +1524,7 @@
     static KillHandler sKillHandler = null;
 
     CompatModeDialog mCompatModeDialog;
+    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
     long mLastMemUsageReportTime = 0;
 
     /**
@@ -1693,6 +1695,22 @@
                 }
                 break;
             }
+            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
+                synchronized (ActivityManagerService.this) {
+                    final ActivityRecord ar = (ActivityRecord) msg.obj;
+                    if (mUnsupportedDisplaySizeDialog != null) {
+                        mUnsupportedDisplaySizeDialog.dismiss();
+                        mUnsupportedDisplaySizeDialog = null;
+                    }
+                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
+                            ar.packageName)) {
+                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
+                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
+                        mUnsupportedDisplaySizeDialog.show();
+                    }
+                }
+                break;
+            }
             case START_USER_SWITCH_UI_MSG: {
                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
                 break;
@@ -3099,6 +3117,16 @@
         mUiHandler.sendMessage(msg);
     }
 
+    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
+        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
+                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
+            final Message msg = Message.obtain();
+            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
+            msg.obj = r;
+            mUiHandler.sendMessage(msg);
+        }
+    }
+
     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
             String what, Object obj, ProcessRecord srcApp) {
         app.lastActivityTime = now;
@@ -11472,11 +11500,15 @@
 
     // Actually is sleeping or shutting down or whatever else in the future
     // is an inactive state.
-    public boolean isSleepingOrShuttingDown() {
-        return isSleeping() || mShuttingDown;
+    boolean isSleepingOrShuttingDownLocked() {
+        return isSleepingLocked() || mShuttingDown;
     }
 
-    public boolean isSleeping() {
+    boolean isShuttingDownLocked() {
+        return mShuttingDown;
+    }
+
+    boolean isSleepingLocked() {
         return mSleeping;
     }
 
@@ -12846,7 +12878,7 @@
                     proc.notCachedSinceIdle = true;
                     proc.initialIdlePss = 0;
                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
-                            mTestPssMode, isSleeping(), now);
+                            mTestPssMode, isSleepingLocked(), now);
                 }
             }
 
@@ -17038,11 +17070,22 @@
     // Cause the target app to be launched if necessary and its backup agent
     // instantiated.  The backup agent will invoke backupAgentCreated() on the
     // activity manager to announce its creation.
-    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
-        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
-                "bindBackupAgent: app=" + app + " mode=" + backupMode);
+    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
+        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
 
+        IPackageManager pm = AppGlobals.getPackageManager();
+        ApplicationInfo app = null;
+        try {
+            app = pm.getApplicationInfo(packageName, 0, userId);
+        } catch (RemoteException e) {
+            // can't happen; package manager is process-local
+        }
+        if (app == null) {
+            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
+            return false;
+        }
+
         synchronized(this) {
             // !!! TODO: currently no check here that we're already bound
             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
@@ -17749,6 +17792,14 @@
                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
 
                                         removeTasksByPackageNameLocked(ssp, userId);
+
+                                        // Hide the "unsupported display" dialog if necessary.
+                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
+                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
+                                            mUnsupportedDisplaySizeDialog.dismiss();
+                                            mUnsupportedDisplaySizeDialog = null;
+                                        }
+                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
                                         mBatteryStatsService.notePackageUninstalled(ssp);
                                     }
                                 } else {
@@ -17820,6 +17871,21 @@
                     }
                     break;
                 }
+                case Intent.ACTION_PACKAGE_DATA_CLEARED:
+                {
+                    Uri data = intent.getData();
+                    String ssp;
+                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
+                        // Hide the "unsupported display" dialog if necessary.
+                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
+                                mUnsupportedDisplaySizeDialog.getPackageName())) {
+                            mUnsupportedDisplaySizeDialog.dismiss();
+                            mUnsupportedDisplaySizeDialog = null;
+                        }
+                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
+                    }
+                    break;
+                }
                 case Intent.ACTION_TIMEZONE_CHANGED:
                     // If this is the time zone changed action, queue up a message that will reset
                     // the timezone of all currently running processes. This message will get
@@ -18642,6 +18708,9 @@
 
                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
                 if (isDensityChange) {
+                    // Reset the unsupported display size dialog.
+                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
+
                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
                 }
@@ -18711,7 +18780,7 @@
                 starting = mainStack.topRunningActivityLocked();
             }
 
-            if (starting != null) {
+            if (starting != null && starting.state != ActivityState.STOPPED) {
                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
                 // And we need to make sure at this point that all other activities
                 // are made visible with the correct configuration.
@@ -19742,7 +19811,7 @@
             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
                 app.pssProcState = app.setProcState;
                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
-                        mTestPssMode, isSleeping(), now);
+                        mTestPssMode, isSleepingLocked(), now);
                 mPendingPssProcesses.add(app);
             }
         }
@@ -19790,7 +19859,7 @@
             }
         }
         return !processingBroadcasts
-                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
+                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
     }
 
     /**
@@ -20081,7 +20150,7 @@
             }
             app.lastStateTime = now;
             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
-                    mTestPssMode, isSleeping(), now);
+                    mTestPssMode, isSleepingLocked(), now);
             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
                     + ProcessList.makeProcStateString(app.setProcState) + " to "
                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
@@ -20092,7 +20161,7 @@
                     mTestPssMode)))) {
                 requestPssLocked(app, app.setProcState);
                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
-                        mTestPssMode, isSleeping(), now);
+                        mTestPssMode, isSleepingLocked(), now);
             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
         }
@@ -20618,7 +20687,7 @@
         }
         mLastMemoryLevel = memFactor;
         mLastNumProcesses = mLruProcesses.size();
-        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
+        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
             if (mLowRamStartTime == 0) {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 3ccac9e..37d7c33 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -931,7 +931,7 @@
         final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
         boolean unsent = true;
         if ((state == ActivityState.RESUMED
-                || (service.isSleeping() && task.stack != null
+                || (service.isSleepingLocked() && task.stack != null
                     && task.stack.topRunningActivityLocked() == this))
                 && app != null && app.thread != null) {
             try {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 27145fc..6af7a5d 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1075,7 +1075,7 @@
         if (mPausingActivity != null) {
             Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
                     + " state=" + mPausingActivity.state);
-            if (!mService.isSleeping()) {
+            if (!mService.isSleepingLocked()) {
                 // Avoid recursion among check for sleep and complete pause during sleeping.
                 // Because activity will be paused immediately after resume, just let pause
                 // be completed by the order of activity paused from clients.
@@ -1139,7 +1139,7 @@
 
         // If we are not going to sleep, we want to ensure the device is
         // awake until the next activity is started.
-        if (!uiSleeping && !mService.isSleepingOrShuttingDown()) {
+        if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
             mStackSupervisor.acquireLaunchWakelock();
         }
 
@@ -1292,7 +1292,7 @@
                     // We don't need to schedule another stop, we only need to let it happen.
                     prev.state = ActivityState.STOPPING;
                 } else if ((!prev.visible && !hasVisibleBehindActivity())
-                        || mService.isSleepingOrShuttingDown()) {
+                        || mService.isSleepingOrShuttingDownLocked()) {
                     // If we were visible then resumeTopActivities will release resources before
                     // stopping.
                     addToStopping(prev, true /* immediate */);
@@ -1310,7 +1310,7 @@
 
         if (resumeNext) {
             final ActivityStack topStack = mStackSupervisor.getFocusedStack();
-            if (!mService.isSleepingOrShuttingDown()) {
+            if (!mService.isSleepingOrShuttingDownLocked()) {
                 mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
             } else {
                 mStackSupervisor.checkReadyForSleepLocked();
@@ -1820,7 +1820,8 @@
             boolean stackVisibleBehind, ActivityRecord visibleBehind,
             boolean behindFullscreenActivity) {
 
-        if (!okToShowLocked(r)) {
+        if (!okToShowLocked(r)
+                || (mService.isSleepingOrShuttingDownLocked() && r.voiceSession == null)) {
             return false;
         }
 
@@ -2195,7 +2196,7 @@
 
         // If we are sleeping, and there is no resumed activity, and the top
         // activity is paused, well that is the state we want.
-        if (mService.isSleepingOrShuttingDown()
+        if (mService.isSleepingOrShuttingDownLocked()
                 && mLastPausedActivity == next
                 && mStackSupervisor.allPausedActivitiesComplete()) {
             // Make sure we have executed any pending transitions, since there
@@ -2277,7 +2278,7 @@
         // If the most recent activity was noHistory but was only stopped rather
         // than stopped+finished because the device went to sleep, we need to make
         // sure to finish it as we're making a new activity topmost.
-        if (mService.isSleeping() && mLastNoHistoryActivity != null &&
+        if (mService.isSleepingLocked() && mLastNoHistoryActivity != null &&
                 !mLastNoHistoryActivity.finishing) {
             if (DEBUG_STATES) Slog.d(TAG_STATES,
                     "no-history finish of " + mLastNoHistoryActivity + " on new resume");
@@ -2480,6 +2481,7 @@
                         System.identityHashCode(next), next.task.taskId, next.shortComponentName);
 
                 next.sleeping = false;
+                mService.showUnsupportedZoomDialogIfNeededLocked(next);
                 mService.showAskCompatModeDialogLocked(next);
                 next.app.pendingUiClean = true;
                 next.app.forceProcessStateUpTo(mService.mTopProcessState);
@@ -3211,7 +3213,7 @@
         if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
             if (!r.finishing) {
-                if (!mService.isSleeping()) {
+                if (!mService.isSleepingLocked()) {
                     if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
                     if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                             "stop-no-history", false)) {
@@ -3243,7 +3245,7 @@
                 EventLogTags.writeAmStopActivity(
                         r.userId, System.identityHashCode(r), r.shortComponentName);
                 r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
-                if (mService.isSleepingOrShuttingDown()) {
+                if (mService.isSleepingOrShuttingDownLocked()) {
                     r.setSleeping(true);
                 }
                 Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 7a43d53..738622fd 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1217,6 +1217,7 @@
                                       PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
             r.sleeping = false;
             r.forceNewConfig = false;
+            mService.showUnsupportedZoomDialogIfNeededLocked(r);
             mService.showAskCompatModeDialogLocked(r);
             r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
             ProfilerInfo profilerInfo = null;
@@ -2707,7 +2708,7 @@
     }
 
     void checkReadyForSleepLocked() {
-        if (!mService.isSleepingOrShuttingDown()) {
+        if (!mService.isSleepingOrShuttingDownLocked()) {
             // Do not care.
             return;
         }
@@ -3047,7 +3048,7 @@
                     mWindowManager.setAppVisibility(s.appToken, false);
                 }
             }
-            if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
+            if ((!waitingVisible || mService.isSleepingOrShuttingDownLocked()) && remove) {
                 if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
                 if (stops == null) {
                     stops = new ArrayList<>();
@@ -3771,7 +3772,7 @@
                 } break;
                 case SLEEP_TIMEOUT_MSG: {
                     synchronized (mService) {
-                        if (mService.isSleepingOrShuttingDown()) {
+                        if (mService.isSleepingOrShuttingDownLocked()) {
                             Slog.w(TAG, "Sleep timeout!  Sleeping now.");
                             mSleepTimeout = true;
                             checkReadyForSleepLocked();
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 522e42b..e425484 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1465,14 +1465,23 @@
                                 intentActivity.task, mNoAnimation, mOptions,
                                 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
                         mMovedToFront = true;
-                    } else if ((launchStack.mStackId == DOCKED_STACK_ID
-                            || launchStack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID)
-                            && (mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
-                        // If we want to launch adjacent and mTargetStack is not the computed
-                        // launch stack - move task to top of computed stack.
-                        mSupervisor.moveTaskToStackLocked(intentActivity.task.taskId,
-                                launchStack.mStackId, ON_TOP, FORCE_FOCUS, "launchToSide",
-                                ANIMATE);
+                    } else if (launchStack.mStackId == DOCKED_STACK_ID
+                            || launchStack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
+                        if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
+                            // If we want to launch adjacent and mTargetStack is not the computed
+                            // launch stack - move task to top of computed stack.
+                            mSupervisor.moveTaskToStackLocked(intentActivity.task.taskId,
+                                    launchStack.mStackId, ON_TOP, FORCE_FOCUS, "launchToSide",
+                                    ANIMATE);
+                        } else {
+                            // TODO: This should be reevaluated in MW v2.
+                            // We choose to move task to front instead of launching it adjacent
+                            // when specific stack was requested explicitly and it appeared to be
+                            // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
+                            mTargetStack.moveTaskToFrontLocked(intentActivity.task, mNoAnimation,
+                                    mOptions, mStartActivity.appTimeTracker,
+                                    "bringToFrontInsteadOfAdjacentLaunch");
+                        }
                         mMovedToFront = true;
                     }
                     mOptions = null;
diff --git a/services/core/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java
index 26264e5..a54df4b 100644
--- a/services/core/java/com/android/server/am/CompatModePackages.java
+++ b/services/core/java/com/android/server/am/CompatModePackages.java
@@ -57,6 +57,8 @@
     public static final int COMPAT_FLAG_DONT_ASK = 1<<0;
     // Compatibility state: compatibility mode is enabled.
     public static final int COMPAT_FLAG_ENABLED = 1<<1;
+    // Unsupported zoom state: don't warn the user about unsupported zoom mode.
+    public static final int UNSUPPORTED_ZOOM_FLAG_DONT_NOTIFY = 1<<2;
 
     private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>();
 
@@ -147,6 +149,24 @@
         return flags != null ? flags : 0;
     }
 
+    public void handlePackageDataClearedLocked(String packageName) {
+        // User has explicitly asked to clear all associated data.
+        removePackage(packageName);
+    }
+
+    public void handlePackageUninstalledLocked(String packageName) {
+        // Clear settings when app is uninstalled since this is an explicit
+        // signal from the user to remove the app and all associated data.
+        removePackage(packageName);
+    }
+
+    private void removePackage(String packageName) {
+        if (mPackages.containsKey(packageName)) {
+            mPackages.remove(packageName);
+            scheduleWrite();
+        }
+    }
+
     public void handlePackageAddedLocked(String packageName, boolean updated) {
         ApplicationInfo ai = null;
         try {
@@ -165,13 +185,17 @@
             // any current settings for it.
             if (!mayCompat && mPackages.containsKey(packageName)) {
                 mPackages.remove(packageName);
-                mHandler.removeMessages(MSG_WRITE);
-                Message msg = mHandler.obtainMessage(MSG_WRITE);
-                mHandler.sendMessageDelayed(msg, 10000);
+                scheduleWrite();
             }
         }
     }
 
+    private void scheduleWrite() {
+        mHandler.removeMessages(MSG_WRITE);
+        Message msg = mHandler.obtainMessage(MSG_WRITE);
+        mHandler.sendMessageDelayed(msg, 10000);
+    }
+
     public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
         CompatibilityInfo ci = new CompatibilityInfo(ai, mService.mConfiguration.screenLayout,
                 mService.mConfiguration.smallestScreenWidthDp,
@@ -207,6 +231,10 @@
         return (getPackageFlags(packageName)&COMPAT_FLAG_DONT_ASK) == 0;
     }
 
+    public boolean getPackageNotifyUnsupportedZoomLocked(String packageName) {
+        return (getPackageFlags(packageName)&UNSUPPORTED_ZOOM_FLAG_DONT_NOTIFY) == 0;
+    }
+
     public void setFrontActivityAskCompatModeLocked(boolean ask) {
         ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked();
         if (r != null) {
@@ -223,9 +251,21 @@
             } else {
                 mPackages.remove(packageName);
             }
-            mHandler.removeMessages(MSG_WRITE);
-            Message msg = mHandler.obtainMessage(MSG_WRITE);
-            mHandler.sendMessageDelayed(msg, 10000);
+            scheduleWrite();
+        }
+    }
+
+    public void setPackageNotifyUnsupportedZoomLocked(String packageName, boolean notify) {
+        final int curFlags = getPackageFlags(packageName);
+        final int newFlags = notify ? (curFlags&~UNSUPPORTED_ZOOM_FLAG_DONT_NOTIFY) :
+                (curFlags|UNSUPPORTED_ZOOM_FLAG_DONT_NOTIFY);
+        if (curFlags != newFlags) {
+            if (newFlags != 0) {
+                mPackages.put(packageName, newFlags);
+            } else {
+                mPackages.remove(packageName);
+            }
+            scheduleWrite();
         }
     }
 
@@ -321,9 +361,7 @@
             // Need to get compatibility info in new state.
             ci = compatibilityInfoForPackageLocked(ai);
 
-            mHandler.removeMessages(MSG_WRITE);
-            Message msg = mHandler.obtainMessage(MSG_WRITE);
-            mHandler.sendMessageDelayed(msg, 10000);
+            scheduleWrite();
 
             final ActivityStack stack = mService.getFocusedStack();
             ActivityRecord starting = stack.restartPackage(packageName);
diff --git a/services/core/java/com/android/server/am/UnsupportedDisplaySizeDialog.java b/services/core/java/com/android/server/am/UnsupportedDisplaySizeDialog.java
new file mode 100644
index 0000000..501cd6b
--- /dev/null
+++ b/services/core/java/com/android/server/am/UnsupportedDisplaySizeDialog.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2011 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.server.am;
+
+import com.android.internal.R;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.CheckBox;
+
+public class UnsupportedDisplaySizeDialog {
+    private final AlertDialog mDialog;
+    private final String mPackageName;
+
+    public UnsupportedDisplaySizeDialog(final ActivityManagerService service, Context context,
+            ApplicationInfo appInfo) {
+        mPackageName = appInfo.packageName;
+
+        final PackageManager pm = context.getPackageManager();
+        final CharSequence label = appInfo.loadSafeLabel(pm);
+        final CharSequence message = context.getString(
+                R.string.unsupported_display_size_message, label);
+
+        mDialog = new AlertDialog.Builder(context)
+                .setPositiveButton(R.string.ok, null)
+                .setMessage(message)
+                .setView(R.layout.unsupported_display_size_dialog_content)
+                .create();
+
+        // Ensure the content view is prepared.
+        mDialog.create();
+
+        final Window window = mDialog.getWindow();
+        window.setType(WindowManager.LayoutParams.TYPE_PHONE);
+
+        // DO NOT MODIFY. Used by CTS to verify the dialog is displayed.
+        window.getAttributes().setTitle("UnsupportedDisplaySizeDialog");
+
+        final CheckBox alwaysShow = (CheckBox) mDialog.findViewById(R.id.ask_checkbox);
+        alwaysShow.setChecked(true);
+        alwaysShow.setOnCheckedChangeListener((buttonView, isChecked) -> {
+            synchronized (service) {
+                service.mCompatModePackages.setPackageNotifyUnsupportedZoomLocked(
+                        mPackageName, isChecked);
+            }
+        });
+    }
+
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    public void show() {
+        mDialog.show();
+    }
+
+    public void dismiss() {
+        mDialog.dismiss();
+    }
+}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index a85064b..4c515f0 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1303,14 +1303,16 @@
         }
 
         if (mAppOpsService != null) { // We skip it until system-ready.
-            final long token = Binder.clearCallingIdentity();
-            try {
-                mAppOpsService.setUserRestrictions(effective, mUserRestriconToken, userId);
-            } catch (RemoteException e) {
-                Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions");
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        mAppOpsService.setUserRestrictions(effective, mUserRestriconToken, userId);
+                    } catch (RemoteException e) {
+                        Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions");
+                    }
+                }
+            });
         }
 
         propagateUserRestrictionsLR(userId, effective, prevAppliedRestrictions);
@@ -2296,7 +2298,7 @@
      */
     @Override
     public UserInfo createRestrictedProfile(String name, int parentUserId) {
-        checkManageUsersPermission("setupRestrictedProfile");
+        checkManageOrCreateUsersPermission("setupRestrictedProfile");
         final UserInfo user = createProfileForUser(name, UserInfo.FLAG_RESTRICTED, parentUserId);
         if (user == null) {
             return null;