Merge "Fixed a bug where the system could crash when expanding" into nyc-mr1-dev
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp
index 6d30f0d..ab6adfb 100644
--- a/cmds/idmap/scan.cpp
+++ b/cmds/idmap/scan.cpp
@@ -1,5 +1,6 @@
 #include <dirent.h>
 #include <inttypes.h>
+#include <sys/file.h>
 #include <sys/stat.h>
 
 #include "idmap.h"
@@ -35,16 +36,31 @@
 
     bool writePackagesList(const char *filename, const SortedVector<Overlay>& overlayVector)
     {
-        FILE* fout = fopen(filename, "w");
+        // the file is opened for appending so that it doesn't get truncated
+        // before we can guarantee mutual exclusion via the flock
+        FILE* fout = fopen(filename, "a");
         if (fout == NULL) {
             return false;
         }
 
+        if (TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_EX)) != 0) {
+            fclose(fout);
+            return false;
+        }
+
+        if (TEMP_FAILURE_RETRY(ftruncate(fileno(fout), 0)) != 0) {
+            TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN));
+            fclose(fout);
+            return false;
+        }
+
         for (size_t i = 0; i < overlayVector.size(); ++i) {
             const Overlay& overlay = overlayVector[i];
             fprintf(fout, "%s %s\n", overlay.apk_path.string(), overlay.idmap_path.string());
         }
 
+        TEMP_FAILURE_RETRY(fflush(fout));
+        TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN));
         fclose(fout);
 
         // Make file world readable since Zygote (running as root) will read
@@ -171,9 +187,6 @@
 {
     String8 filename = String8(idmap_dir);
     filename.appendPath("overlays.list");
-    if (unlink(filename.string()) != 0 && errno != ENOENT) {
-        return EXIT_FAILURE;
-    }
 
     SortedVector<Overlay> overlayVector;
     const size_t N = overlay_dirs->size();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 1103d9e..0dd9c63 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1049,6 +1049,7 @@
             this(Icon.createWithResource("", icon), title, intent, new Bundle(), null, false);
         }
 
+        /** Keep in sync with {@link Notification.Action.Builder#Builder(Action)}! */
         private Action(Icon icon, CharSequence title, PendingIntent intent, Bundle extras,
                 RemoteInput[] remoteInputs, boolean allowGeneratedReplies) {
             this.mIcon = icon;
@@ -1115,7 +1116,7 @@
              */
             @Deprecated
             public Builder(int icon, CharSequence title, PendingIntent intent) {
-                this(Icon.createWithResource("", icon), title, intent, new Bundle(), null);
+                this(Icon.createWithResource("", icon), title, intent);
             }
 
             /**
@@ -1125,7 +1126,7 @@
              * @param intent the {@link PendingIntent} to fire when users trigger this action
              */
             public Builder(Icon icon, CharSequence title, PendingIntent intent) {
-                this(icon, title, intent, new Bundle(), null);
+                this(icon, title, intent, new Bundle(), null, false);
             }
 
             /**
@@ -1134,12 +1135,13 @@
              * @param action the action to read fields from.
              */
             public Builder(Action action) {
-                this(action.getIcon(), action.title, action.actionIntent, new Bundle(action.mExtras),
-                        action.getRemoteInputs());
+                this(action.getIcon(), action.title, action.actionIntent,
+                        new Bundle(action.mExtras), action.getRemoteInputs(),
+                        action.getAllowGeneratedReplies());
             }
 
             private Builder(Icon icon, CharSequence title, PendingIntent intent, Bundle extras,
-                    RemoteInput[] remoteInputs) {
+                    RemoteInput[] remoteInputs, boolean allowGeneratedReplies) {
                 mIcon = icon;
                 mTitle = title;
                 mIntent = intent;
@@ -1148,6 +1150,7 @@
                     mRemoteInputs = new ArrayList<RemoteInput>(remoteInputs.length);
                     Collections.addAll(mRemoteInputs, remoteInputs);
                 }
+                mAllowGeneratedReplies = allowGeneratedReplies;
             }
 
             /**
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index cd248ea..96ad67c 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -329,7 +329,7 @@
  * <p>Applications with a foreground activity or service are not rate-limited.
  *
  * <p>Rate-limiting will be reset upon certain events, so that even background applications
- * can call these APIs again until they are rate limit is reached again.
+ * can call these APIs again until the rate limit is reached again.
  * These events include the following:
  * <ul>
  *   <li>When an application comes to the foreground.
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index d9cb269..4d405c5 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -467,6 +467,14 @@
      * {@link #setImageBitmap(android.graphics.Bitmap)} and
      * {@link android.graphics.BitmapFactory} instead.</p>
      *
+     * <p class="note">On devices running SDK < 24, this method will fail to
+     * apply correct density scaling to images loaded from
+     * {@link ContentResolver#SCHEME_CONTENT content} and
+     * {@link ContentResolver#SCHEME_FILE file} schemes. Applications running
+     * on devices with SDK >= 24 <strong>MUST</strong> specify the
+     * {@code targetSdkVersion} in their manifest as 24 or above for density
+     * scaling to be applied to images loaded from these schemes.</p>
+     *
      * @param uri the Uri of an image, or {@code null} to clear the content
      */
     @android.view.RemotableViewMethod(asyncImpl="setImageURIAsync")
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index 7200d47..6185dab 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -289,6 +289,8 @@
   to: /design/patterns/app-structure.html
 - from: /guide/practices/ui_guidelines/menu_design.html
   to: /design/patterns/actionbar.html
