Merge "Clarify WebView's lack of plugin support."
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 3f19b8f..2247e43 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -246,6 +246,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/statsdprotolite_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.mediadrm.signer.jar)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.location.provider.jar)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.future.usb.accessory.jar)
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
 # ******************************************************************
diff --git a/api/current.txt b/api/current.txt
index 20e62c0..c641a8c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -41805,6 +41805,7 @@
     field public static final java.lang.String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool";
     field public static final java.lang.String KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL = "support_3gpp_call_forwarding_while_roaming_bool";
     field public static final java.lang.String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
+    field public static final java.lang.String KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
     field public static final java.lang.String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
     field public static final java.lang.String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
     field public static final java.lang.String KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL = "treat_downgraded_video_calls_as_video_calls_bool";
diff --git a/api/test-current.txt b/api/test-current.txt
index b08ae0e..718c0f2 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -130,6 +130,12 @@
     method public android.content.ComponentName getEffectsSuppressor();
   }
 
+  public final class PictureInPictureParams implements android.os.Parcelable {
+    method public java.util.List<android.app.RemoteAction> getActions();
+    method public float getAspectRatio();
+    method public android.graphics.Rect getSourceRectHint();
+  }
+
   public class TimePickerDialog extends android.app.AlertDialog implements android.content.DialogInterface.OnClickListener android.widget.TimePicker.OnTimeChangedListener {
     method public android.widget.TimePicker getTimePicker();
   }
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 0941d39..f805dea 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -857,9 +857,6 @@
 Landroid/app/PictureInPictureArgs;-><init>()V
 Landroid/app/PictureInPictureArgs;->setActions(Ljava/util/List;)V
 Landroid/app/PictureInPictureArgs;->setAspectRatio(F)V
-Landroid/app/PictureInPictureParams;->getActions()Ljava/util/List;
-Landroid/app/PictureInPictureParams;->getAspectRatio()F
-Landroid/app/PictureInPictureParams;->getSourceRectHint()Landroid/graphics/Rect;
 Landroid/app/Presentation;->createPresentationContext(Landroid/content/Context;Landroid/view/Display;I)Landroid/content/Context;
 Landroid/app/ProgressDialog;->mMessageView:Landroid/widget/TextView;
 Landroid/app/ProgressDialog;->mProgress:Landroid/widget/ProgressBar;
diff --git a/core/java/android/app/PictureInPictureParams.java b/core/java/android/app/PictureInPictureParams.java
index 7313b0d..edaae75 100644
--- a/core/java/android/app/PictureInPictureParams.java
+++ b/core/java/android/app/PictureInPictureParams.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.graphics.Rect;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -181,6 +182,7 @@
      * @return the aspect ratio. If none is set, return 0.
      * @hide
      */