+- from: /design/patterns/accessibility.html
+  to: https://material.google.com/usability/accessibility.html
 - from: /design/get-started/ui-overview.html
   to: /design/handhelds/index.html
 - from: /design/building-blocks/buttons.html
diff --git a/docs/html/design/_book.yaml b/docs/html/design/_book.yaml
index 18b4719..8ffa9a4 100644
--- a/docs/html/design/_book.yaml
+++ b/docs/html/design/_book.yaml
@@ -117,8 +117,6 @@
     path: /design/patterns/pure-android.html
   - title: Compatibility
     path: /design/patterns/compatibility.html
-  - title: Accessibility
-    path: /design/patterns/accessibility.html
   - title: Help
     path: /design/patterns/help.html
 
diff --git a/docs/html/design/patterns/accessibility.jd b/docs/html/design/patterns/accessibility.jd
deleted file mode 100644
index b910294..0000000
--- a/docs/html/design/patterns/accessibility.jd
+++ /dev/null
@@ -1,98 +0,0 @@
-page.title=Accessibility
-page.tags="accessibility","navigation","input"
-page.metaDescription=Design an app that's universally accessible to people with visual impairment, color deficiency, hearing loss, and limited dexterity.
-@jd:body
-
-<a class="notice-designers-material"
-  href="http://www.google.com/design/spec/usability/accessibility.html">
-  <div>
-    <h3>Material Design</h3>
-    <p>Accessibility<p>
-  </div>
-</a>
-
-<a class="notice-developers" href="{@docRoot}training/accessibility/index.html">
-  <div>
-    <h3>Developer Docs</h3>
-    <p>Implementing Accessibility</p>
-  </div>
-</a>
-
-<p>One of Android's missions is to organize the world's information and make it universally accessible and useful. Accessibility is the measure of how successfully a product can be used by people with varying abilities. Our mission applies to all users-including people with disabilities such as visual impairment, color deficiency, hearing loss, and limited dexterity.</p>
-<p><a href="https://www.google.com/#hl=en&q=universal+design&fp=1">Universal design</a> is the practice of making products that are inherently accessible to all users, regardless of ability. The Android design patterns were created in accordance with universal design principles, and following them will help your app meet basic usability standards. Adhering to universal design and enabling Android's accessibility tools will make your app as accessible as possible.</p>
-<p>Robust support for accessibility will increase your app's user base. It may also be required for adoption by some organizations.</p>
-<p><a href="http://www.google.com/accessibility/">Learn more about Google and accessibility.</a></p>
-
-<h2 id="tools">Android's Accessibility Tools</h2>
-<p>Android includes several features that support access for users with visual impairments; they don't require drastic visual changes to your app.</p>
-
-<ul>
-  <li><strong><a href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">TalkBack</a></strong> is a pre-installed screen reader service provided by Google. It uses spoken feedback to describe the results of actions such as launching an app, and events such as notifications.</li>
-  <li><strong>Explore by Touch</strong> is a system feature that works with TalkBack, allowing you to touch your device's screen and hear what's under your finger via spoken feedback. This feature is helpful to users with low vision.</li>
-  <li><strong>Accessibility settings</strong> let you modify your device's display and sound options, such as increasing the text size, changing the speed at which text is spoken, and more.</li>
-</ul>
-
-<p>Some users use hardware or software directional controllers (such as a D-pad, trackball, keyboard) to jump from selection to selection on a screen. They interact with the structure of your app in a linear fashion, similar to 4-way remote control navigation on a television.</p>
-
-<h2 id="tools">Guidelines</h2>
-<p>The Android design principle "I should always know where I am" is key for accessibility concerns. As a user navigates through an application, they need feedback and a mental model of where they are. All users benefit from a strong sense of information hierarchy and an architecture that makes sense. Most users benefit from visual and haptic feedback during their navigation (such as labels, colors, icons, touch feedback) Low vision users benefit from explicit verbal descriptions and large visuals with high contrast.</p>
-<p>As you design your app, think about the labels and notations needed to navigate your app by sound. When using Explore by Touch, the user enables an invisible but audible layer of structure in your application. Like any other aspect of app design, this structure can be simple, elegant, and robust. The following are Android's recommended guidelines to enable effective navigation for all users.</p>
-
-<h4>Make navigation intuitive</h4>
-<p>Design well-defined, clear task flows with minimal navigation steps, especially for major user tasks. Make sure those tasks are navigable via focus controls. </p>
-
-<h4>Use recommended touch target sizes</h4>
-<p>48 dp is the recommended touch target size for on screen elements. Read about <a href="{@docRoot}design/style/metrics-grids.html">Android Metrics and Grids</a> to learn about implementation strategies to help most of your users. For certain users, it may be appropriate to use larger touch targets. An example of this is educational apps, where buttons larger than the minimum recommendations are appropriate for children with developing motor skills and people with manual dexterity challenges.</p>
-
-
-<h4>Label visual UI elements meaningfully</h4>
-<p>In your wireframes, <a href="{@docRoot}guide/topics/ui/accessibility/apps.html#label-ui">label functional UI components</a> that have no visible text. Those components might be buttons, icons, tabs with icons, and icons with state (like stars). Developers can use the <code><a href="{@docRoot}guide/topics/ui/accessibility/apps.html#label-ui">contentDescription</a></code> attribute to set the label.</p>
-
-<div class ="cols">
-    <div class="col-8">
-      <img src="{@docRoot}design/media/accessibility_contentdesc.png">
-    </div>
-    <div class="col-5 with-callouts">
-      <ol>
-        <li class="value-1">group</li>
-        <li class="value-2">all contacts</li>
-        <li class="value-3">favorites</li>
-        <li class="value-4">search</li>
-        <li class="value-5">action overflow button</li>
-        <li class="value-6">
-          <em>when starred:</em> remove from favorites </br>
-          <em>when not starred:</em> add to favorties</li>
-        <li class="value-7">action overflow button</li>
-        <li class="value-8">text message</li>
-      </ol>
-  </div>
-</div>
-
-<h4>Provide alternatives to affordances that time out</h4>
-<p>Your app may have icons or controls that disappear after a certain amount of time. For example, five seconds after starting a video, playback controls may fade from the screen.</p>
-
-<p>Due to the way that TalkBack works, those controls are not read out loud unless they are focused on. If they fade out from the screen quickly, your user may not even be aware that they are available. Therefore, make sure that you are not relying on timed out controls for high priority task flows. (This is a good universal design guideline too.) If the controls enable an important function, make sure that the user can turn on the controls again and/or their function is duplicated elsewhere. You can also change the behavior of your app when accessibility services are turned on. Your developer may be able to make sure that timed-out controls won't disappear.</p>
-
-<h4>Use standard framework controls or enable TalkBack for custom controls</h4>
-<p>Standard Android framework controls work automatically with accessibility services and have ContentDescriptions built in by default.</p>
-
-<p>An oft-overlooked system control is font size. Users can turn on a system-wide large font size in Settings; using the default system font size in your application will enable the user's preferences in your app as well. To enable system font size in your app, mark text and their associated containers to be measured in <a href="{@docRoot}guide/practices/screens_support.html#screen-independence">scale pixels</a>.</p>
-
-<p>Also, keep in mind that when users have large fonts enabled or speak a different language than you, their type might be larger than the space you've allotted for it. Read <a href="{@docRoot}design/style/devices-displays.html">Devices and Displays</a> and <a href="http://developer.android.com/guide/practices/screens_support.html">Supporting Multiple Screens</a> for design strategies.</p>
-
-<p>If you use custom controls, Android has the developer tools in place to allow adherence to the above guidelines and provide meaningful descriptions about the UI. Provide adequate notation on your wireframes and direct your developer to the <a href="{@docRoot}guide/topics/ui/accessibility/apps.html#custom-views">Custom Views</a> documentation.</p>
-
-<h4>Try it out yourself</h4>
-<p>Turn on the TalkBack service in <strong>Settings > Accessibility</strong> and navigate your application using directional controls or eyes-free navigation.</p>
-
-
-
-<h2>Checklist</h2>
-<ul>
-  <li>Make navigation intuitive</li>
-  <li>Use recommended touch target sizes</li>
-  <li>Label visual UI elements meaningfully</li>
-  <li>Provide alternatives to affordances that time out</li>
-  <li>Use standard framework controls or enable TalkBack for custom controls</li>
-  <li>Try it out yourself</li>
-</ul>
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 8ea25d6..07044d0 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -35,6 +35,9 @@
 #include <utils/threads.h>
 #include <utils/Timers.h>
 #include <utils/Trace.h>
+#ifndef _WIN32
+#include <sys/file.h>
+#endif
 
 #include <assert.h>
 #include <dirent.h>
@@ -767,6 +770,12 @@
         return;
     }
 
+#ifndef _WIN32
+    if (TEMP_FAILURE_RETRY(flock(fileno(fin), LOCK_SH)) != 0) {
+        fclose(fin);
+        return;
+    }
+#endif
     char buf[1024];
     while (fgets(buf, sizeof(buf), fin)) {
         // format of each line:
@@ -797,6 +806,10 @@
             const_cast<AssetManager*>(this)->mZipSet.addOverlay(targetPackagePath, oap);
         }
     }
+
+#ifndef _WIN32
+    TEMP_FAILURE_RETRY(flock(fileno(fin), LOCK_UN));
+#endif
     fclose(fin);
 }
 
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 2b79941..aeee661 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -202,7 +202,9 @@
     if (properties.getFillGradient() != nullptr) {
         paint.setColor(applyAlpha(SK_ColorBLACK, properties.getFillAlpha()));
         SkShader* newShader = properties.getFillGradient()->newWithLocalMatrix(matrix);
-        paint.setShader(newShader);
+        // newWithLocalMatrix(...) creates a new SkShader and returns a bare pointer. We need to
+        // remove the extra ref so that the ref count is correctly managed.
+        paint.setShader(newShader)->unref();
         needsFill = true;
     } else if (properties.getFillColor() != SK_ColorTRANSPARENT) {
         paint.setColor(applyAlpha(properties.getFillColor(), properties.getFillAlpha()));
@@ -222,7 +224,9 @@
     if (properties.getStrokeGradient() != nullptr) {
         paint.setColor(applyAlpha(SK_ColorBLACK, properties.getStrokeAlpha()));
         SkShader* newShader = properties.getStrokeGradient()->newWithLocalMatrix(matrix);
-        paint.setShader(newShader);
+        // newWithLocalMatrix(...) creates a new SkShader and returns a bare pointer. We need to
+        // remove the extra ref so that the ref count is correctly managed.
+        paint.setShader(newShader)->unref();
         needsStroke = true;
     } else if (properties.getStrokeColor() != SK_ColorTRANSPARENT) {
         paint.setColor(applyAlpha(properties.getStrokeColor(), properties.getStrokeAlpha()));
diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
index 83b485f..8e0d3ee 100644
--- a/libs/hwui/tests/unit/VectorDrawableTests.cpp
+++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp
@@ -426,5 +426,49 @@
     EXPECT_EQ(1.0f, properties->getPivotY());
 
 }
+
+static SkShader* createShader(bool* isDestroyed) {
+    class TestShader : public SkShader {
+    public:
+        TestShader(bool* isDestroyed) : SkShader(), mDestroyed(isDestroyed) {
+        }
+        ~TestShader() {
+            *mDestroyed = true;
+        }
+
+        Factory getFactory() const override { return nullptr; }
+    private:
+        bool* mDestroyed;
+    };
+    return new TestShader(isDestroyed);
+}
+
+TEST(VectorDrawable, drawPathWithoutIncrementingShaderRefCount) {
+    VectorDrawable::FullPath path("m1 1", 4);
+    SkBitmap bitmap;
+    SkImageInfo info = SkImageInfo::Make(5, 5, kN32_SkColorType, kPremul_SkAlphaType);
+    bitmap.setInfo(info);
+    bitmap.allocPixels(info);
+    SkCanvas canvas(bitmap);
+
+    bool shaderIsDestroyed = false;
+
+    // Initial ref count is 1
+    SkShader* shader = createShader(&shaderIsDestroyed);
+
+    // Setting the fill gradient increments the ref count of the shader by 1
+    path.mutateStagingProperties()->setFillGradient(shader);
+    path.draw(&canvas, SkMatrix::I(), 1.0f, 1.0f, true);
+    // Resetting the fill gradient decrements the ref count of the shader by 1
+    path.mutateStagingProperties()->setFillGradient(nullptr);
+
+    // Expect ref count to be 1 again, i.e. nothing else to have a ref to the shader now. Unref()
+    // again should bring the ref count to zero and consequently trigger detor.
+    shader->unref();
+
+    // Verify that detor is called.
+    EXPECT_TRUE(shaderIsDestroyed);
+}
+
 }; // namespace uirenderer
 }; // namespace android
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 443299e..a74fbf8 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -217,12 +217,6 @@
                 android:permission="android.permission.BIND_WALLPAPER"
                 android:exported="true" />
 