+    @TestApi
     public float getAspectRatio() {
         if (mAspectRatio != null) {
             return mAspectRatio.floatValue();
@@ -205,6 +207,7 @@
      * @return the set of user actions.
      * @hide
      */
+    @TestApi
     public List<RemoteAction> getActions() {
         return mUserActions;
     }
@@ -231,6 +234,7 @@
      * @return the source rect hint
      * @hide
      */
+    @TestApi
     public Rect getSourceRectHint() {
         return mSourceRectHint;
     }
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index 9657922..ec2cf0c 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -43,7 +43,6 @@
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.util.Collection;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Set;
@@ -833,7 +832,7 @@
         }
 
         if (excludes != null &&
-                isFileSpecifiedInPathList(destination, excludes)) {
+                BackupUtils.isFileSpecifiedInPathList(destination, excludes)) {
             if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) {
                 Log.v(FullBackup.TAG_XML_PARSER,
                         "onRestoreFile: \"" + destinationCanonicalPath + "\": listed in"
@@ -847,7 +846,8 @@
             // it's a small list), we'll go through and look for it.
             boolean explicitlyIncluded = false;
             for (Set<PathWithRequiredFlags> domainIncludes : includes.values()) {
-                explicitlyIncluded |= isFileSpecifiedInPathList(destination, domainIncludes);
+                explicitlyIncluded |=
+                        BackupUtils.isFileSpecifiedInPathList(destination, domainIncludes);
                 if (explicitlyIncluded) {
                     break;
                 }
@@ -866,33 +866,6 @@
     }
 
     /**
-     * @return True if the provided file is either directly in the provided list, or the provided
-     * file is within a directory in the list.
-     */
-    private boolean isFileSpecifiedInPathList(File file,
-            Collection<PathWithRequiredFlags> canonicalPathList) throws IOException {
-        for (PathWithRequiredFlags canonical : canonicalPathList) {
-            String canonicalPath = canonical.getPath();
-            File fileFromList = new File(canonicalPath);
-            if (fileFromList.isDirectory()) {
-                if (file.isDirectory()) {
-                    // If they are both directories check exact equals.
-                    return file.equals(fileFromList);
-                } else {
-                    // O/w we have to check if the file is within the directory from the list.
-                    return file.getCanonicalPath().startsWith(canonicalPath);
-                }
-            } else {
-                if (file.equals(fileFromList)) {
-                    // Need to check the explicit "equals" so we don't end up with substrings.
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
      * Only specialized platform agents should overload this entry point to support
      * restores to crazy non-app locations.
      * @hide
diff --git a/core/java/android/app/backup/BackupUtils.java b/core/java/android/app/backup/BackupUtils.java
new file mode 100644
index 0000000..8cf8a84
--- /dev/null
+++ b/core/java/android/app/backup/BackupUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.backup;
+
+import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+
+/** @hide */
+public class BackupUtils {
+
+    private BackupUtils() {}
+
+    /**
+     * Returns {@code true} if {@code file} is either directly in {@code canonicalPathList} or is a
+     * file contained in a directory in the list.
+     */
+    public static boolean isFileSpecifiedInPathList(
+            File file, Collection<PathWithRequiredFlags> canonicalPathList) throws IOException {
+        for (PathWithRequiredFlags canonical : canonicalPathList) {
+            String canonicalPath = canonical.getPath();
+            File fileFromList = new File(canonicalPath);
+            if (fileFromList.isDirectory()) {
+                if (file.isDirectory()) {
+                    // If they are both directories check exact equals.
+                    if (file.equals(fileFromList)) {
+                        return true;
+                    }
+                } else {
+                    // O/w we have to check if the file is within the directory from the list.
+                    if (file.toPath().startsWith(canonicalPath)) {
+                        return true;
+                    }
+                }
+            } else if (file.equals(fileFromList)) {
+                // Need to check the explicit "equals" so we don't end up with substrings.
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java
index b5912bc..ee08bf7 100644
--- a/core/java/android/view/SurfaceSession.java
+++ b/core/java/android/view/SurfaceSession.java
@@ -37,7 +37,12 @@
     }
 
     public SurfaceSession(Surface root) {
-        mNativeClient = nativeCreateScoped(root.mNativeObject);
+        synchronized (root.mLock) {
+            if (root.mNativeObject == 0) {
+                throw new IllegalStateException("Surface is not initialized or has been released");
+            }
+            mNativeClient = nativeCreateScoped(root.mNativeObject);
+        }
     }
 
     /* no user serviceable parts here ... */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 964ee5e..0e5527d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -23993,6 +23993,10 @@
             Log.w(VIEW_LOG_TAG, "startDragAndDrop called on a detached view.");
             return false;
         }
+        if (!mAttachInfo.mViewRootImpl.mSurface.isValid()) {
+            Log.w(VIEW_LOG_TAG, "startDragAndDrop called with an invalid surface.");
+            return false;
+        }
 
         if (data != null) {
             data.prepareToLeaveProcess((flags & View.DRAG_FLAG_GLOBAL) != 0);
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 381758f..aef48fa 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2914,7 +2914,7 @@
     <string name="config_keyguardComponent" translatable="false">com.android.systemui/com.android.systemui.keyguard.KeyguardService</string>
 
     <!-- Limit for the number of face templates per user -->
-    <integer name="config_face_MaxTemplatesPerUser">1</integer>
+    <integer name="config_faceMaxTemplatesPerUser">1</integer>
 
     <!-- For performance and storage reasons, limit the number of fingerprints per user -->
     <integer name="config_fingerprintMaxTemplatesPerUser">5</integer>
@@ -3374,6 +3374,9 @@
     <!-- URI for in call notification sound -->
     <string translatable="false" name="config_inCallNotificationSound">/system/media/audio/ui/InCallNotification.ogg</string>
 
+    <!-- Default number of notifications from the same app before they are automatically grouped by the OS -->
+    <integer translatable="false" name="config_autoGroupAtCount">4</integer>
+
     <!-- The OEM specified sensor type for the lift trigger to launch the camera app. -->
     <integer name="config_cameraLiftTriggerSensorType">-1</integer>
     <!-- The OEM specified sensor string type for the gesture to launch camera app, this value
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 99d0dba..6054180 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2446,7 +2446,7 @@
   <java-symbol type="string" name="face_name_template" />
 
   <!-- Face config -->
-  <java-symbol type="integer" name="config_face_MaxTemplatesPerUser" />
+  <java-symbol type="integer" name="config_faceMaxTemplatesPerUser" />
 
   <!-- From various Material changes -->
   <java-symbol type="attr" name="titleTextAppearance" />
@@ -3266,6 +3266,7 @@
   <java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
   <java-symbol type="dimen" name="config_inCallNotificationVolume" />
   <java-symbol type="string" name="config_inCallNotificationSound" />
+  <java-symbol type="integer" name="config_autoGroupAtCount" />
   <java-symbol type="bool" name="config_dozeAlwaysOnDisplayAvailable" />
   <java-symbol type="bool" name="config_dozeAlwaysOnEnabled" />
   <java-symbol type="bool" name="config_displayBlanksAfterDoze" />
diff --git a/libs/usb/Android.bp b/libs/usb/Android.bp
index b8f2904..027a748 100644
--- a/libs/usb/Android.bp
+++ b/libs/usb/Android.bp
@@ -1 +1,23 @@
+//
+// Copyright (C) 2018 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.
+//
+
+java_sdk_library {
+    name: "com.android.future.usb.accessory",
+    srcs: ["src/**/*.java"],
+    api_packages: ["com.android.future.usb"],
+}
+
 subdirs = ["tests/*"]
diff --git a/libs/usb/Android.mk b/libs/usb/Android.mk
deleted file mode 100644
index 129828f..0000000
--- a/libs/usb/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= com.android.future.usb.accessory
-
-include $(BUILD_JAVA_LIBRARY)
diff --git a/libs/usb/api/current.txt b/libs/usb/api/current.txt
new file mode 100644
index 0000000..8488db5
--- /dev/null
+++ b/libs/usb/api/current.txt
@@ -0,0 +1,25 @@
+package com.android.future.usb {
+
+  public class UsbAccessory {
+    method public java.lang.String getDescription();
+    method public java.lang.String getManufacturer();
+    method public java.lang.String getModel();
+    method public java.lang.String getSerial();
+    method public java.lang.String getUri();
+    method public java.lang.String getVersion();
+  }
+
+  public class UsbManager {
+    method public static com.android.future.usb.UsbAccessory getAccessory(android.content.Intent);
+    method public com.android.future.usb.UsbAccessory[] getAccessoryList();
+    method public static com.android.future.usb.UsbManager getInstance(android.content.Context);
+    method public boolean hasPermission(com.android.future.usb.UsbAccessory);
+    method public android.os.ParcelFileDescriptor openAccessory(com.android.future.usb.UsbAccessory);
+    method public void requestPermission(com.android.future.usb.UsbAccessory, android.app.PendingIntent);
+    field public static final java.lang.String ACTION_USB_ACCESSORY_ATTACHED = "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";
+    field public static final java.lang.String ACTION_USB_ACCESSORY_DETACHED = "android.hardware.usb.action.USB_ACCESSORY_DETACHED";
+    field public static final java.lang.String EXTRA_PERMISSION_GRANTED = "permission";
+  }
+
+}
+
diff --git a/libs/usb/api/removed.txt b/libs/usb/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/removed.txt
diff --git a/libs/usb/api/system-current.txt b/libs/usb/api/system-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/system-current.txt
diff --git a/libs/usb/api/system-removed.txt b/libs/usb/api/system-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/system-removed.txt
diff --git a/libs/usb/api/test-current.txt b/libs/usb/api/test-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/test-current.txt
diff --git a/libs/usb/api/test-removed.txt b/libs/usb/api/test-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/test-removed.txt
diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk
index ecb455a..cfe2da1 100644
--- a/libs/usb/tests/AccessoryChat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/Android.mk
@@ -23,4 +23,6 @@
 
 LOCAL_PACKAGE_NAME := AccessoryChat
 
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
 include $(BUILD_PACKAGE)
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 1942fc1..745f81d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -143,6 +143,7 @@
             mSecurityViewFlipper.addView(v);
             updateSecurityView(v);
             view = (KeyguardSecurityView)v;
+            view.reset();
         }
 
         return view;
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 3261209..cc5acdf 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -2685,19 +2685,23 @@
     private void validateLastAlarmExpiredLocked(long nowElapsed) {
         final StringBuilder errorMsg = new StringBuilder();
         boolean stuck = false;
-        if (mNextNonWakeup < nowElapsed && mLastWakeup < (mNextNonWakeup - 30_000)) {
+        if (mNextNonWakeup < (nowElapsed - 10_000) && mLastWakeup < mNextNonWakeup) {
             stuck = true;
             errorMsg.append("[mNextNonWakeup=");
             TimeUtils.formatDuration(mNextNonWakeup - nowElapsed, errorMsg);
+            errorMsg.append(" set at ");
+            TimeUtils.formatDuration(mNextNonWakeUpSetAt, errorMsg);
             errorMsg.append(", mLastWakeup=");
             TimeUtils.formatDuration(mLastWakeup - nowElapsed, errorMsg);
             errorMsg.append(", timerfd_gettime=" + getNextAlarm(mNativeData, ELAPSED_REALTIME));
             errorMsg.append("];");
         }
-        if (mNextWakeup < nowElapsed && mLastWakeup < (mNextWakeup - 30_000)) {
+        if (mNextWakeup < (nowElapsed - 10_000) && mLastWakeup < mNextWakeup) {
             stuck = true;
             errorMsg.append("[mNextWakeup=");
             TimeUtils.formatDuration(mNextWakeup - nowElapsed, errorMsg);
+            errorMsg.append(" set at ");
+            TimeUtils.formatDuration(mNextWakeUpSetAt, errorMsg);
             errorMsg.append(", mLastWakeup=");
             TimeUtils.formatDuration(mLastWakeup - nowElapsed, errorMsg);
             errorMsg.append(", timerfd_gettime="
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index d2a29e4..35679a88 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -541,7 +541,7 @@
     @Override
     protected boolean hasReachedEnrollmentLimit(int userId) {
         final int limit = getContext().getResources().getInteger(
-                com.android.internal.R.integer.config_face_MaxTemplatesPerUser);
+                com.android.internal.R.integer.config_faceMaxTemplatesPerUser);
         final int enrolled = FaceService.this.getEnrolledFaces(userId).size();
         if (enrolled >= limit) {
             Slog.w(TAG, "Too many faces registered");
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index ce805aad..b1cd627 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -32,16 +32,17 @@
     private static final String TAG = "GroupHelper";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    protected static final int AUTOGROUP_AT_COUNT = 4;
     protected static final String AUTOGROUP_KEY = "ranker_group";
 
     private final Callback mCallback;
+    private final int mAutoGroupAtCount;
 
     // Map of user : <Map of package : notification keys>. Only contains notifications that are not
     // grouped by the app (aka no group or sort key).
     Map<Integer, Map<String, LinkedHashSet<String>>> mUngroupedNotifications = new HashMap<>();
 
-    public GroupHelper(Callback callback) {;
+    public GroupHelper(int autoGroupAtCount, Callback callback) {
+        mAutoGroupAtCount = autoGroupAtCount;
         mCallback = callback;
     }
 
@@ -68,7 +69,7 @@
                     notificationsForPackage.add(sbn.getKey());
                     ungroupedNotificationsByUser.put(sbn.getPackageName(), notificationsForPackage);
 
-                    if (notificationsForPackage.size() >= AUTOGROUP_AT_COUNT
+                    if (notificationsForPackage.size() >= mAutoGroupAtCount
                             || autogroupSummaryExists) {
                         notificationsToGroup.addAll(notificationsForPackage);
                     }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 6402b7b..52f4461 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -400,6 +400,7 @@
 
     private SnoozeHelper mSnoozeHelper;
     private GroupHelper mGroupHelper;
+    private int mAutoGroupAtCount;
     private boolean mIsTelevision;
 
     private MetricsLogger mMetricsLogger;
@@ -1565,7 +1566,9 @@
     }
 
     private GroupHelper getGroupHelper() {
-        return new GroupHelper(new GroupHelper.Callback() {
+        mAutoGroupAtCount =
+                getContext().getResources().getInteger(R.integer.config_autoGroupAtCount);
+        return new GroupHelper(mAutoGroupAtCount, new GroupHelper.Callback() {
             @Override
             public void addAutoGroup(String key) {
                 synchronized (mNotificationLock) {
diff --git a/services/robotests/src/android/app/backup/BackupUtilsTest.java b/services/robotests/src/android/app/backup/BackupUtilsTest.java
new file mode 100644
index 0000000..04a2a14
--- /dev/null
+++ b/services/robotests/src/android/app/backup/BackupUtilsTest.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app.backup;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags;
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"android.app.backup"})
+@Presubmit
+@DoNotInstrument
+public class BackupUtilsTest {
+    private Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = RuntimeEnvironment.application;
+    }
+
+    @Test
+    public void testIsFileSpecifiedInPathList_whenFileAndPathListHasIt() throws Exception {
+        boolean isSpecified =
+                BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(file("a/b.txt")));
+
+        assertThat(isSpecified).isTrue();
+    }
+
+    @Test
+    public void testIsFileSpecifiedInPathList_whenFileAndPathListHasItsDirectory()
+            throws Exception {
+        boolean isSpecified =
+                BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(directory("a")));
+
+        assertThat(isSpecified).isTrue();
+    }
+
+    @Test
+    public void testIsFileSpecifiedInPathList_whenFileAndPathListHasOtherFile() throws Exception {
+        boolean isSpecified =
+                BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(file("a/c.txt")));
+
+        assertThat(isSpecified).isFalse();
+    }
+
+    @Test
+    public void testIsFileSpecifiedInPathList_whenFileAndPathListEmpty() throws Exception {
+        boolean isSpecified = BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths());
+
+        assertThat(isSpecified).isFalse();
+    }
+
+    @Test
+    public void testIsFileSpecifiedInPathList_whenDirectoryAndPathListHasIt() throws Exception {
+        boolean isSpecified =
+                BackupUtils.isFileSpecifiedInPathList(directory("a"), paths(directory("a")));
+
+        assertThat(isSpecified).isTrue();
+    }
+
+    @Test
+    public void testIsFileSpecifiedInPathList_whenDirectoryAndPathListEmpty() throws Exception {
+        boolean isSpecified = BackupUtils.isFileSpecifiedInPathList(directory("a"), paths());
+
+        assertThat(isSpecified).isFalse();
+    }
+
+    @Test
+    public void testIsFileSpecifiedInPathList_whenDirectoryAndPathListHasParent() throws Exception {
+        boolean isSpecified =
+                BackupUtils.isFileSpecifiedInPathList(directory("a/b"), paths(directory("a")));
+
+        assertThat(isSpecified).isFalse();
+    }
+
+    @Test
+    public void testIsFileSpecifiedInPathList_whenFileAndPathListDoesntContainDirectory()
+            throws Exception {
+        boolean isSpecified =
+                BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(directory("c")));
+
+        assertThat(isSpecified).isFalse();
+    }
+
+    @Test
+    public void testIsFileSpecifiedInPathList_whenFileAndPathListHasDirectoryWhoseNameIsPrefix()
+            throws Exception {
+        boolean isSpecified =
+                BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(directory("a/b")));
+
+        assertThat(isSpecified).isFalse();
+    }
+
+    @Test
+    public void testIsFileSpecifiedInPathList_whenFileAndPathListHasDirectoryWhoseNameIsPrefix2()
+            throws Exception {
+        boolean isSpecified =
+                BackupUtils.isFileSpecifiedInPathList(
+                        file("name/subname.txt"), paths(directory("nam")));
+
+        assertThat(isSpecified).isFalse();
+    }
+
+    @Test
+    public void
+            testIsFileSpecifiedInPathList_whenFileAndPathListContainsFirstNotRelatedAndSecondContainingDirectory()
+                    throws Exception {
+        boolean isSpecified =
+                BackupUtils.isFileSpecifiedInPathList(
+                        file("a/b.txt"), paths(directory("b"), directory("a")));
+
+        assertThat(isSpecified).isTrue();
+    }
+
+    @Test
+    public void
+            testIsFileSpecifiedInPathList_whenDirectoryAndPathListContainsFirstNotRelatedAndSecondSameDirectory()
+                    throws Exception {
+        boolean isSpecified =
+                BackupUtils.isFileSpecifiedInPathList(
+                        directory("a/b"), paths(directory("b"), directory("a/b")));
+
+        assertThat(isSpecified).isTrue();
+    }
+
+    @Test
+    public void
+            testIsFileSpecifiedInPathList_whenFileAndPathListContainsFirstNotRelatedFileAndSecondSameFile()
+                    throws Exception {
+        boolean isSpecified =
+                BackupUtils.isFileSpecifiedInPathList(
+                        file("a/b.txt"), paths(directory("b"), file("a/b.txt")));
+
+        assertThat(isSpecified).isTrue();
+    }
+
+    private File file(String path) throws IOException {
+        File file = new File(mContext.getDataDir(), path);
+        File parent = file.getParentFile();
+        parent.mkdirs();
+        file.createNewFile();
+        if (!file.isFile()) {
+            throw new IOException("Couldn't create file");
+        }
+        return file;
+    }
+
+    private File directory(String path) throws IOException {
+        File directory = new File(mContext.getDataDir(), path);
+        directory.mkdirs();
+        if (!directory.isDirectory()) {
+            throw new IOException("Couldn't create directory");
+        }
+        return directory;
+    }
+
+    private Collection<PathWithRequiredFlags> paths(File... files) {
+        return Stream.of(files)
+                .map(file -> new PathWithRequiredFlags(file.getPath(), 0))
+                .collect(Collectors.toList());
+    }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 8d4c5b1..84ef0c9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -50,13 +50,14 @@
 public class GroupHelperTest extends UiServiceTestCase {
     private @Mock GroupHelper.Callback mCallback;
 
+    private final static int AUTOGROUP_AT_COUNT = 4;
     private GroupHelper mGroupHelper;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mGroupHelper = new GroupHelper(mCallback);
+        mGroupHelper = new GroupHelper(AUTOGROUP_AT_COUNT, mCallback);
     }
 
     private StatusBarNotification getSbn(String pkg, int id, String tag,
@@ -79,7 +80,7 @@
     @Test
     public void testNoGroup_postingUnderLimit() throws Exception {
         final String pkg = "package";
-        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
                     false);
         }
@@ -94,12 +95,12 @@
     public void testNoGroup_multiPackage() throws Exception {
         final String pkg = "package";
         final String pkg2 = "package2";
-        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
                     false);
         }
         mGroupHelper.onNotificationPosted(
-                getSbn(pkg2, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
+                getSbn(pkg2, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
         verify(mCallback, never()).addAutoGroupSummary(
                 eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
         verify(mCallback, never()).addAutoGroup(anyString());
@@ -110,13 +111,12 @@
     @Test
     public void testNoGroup_multiUser() throws Exception {
         final String pkg = "package";
-        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
                     false);
         }
         mGroupHelper.onNotificationPosted(
-                getSbn(pkg, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.ALL),
-                false);
+                getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.ALL), false);
         verify(mCallback, never()).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
         verify(mCallback, never()).addAutoGroup(anyString());
         verify(mCallback, never()).removeAutoGroup(anyString());
@@ -126,13 +126,12 @@
     @Test
     public void testNoGroup_someAreGrouped() throws Exception {
         final String pkg = "package";
-        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             mGroupHelper.onNotificationPosted(
                     getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
         }
         mGroupHelper.onNotificationPosted(
-                getSbn(pkg, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"),
-                false);
+                getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"), false);
         verify(mCallback, never()).addAutoGroupSummary(
                 eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
         verify(mCallback, never()).addAutoGroup(anyString());
@@ -144,12 +143,12 @@
     @Test
     public void testPostingOverLimit() throws Exception {
         final String pkg = "package";
-        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             mGroupHelper.onNotificationPosted(
                     getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
-        verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
         verify(mCallback, never()).removeAutoGroup(anyString());
         verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
     }
@@ -158,18 +157,18 @@
     public void testDropToZeroRemoveGroup() throws Exception {
         final String pkg = "package";
         List<StatusBarNotification> posted = new ArrayList<>();
-        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
             posted.add(sbn);
             mGroupHelper.onNotificationPosted(sbn, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
-        verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
         verify(mCallback, never()).removeAutoGroup(anyString());
         verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
         Mockito.reset(mCallback);
 
-        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             mGroupHelper.onNotificationRemoved(posted.remove(0));
         }
         verify(mCallback, never()).removeAutoGroup(anyString());
@@ -185,28 +184,28 @@
     public void testAppStartsGrouping() throws Exception {
         final String pkg = "package";
         List<StatusBarNotification> posted = new ArrayList<>();
-        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
             posted.add(sbn);
             mGroupHelper.onNotificationPosted(sbn, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
-        verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
         verify(mCallback, never()).removeAutoGroup(anyString());
         verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
         Mockito.reset(mCallback);
 
         int i = 0;
-        for (i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 2; i++) {
+        for (i = 0; i < AUTOGROUP_AT_COUNT - 2; i++) {
             final StatusBarNotification sbn =
                     getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
             mGroupHelper.onNotificationPosted(sbn, false);
         }
-        verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT - 2)).removeAutoGroup(anyString());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 2)).removeAutoGroup(anyString());
         verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
         Mockito.reset(mCallback);
 
-        for (; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+        for (; i < AUTOGROUP_AT_COUNT; i++) {
             final StatusBarNotification sbn =
                     getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
             mGroupHelper.onNotificationPosted(sbn, false);
@@ -220,13 +219,13 @@
             throws Exception {
         final String pkg = "package";
         List<StatusBarNotification> posted = new ArrayList<>();
-        for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
             posted.add(sbn);
             mGroupHelper.onNotificationPosted(sbn, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
-        verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
         verify(mCallback, never()).removeAutoGroup(anyString());
         verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
         Mockito.reset(mCallback);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index f60332e..3913dbb 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -116,6 +116,14 @@
     public static final String
             KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
 
+    /**
+     * Flag indicating whether or not sending emergency SMS messages over IMS
+     * is supported when in LTE/limited LTE (Emergency only) service mode..
+     *
+     */
+    public static final String
+            KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
+
     /** Flag indicating if the phone is a world phone */
     public static final String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
 
@@ -2025,6 +2033,7 @@
         sDefaults.putBoolean(KEY_SHOW_APN_SETTING_CDMA_BOOL, false);
         sDefaults.putBoolean(KEY_SHOW_CDMA_CHOICES_BOOL, false);
         sDefaults.putBoolean(KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL, false);
+        sDefaults.putBoolean(KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL, false);
         sDefaults.putBoolean(KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL, true);
         sDefaults.putBoolean(KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL, true);
         sDefaults.putBoolean(KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL, false);