-        <receiver android:name=".BootReceiver" androidprv:systemUserOnly="true">
-            <intent-filter android:priority="1000">
-                <action android:name="android.intent.action.BOOT_COMPLETED" />
-            </intent-filter>
-        </receiver>
-
         <activity android:name=".tuner.TunerActivity"
                   android:enabled="false"
                   android:icon="@drawable/tuner"
diff --git a/packages/SystemUI/res/layout/notification_guts.xml b/packages/SystemUI/res/layout/notification_guts.xml
index e84ed23..17bade4 100644
--- a/packages/SystemUI/res/layout/notification_guts.xml
+++ b/packages/SystemUI/res/layout/notification_guts.xml
@@ -91,6 +91,16 @@
                 style="@style/TextAppearance.NotificationGuts.Radio"
                 android:buttonTint="@color/notification_guts_buttons" />
     </RadioGroup>
+    <!-- When neither blocking or silencing is available -->
+    <TextView
+        android:id="@+id/cant_silence_or_block"
+        android:layout_width="match_parent"
+        android:layout_height="48dp"
+        android:gravity="center_vertical"
+        style="@style/TextAppearance.NotificationGuts.Radio"
+        android:text="@string/cant_silence_or_block"
+        android:visibility="gone"
+        />
     <!-- Importance slider -->
     <LinearLayout
             android:id="@+id/importance_slider"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d13039e..2ea475a 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1666,7 +1666,10 @@
     <!-- accessibility label for button to edit quick settings [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_edit">Edit order of settings.</string>
 
-    <!-- accessibility label for paging indicator in quick settings [CHAR LIMITi=NONE] -->
+    <!-- accessibility label for paging indicator in quick settings [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_page">Page <xliff:g name="current_page" example="1">%1$d</xliff:g> of <xliff:g name="num_pages" example="2">%2$d</xliff:g></string>
 
+    <!-- Label that replaces other notification controls when the notification is from the system
+         and cannot be silenced (see @string/show_silently) or blocked (see @string/block) -->
+    <string name="cant_silence_or_block">Notifications can\'t be silenced or blocked</string>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 98957dd..4866fca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -829,7 +829,7 @@
             Slog.e(TAG, "Failed to register VR mode state listener: " + e);
         }
 
-        mNonBlockablePkgs = new HashSet<String>();
+        mNonBlockablePkgs = new ArraySet<String>();
         Collections.addAll(mNonBlockablePkgs, mContext.getResources().getStringArray(
                 com.android.internal.R.array.config_nonBlockableNotificationPackages));
     }
@@ -1706,6 +1706,23 @@
                         sbn.getPackageContext(mContext),
                         contentContainerPublic, mOnClickHandler);
             }
+
+            if (contentViewLocal != null) {
+                contentViewLocal.setIsRootNamespace(true);
+                contentContainer.setContractedChild(contentViewLocal);
+            }
+            if (bigContentViewLocal != null) {
+                bigContentViewLocal.setIsRootNamespace(true);
+                contentContainer.setExpandedChild(bigContentViewLocal);
+            }
+            if (headsUpContentViewLocal != null) {
+                headsUpContentViewLocal.setIsRootNamespace(true);
+                contentContainer.setHeadsUpChild(headsUpContentViewLocal);
+            }
+            if (publicViewLocal != null) {
+                publicViewLocal.setIsRootNamespace(true);
+                contentContainerPublic.setContractedChild(publicViewLocal);
+            }
         }
         catch (RuntimeException e) {
             final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
@@ -1713,23 +1730,6 @@
             return false;
         }
 
-        if (contentViewLocal != null) {
-            contentViewLocal.setIsRootNamespace(true);
-            contentContainer.setContractedChild(contentViewLocal);
-        }
-        if (bigContentViewLocal != null) {
-            bigContentViewLocal.setIsRootNamespace(true);
-            contentContainer.setExpandedChild(bigContentViewLocal);
-        }
-        if (headsUpContentViewLocal != null) {
-            headsUpContentViewLocal.setIsRootNamespace(true);
-            contentContainer.setHeadsUpChild(headsUpContentViewLocal);
-        }
-        if (publicViewLocal != null) {
-            publicViewLocal.setIsRootNamespace(true);
-            contentContainerPublic.setContractedChild(publicViewLocal);
-        }
-
         // Extract target SDK version.
         try {
             ApplicationInfo info = pmUser.getApplicationInfo(sbn.getPackageName(), 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 62d730a..c850a25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -184,28 +184,38 @@
                     mINotificationManager.getImportance(sbn.getPackageName(), sbn.getUid());
         } catch (RemoteException e) {}
         mNotificationImportance = importance;
-        boolean nonBlockable = false;
-        try {
-            final PackageInfo info =
-                    pm.getPackageInfo(sbn.getPackageName(), PackageManager.GET_SIGNATURES);
-            nonBlockable = Utils.isSystemPackage(getResources(), pm, info);
-        } catch (PackageManager.NameNotFoundException e) {
-            // unlikely.
-        }
-        if (nonBlockablePkgs != null) {
-            nonBlockable |= nonBlockablePkgs.contains(sbn.getPackageName());
-        }
 
         final View importanceSlider = findViewById(R.id.importance_slider);
         final View importanceButtons = findViewById(R.id.importance_buttons);
-        if (mShowSlider) {
-            bindSlider(importanceSlider, nonBlockable);
-            importanceSlider.setVisibility(View.VISIBLE);
+        final View cantTouchThis = findViewById(R.id.cant_silence_or_block);
+
+        final boolean essentialPackage =
+                (nonBlockablePkgs != null && nonBlockablePkgs.contains(sbn.getPackageName()));
+        if (essentialPackage) {
             importanceButtons.setVisibility(View.GONE);
-        } else {
-            bindToggles(importanceButtons, mStartingUserImportance, nonBlockable);
-            importanceButtons.setVisibility(View.VISIBLE);
             importanceSlider.setVisibility(View.GONE);
+            cantTouchThis.setVisibility(View.VISIBLE);
+        } else {
+            cantTouchThis.setVisibility(View.GONE);
+
+            boolean nonBlockable = false;
+            try {
+                final PackageInfo info =
+                        pm.getPackageInfo(sbn.getPackageName(), PackageManager.GET_SIGNATURES);
+                nonBlockable = Utils.isSystemPackage(getResources(), pm, info);
+            } catch (PackageManager.NameNotFoundException e) {
+                // unlikely.
+            }
+
+            if (mShowSlider) {
+                bindSlider(importanceSlider, nonBlockable);
+                importanceSlider.setVisibility(View.VISIBLE);
+                importanceButtons.setVisibility(View.GONE);
+            } else {
+                bindToggles(importanceButtons, mStartingUserImportance, nonBlockable);
+                importanceButtons.setVisibility(View.VISIBLE);
+                importanceSlider.setVisibility(View.GONE);
+            }
         }
     }
 
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 497eac9..8424b39 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -6057,7 +6057,11 @@
                                         // the app developer's cert, so they're different on every
                                         // device.
                                         if (signaturesMatch(sigs, pkgInfo)) {
-                                            if (pkgInfo.versionCode >= version) {
+                                            if ((pkgInfo.applicationInfo.flags
+                                                    & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) != 0) {
+                                                Slog.i(TAG, "Package has restoreAnyVersion; taking data");
+                                                policy = RestorePolicy.ACCEPT;
+                                            } else if (pkgInfo.versionCode >= version) {
                                                 Slog.i(TAG, "Sig + version match; taking data");
                                                 policy = RestorePolicy.ACCEPT;
                                             } else {
@@ -7479,7 +7483,11 @@
                                         // the app developer's cert, so they're different on every
                                         // device.
                                         if (signaturesMatch(sigs, pkgInfo)) {
-                                            if (pkgInfo.versionCode >= version) {
+                                            if ((pkgInfo.applicationInfo.flags
+                                                    & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) != 0) {
+                                                Slog.i(TAG, "Package has restoreAnyVersion; taking data");
+                                                policy = RestorePolicy.ACCEPT;
+                                            } else if (pkgInfo.versionCode >= version) {
                                                 Slog.i(TAG, "Sig + version match; taking data");
                                                 policy = RestorePolicy.ACCEPT;
                                             } else {
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 6870c56..131da0b 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -795,7 +795,17 @@
      *           Use {@link AuthorityInfo#UNDEFINED} to sync all authorities.
      */
     public void scheduleSync(Account requestedAccount, int userId, int reason,
-            String requestedAuthority, Bundle extras, int targetSyncState) {
+                             String requestedAuthority, Bundle extras, int targetSyncState) {
+        scheduleSync(requestedAccount, userId, reason, requestedAuthority, extras, targetSyncState,
+                0 /* min delay */);
+    }
+
+    /**
+     * @param minDelayMillis The sync can't land before this delay expires.
+     */
+    private void scheduleSync(Account requestedAccount, int userId, int reason,
+                             String requestedAuthority, Bundle extras, int targetSyncState,
+                             final long minDelayMillis) {
         final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
         if (extras == null) {
             extras = new Bundle();
@@ -906,7 +916,7 @@
                                 if (result != null
                                         && result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) {
                                     scheduleSync(account.account, userId, reason, authority,
-                                            finalExtras, targetSyncState);
+                                            finalExtras, targetSyncState, minDelayMillis);
                                 }
                             }
                         ));
@@ -967,7 +977,8 @@
                     postScheduleSyncMessage(
                             new SyncOperation(account.account, account.userId,
                                     owningUid, owningPackage, reason, source,
-                                    authority, newExtras, allowParallelSyncs)
+                                    authority, newExtras, allowParallelSyncs),
+                            minDelayMillis
                     );
                 } else if (targetSyncState == AuthorityInfo.UNDEFINED
                         || targetSyncState == isSyncable) {
@@ -982,7 +993,8 @@
                     postScheduleSyncMessage(
                             new SyncOperation(account.account, account.userId,
                                     owningUid, owningPackage, reason, source,
-                                    authority, extras, allowParallelSyncs)
+                                    authority, extras, allowParallelSyncs),
+                            minDelayMillis
                     );
                 }
             }
@@ -1088,14 +1100,14 @@
     }
 
     /**
-     * Schedule sync based on local changes to a provider. Occurs within interval
-     * [LOCAL_SYNC_DELAY, 2*LOCAL_SYNC_DELAY].
+     * Schedule sync based on local changes to a provider. We wait for at least LOCAL_SYNC_DELAY
+     * ms to batch syncs.
      */
     public void scheduleLocalSync(Account account, int userId, int reason, String authority) {
         final Bundle extras = new Bundle();
         extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
         scheduleSync(account, userId, reason, authority, extras,
-                AuthorityInfo.UNDEFINED);
+                AuthorityInfo.UNDEFINED, LOCAL_SYNC_DELAY);
     }
 
     public SyncAdapterType[] getSyncAdapterTypes(int userId) {
@@ -1152,9 +1164,10 @@
         mSyncHandler.sendMessageDelayed(monitorMessage, SYNC_MONITOR_WINDOW_LENGTH_MILLIS);
     }
 
-    private void postScheduleSyncMessage(SyncOperation syncOperation) {
-        mSyncHandler.obtainMessage(mSyncHandler.MESSAGE_SCHEDULE_SYNC, syncOperation)
-                .sendToTarget();
+    private void postScheduleSyncMessage(SyncOperation syncOperation, long minDelayMillis) {
+        ScheduleSyncMessagePayload payload =
+                new ScheduleSyncMessagePayload(syncOperation, minDelayMillis);
+        mSyncHandler.obtainMessage(mSyncHandler.MESSAGE_SCHEDULE_SYNC, payload).sendToTarget();
     }
 
     /**
@@ -1194,6 +1207,16 @@
         }
     }
 
+    private static class ScheduleSyncMessagePayload {
+        final SyncOperation syncOperation;
+        final long minDelayMillis;
+
+        ScheduleSyncMessagePayload(SyncOperation syncOperation, long minDelayMillis) {
+            this.syncOperation = syncOperation;
+            this.minDelayMillis = minDelayMillis;
+        }
+    }
+
     private void clearBackoffSetting(EndPoint target) {
         Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(target);
         if (backoff != null && backoff.first == SyncStorageEngine.NOT_IN_BACKOFF_MODE &&
@@ -1262,7 +1285,7 @@
             if (!op.isPeriodic && op.target.matchesSpec(target)) {
                 count++;
                 getJobScheduler().cancel(op.jobId);
-                postScheduleSyncMessage(op);
+                postScheduleSyncMessage(op, 0 /* min delay */);
             }
         }
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -2417,8 +2440,10 @@
                 mDataConnectionIsConnected = readDataConnectionState();
                 switch (msg.what) {
                     case MESSAGE_SCHEDULE_SYNC:
-                        SyncOperation op = (SyncOperation) msg.obj;
-                        scheduleSyncOperationH(op);
+                        ScheduleSyncMessagePayload syncPayload =
+                                (ScheduleSyncMessagePayload) msg.obj;
+                        SyncOperation op = syncPayload.syncOperation;
+                        scheduleSyncOperationH(op, syncPayload.minDelayMillis);
                         break;
 
                     case MESSAGE_START_SYNC:
@@ -3101,7 +3126,8 @@
                         maybeRescheduleSync(syncResult, syncOperation);
                     } else {
                         // create a normal sync instance that will respect adapter backoffs
-                        postScheduleSyncMessage(syncOperation.createOneTimeSyncOperation());
+                        postScheduleSyncMessage(syncOperation.createOneTimeSyncOperation(),
+                                0 /* min delay */);
                     }
                     historyMessage = ContentResolver.syncErrorToString(
                             syncResultToErrorNumber(syncResult));
diff --git a/services/core/java/com/android/server/emergency/EmergencyAffordanceService.java b/services/core/java/com/android/server/emergency/EmergencyAffordanceService.java
index cca9f10..353f450 100644
--- a/services/core/java/com/android/server/emergency/EmergencyAffordanceService.java
+++ b/services/core/java/com/android/server/emergency/EmergencyAffordanceService.java
@@ -99,6 +99,7 @@
     };
     private boolean mSimNeedsEmergencyAffordance;
     private boolean mNetworkNeedsEmergencyAffordance;
+    private boolean mVoiceCapable;
 
     private void requestCellScan() {
         mHandler.obtainMessage(CELL_INFO_STATE_CHANGED).sendToTarget();
@@ -125,8 +126,8 @@
 
     private void updateEmergencyAffordanceNeeded() {
         synchronized (mLock) {
-            mEmergencyAffordanceNeeded = mSimNeedsEmergencyAffordance ||
-                    mNetworkNeedsEmergencyAffordance;
+            mEmergencyAffordanceNeeded = mVoiceCapable && (mSimNeedsEmergencyAffordance ||
+                    mNetworkNeedsEmergencyAffordance);
             Settings.Global.putInt(mContext.getContentResolver(),
                     Settings.Global.EMERGENCY_AFFORDANCE_NEEDED,
                     mEmergencyAffordanceNeeded ? 1 : 0);
@@ -157,6 +158,11 @@
     public void onBootPhase(int phase) {
         if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
             mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+            mVoiceCapable = mTelephonyManager.isVoiceCapable();
+            if (!mVoiceCapable) {
+                updateEmergencyAffordanceNeeded();
+                return;
+            }
             mSubscriptionManager = SubscriptionManager.from(mContext);
             HandlerThread thread = new HandlerThread(TAG);
             thread.start();
diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java
index 1c12a96..40b0be2 100644
--- a/services/core/java/com/android/server/notification/ZenModeConditions.java
+++ b/services/core/java/com/android/server/notification/ZenModeConditions.java
@@ -99,7 +99,7 @@
     @Override
     public void onServiceAdded(ComponentName component) {
         if (DEBUG) Log.d(TAG, "onServiceAdded " + component);
-        mHelper.setConfigAsync(mHelper.getConfig(), "zmc.onServiceAdded");
+        mHelper.setConfig(mHelper.getConfig(), "zmc.onServiceAdded");
     }
 
     @Override
@@ -113,7 +113,7 @@
             updated |= updateSnoozing(automaticRule);
         }
         if (updated) {
-            mHelper.setConfigAsync(config, "conditionChanged");
+            mHelper.setConfig(config, "conditionChanged");
         }
     }
 
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index afd42ea..15549d2 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -620,8 +620,10 @@
         return setConfigLocked(config, reason, true /*setRingerMode*/);
     }
 
-    public void setConfigAsync(ZenModeConfig config, String reason) {
-        mHandler.postSetConfig(config, reason);
+    public void setConfig(ZenModeConfig config, String reason) {
+        synchronized (mConfig) {
+            setConfigLocked(config, reason);
+        }
     }
 
     private boolean setConfigLocked(ZenModeConfig config, String reason, boolean setRingerMode) {
@@ -1084,7 +1086,6 @@
     private final class H extends Handler {
         private static final int MSG_DISPATCH = 1;
         private static final int MSG_METRICS = 2;
-        private static final int MSG_SET_CONFIG = 3;
         private static final int MSG_APPLY_CONFIG = 4;
 
         private final class ConfigMessageData {
@@ -1092,12 +1093,6 @@
             public final String reason;
             public final boolean setRingerMode;
 
-            ConfigMessageData(ZenModeConfig config, String reason) {
-                this.config = config;
-                this.reason = reason;
-                this.setRingerMode = false;
-            }
-
             ConfigMessageData(ZenModeConfig config, String reason, boolean setRingerMode) {
                 this.config = config;
                 this.reason = reason;
@@ -1121,10 +1116,6 @@
             sendEmptyMessageDelayed(MSG_METRICS, METRICS_PERIOD_MS);
         }
 
-        private void postSetConfig(ZenModeConfig config, String reason) {
-            sendMessage(obtainMessage(MSG_SET_CONFIG, new ConfigMessageData(config, reason)));
-        }
-
         private void postApplyConfig(ZenModeConfig config, String reason, boolean setRingerMode) {
             sendMessage(obtainMessage(MSG_APPLY_CONFIG,
                     new ConfigMessageData(config, reason, setRingerMode)));
@@ -1139,12 +1130,6 @@
                 case MSG_METRICS:
                     mMetrics.emit();
                     break;
-                case MSG_SET_CONFIG:
-                    ConfigMessageData configData = (ConfigMessageData) msg.obj;
-                    synchronized (mConfig) {
-                        setConfigLocked(configData.config, configData.reason);
-                    }
-                    break;
                 case MSG_APPLY_CONFIG:
                     ConfigMessageData applyConfigData = (ConfigMessageData) msg.obj;
                     applyConfig(applyConfigData.config, applyConfigData.reason,