Merge "Import translations. DO NOT MERGE"
diff --git a/api/current.txt b/api/current.txt
index e31f8a0..b9e00f6 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -42654,6 +42654,7 @@
     method public static int[] getSubscriptionIds(int);
     method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
     method public boolean isNetworkRoaming(int);
+    method public static boolean isValidSubscriptionId(int);
     method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
     method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
     method public void setSubscriptionOverrideCongested(int, boolean, long);
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index d9d1777..9e20503 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -234,7 +234,7 @@
     /**
      * Array of all signatures read from the package file. This is only filled
      * in if the flag {@link PackageManager#GET_SIGNATURES} was set. A package
-     * must be singed with at least one certificate which is at position zero.
+     * must be signed with at least one certificate which is at position zero.
      * The package can be signed with additional certificates which appear as
      * subsequent entries.
      *
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 1ee3c93..cb33659 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -58,7 +58,7 @@
  * execute in parallel with any {@link Surface} initialization, such as waiting for a
  * {@link android.view.SurfaceView} to be ready as part of the UI initialization.</li>
  *
- * <li>The third and most complex usage pattern inlvolves surface sharing. Once instantiated an
+ * <li>The third and most complex usage pattern involves surface sharing. Once instantiated an
  * OutputConfiguration can be enabled for surface sharing via {@link #enableSurfaceSharing}. This
  * must be done before creating a new capture session and enables calls to
  * {@link CameraCaptureSession#updateOutputConfiguration}. An OutputConfiguration with enabled
diff --git a/core/java/android/hardware/display/BrightnessConfiguration.java b/core/java/android/hardware/display/BrightnessConfiguration.java
index 6d9ba77..7e52ca3 100644
--- a/core/java/android/hardware/display/BrightnessConfiguration.java
+++ b/core/java/android/hardware/display/BrightnessConfiguration.java
@@ -141,13 +141,6 @@
         private String mDescription;
 
         /**
-         * STOPSHIP remove when app has stopped using this.
-         * @hide
-         */
-        public Builder() {
-        }
-
-        /**
          * Constructs the builder with the control points for the brightness curve.
          *
          * Brightness curves must have strictly increasing ambient brightness values in lux and
@@ -159,24 +152,6 @@
          * @throws IllegalArgumentException if the nit levels are not monotonically increasing.
          */
         public Builder(float[] lux, float[] nits) {
-            setCurve(lux, nits);
-        }
-
-        /**
-         * Sets the control points for the brightness curve.
-         *
-         * Brightness curves must have strictly increasing ambient brightness values in lux and
-         * monotonically increasing display brightness values in nits. In addition, the initial
-         * control point must be 0 lux.
-         *
-         * @throws IllegalArgumentException if the initial control point is not at 0 lux.
-         * @throws IllegalArgumentException if the lux levels are not strictly increasing.
-         * @throws IllegalArgumentException if the nit levels are not monotonically increasing.
-         *
-         * STOPSHIP remove when app has stopped using this.
-         * @hide
-         */
-        public Builder setCurve(float[] lux, float[] nits) {
             Preconditions.checkNotNull(lux);
             Preconditions.checkNotNull(nits);
             if (lux.length == 0 || nits.length == 0) {
@@ -190,11 +165,10 @@
             }
             Preconditions.checkArrayElementsInRange(lux, 0, Float.MAX_VALUE, "lux");
             Preconditions.checkArrayElementsInRange(nits, 0, Float.MAX_VALUE, "nits");
-            checkMonotonic(lux, true/*strictly increasing*/, "lux");
+            checkMonotonic(lux, true /*strictly increasing*/, "lux");
             checkMonotonic(nits, false /*strictly increasing*/, "nits");
             mCurveLux = lux;
             mCurveNits = nits;
-            return this;
         }
 
         /**
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index 00a1f6f..4080ee6 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -87,8 +87,8 @@
      * guarantees that {@link #bindInput(InputBinding)},
      * {@link #startInput(IBinder, IInputContext, int, EditorInfo, boolean)}, and
      * {@link #unbindInput()} are called with the same order as the original calls
-     * in {@link com.android.server.InputMethodManagerService}.  See {@link IBinder#FLAG_ONEWAY}
-     * for detailed semantics.</p>
+     * in {@link com.android.server.inputmethod.InputMethodManagerService}.
+     * See {@link IBinder#FLAG_ONEWAY} for detailed semantics.</p>
      */
     AtomicBoolean mIsUnbindIssued = null;
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 0645a16..d913273 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -313,6 +313,7 @@
  * @attr ref android.R.styleable#TextView_fallbackLineSpacing
  * @attr ref android.R.styleable#TextView_letterSpacing
  * @attr ref android.R.styleable#TextView_fontFeatureSettings
+ * @attr ref android.R.styleable#TextView_fontVariationSettings
  * @attr ref android.R.styleable#TextView_breakStrategy
  * @attr ref android.R.styleable#TextView_hyphenationFrequency
  * @attr ref android.R.styleable#TextView_autoSizeTextType
@@ -4382,6 +4383,8 @@
      *
      * @see #getFontVariationSettings()
      * @see FontVariationAxis
+     *
+     * @attr ref android.R.styleable#TextView_fontVariationSettings
      */
     public boolean setFontVariationSettings(@Nullable String fontVariationSettings) {
         final String existingSettings = mTextPaint.getFontVariationSettings();
diff --git a/core/java/com/android/internal/view/InputBindResult.java b/core/java/com/android/internal/view/InputBindResult.java
index e03c1f8..7548c22 100644
--- a/core/java/com/android/internal/view/InputBindResult.java
+++ b/core/java/com/android/internal/view/InputBindResult.java
@@ -60,7 +60,7 @@
         /**
          * Indicates that this is a temporary binding until the
          * {@link android.inputmethodservice.InputMethodService} (IMS) establishes a valid session
-         * to {@link com.android.server.InputMethodManagerService} (IMMS).
+         * to {@link com.android.server.inputmethod.InputMethodManagerService} (IMMS).
          *
          * <p>Note that in this state the IMS is already bound to IMMS but the logical session
          * is not yet established on top of the IPC channel.</p>
@@ -73,7 +73,7 @@
         /**
          * Indicates that this is a temporary binding until the
          * {@link android.inputmethodservice.InputMethodService} (IMS) establishes a valid session
-         * to {@link com.android.server.InputMethodManagerService} (IMMS).
+         * to {@link com.android.server.inputmethod.InputMethodManagerService} (IMMS).
          *
          * <p>Note that in this state the IMMS has already initiated a connection to the IMS but
          * the binding process is not completed yet.</p>
@@ -91,12 +91,14 @@
         int SUCCESS_REPORT_WINDOW_FOCUS_ONLY = 3;
         /**
          * Indicates somehow
-         * {@link com.android.server.InputMethodManagerService#startInputOrWindowGainedFocus} is
-         * trying to return null {@link InputBindResult}, which must never happen.
+         * {@link
+         * com.android.server.inputmethod.InputMethodManagerService#startInputOrWindowGainedFocus}
+         * is trying to return null {@link InputBindResult}, which must never happen.
          */
         int ERROR_NULL = 4;
         /**
-         * Indicates that {@link com.android.server.InputMethodManagerService} recognizes no IME.
+         * Indicates that {@link com.android.server.inputmethod.InputMethodManagerService}
+         * recognizes no IME.
          */
         int ERROR_NO_IME = 5;
         /**
@@ -114,8 +116,8 @@
          */
         int ERROR_SYSTEM_NOT_READY = 7;
         /**
-         * Indicates that {@link com.android.server.InputMethodManagerService} tried to connect to
-         * an {@link android.inputmethodservice.InputMethodService} but failed.
+         * Indicates that {@link com.android.server.inputmethod.InputMethodManagerService} tried to
+         * connect to an {@link android.inputmethodservice.InputMethodService} but failed.
          *
          * @see android.content.Context#bindServiceAsUser(Intent, ServiceConnection, int, UserHandle)
          */
@@ -137,7 +139,8 @@
          * The client should try to restart input when its {@link android.view.Window} is focused
          * again.</p>
          *
-         * @see com.android.server.wm.WindowManagerService#inputMethodClientHasFocus(IInputMethodClient)
+         * @see com.android.server.wm.WindowManagerInternal#inputMethodClientHasFocus(
+         * IInputMethodClient)
          */
         int ERROR_NOT_IME_TARGET_WINDOW = 11;
         /**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f845bd0..9ab55d6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -584,7 +584,7 @@
     <protected-broadcast android:name="android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED" />
     <protected-broadcast android:name="android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" />
     <protected-broadcast android:name="android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED" />
-    <protected-broadcast android:name="com.android.server.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER" />
+    <protected-broadcast android:name="com.android.server.inputmethod.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER" />
 
     <!-- Time zone rules update intents fired by the system server -->
     <protected-broadcast android:name="com.android.intent.action.timezone.RULES_UPDATE_OPERATION" />
@@ -3352,7 +3352,7 @@
           @hide
           @removed -->
     <permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"
-        android:protectionLevel="signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to know what content is playing and control its playback.
          <p>Not for use by third-party applications due to privacy of media consumption</p>  -->
@@ -4120,11 +4120,6 @@
     <permission android:name="android.permission.DISABLE_HIDDEN_API_CHECKS"
                 android:protectionLevel="signature" />
 
-    <!-- Allows an application to read emergency info name.
-         @hide <p>Not for use by third-party applications. -->
-    <permission android:name="com.android.emergency.permission.READ_EMERGENCY_INFO_NAME"
-                android:protectionLevel="signature" />
-
     <application android:process="system"
                  android:persistent="true"
                  android:hasCode="false"
diff --git a/core/res/res/values-night/themes_device_defaults.xml b/core/res/res/values-night/themes_device_defaults.xml
index 5e3675a..c8d4d05 100644
--- a/core/res/res/values-night/themes_device_defaults.xml
+++ b/core/res/res/values-night/themes_device_defaults.xml
@@ -51,4 +51,7 @@
           -->
     <!-- DeviceDefault theme for a window that should look like the Settings app.  -->
     <style name="Theme.DeviceDefault.Settings" parent="Theme.DeviceDefault"/>
+
+    <!-- Theme for the dialog shown when an app crashes or ANRs. -->
+    <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.DeviceDefault.Dialog.Alert" />
 </resources>
diff --git a/core/res/res/values-television/themes.xml b/core/res/res/values-television/themes.xml
index 377982a..0712cbc 100644
--- a/core/res/res/values-television/themes.xml
+++ b/core/res/res/values-television/themes.xml
@@ -15,7 +15,7 @@
 -->
 <resources>
     <style name="Theme.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
-    <style name="Theme.Dialog.AppError" parent="Theme.Leanback.Dialog.AppError" />
+    <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.Leanback.Dialog.AppError" />
     <style name="Theme.Holo.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
     <style name="Theme.Holo.Light.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
     <style name="Theme.Material.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
diff --git a/core/res/res/values-watch/themes.xml b/core/res/res/values-watch/themes.xml
index 04df180..1be47ba 100644
--- a/core/res/res/values-watch/themes.xml
+++ b/core/res/res/values-watch/themes.xml
@@ -15,7 +15,7 @@
 -->
 <resources>
     <!-- Theme for the dialog shown when an app crashes or ANRs. Override to make it dark. -->
-    <style name="Theme.Dialog.AppError" parent="Theme.DeviceDefault.Dialog.Alert">
+    <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.DeviceDefault.Dialog.Alert">
         <item name="windowContentTransitions">false</item>
         <item name="windowActivityTransitions">false</item>
         <item name="windowCloseOnTouchOutside">false</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 92cca72..389278f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2099,7 +2099,7 @@
   <java-symbol type="string" name="vpn_lockdown_error" />
   <java-symbol type="string" name="vpn_lockdown_config" />
   <java-symbol type="string" name="wallpaper_binding_label" />
-  <java-symbol type="style" name="Theme.Dialog.AppError" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Dialog.AppError" />
   <java-symbol type="style" name="Theme.Leanback.Dialog.Alert" />
   <java-symbol type="style" name="Theme.Toast" />
   <java-symbol type="xml" name="storage_list" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 3937af5..a7530ce 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -869,13 +869,6 @@
     <!-- System themes -->
     <eat-comment />
 
-    <!-- Theme for the dialog shown when an app crashes or ANRs. -->
-    <style name="Theme.Dialog.AppError" parent="Theme.DeviceDefault.Light.Dialog.Alert">
-        <item name="windowContentTransitions">false</item>
-        <item name="windowActivityTransitions">false</item>
-        <item name="windowCloseOnTouchOutside">false</item>
-    </style>
-
     <!-- Special theme for the recent apps dialog, to allow customization
          with overlays. -->
     <style name="Theme.Dialog.RecentApplications" parent="Theme.DeviceDefault.Light.Dialog">
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 14e5082..92096ab 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -719,6 +719,13 @@
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
+    <!-- Theme for the dialog shown when an app crashes or ANRs. -->
+    <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.DeviceDefault.Light.Dialog.Alert">
+        <item name="windowContentTransitions">false</item>
+        <item name="windowActivityTransitions">false</item>
+        <item name="windowCloseOnTouchOutside">false</item>
+    </style>
+
     <style name="Theme.DeviceDefault.SearchBar" parent="Theme.Material.SearchBar">
         <!-- Color palette -->
         <item name="colorPrimary">@color/primary_device_default_dark</item>
diff --git a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
index 5ef30a8..dcc51e1 100644
--- a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
+++ b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
@@ -48,8 +48,8 @@
 
     @Test
     public void testSetCurveIsUnmodified() {
-        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
-        builder.setCurve(LUX_LEVELS, NITS_LEVELS);
+        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder(
+                LUX_LEVELS, NITS_LEVELS);
         BrightnessConfiguration config = builder.build();
         Pair<float[], float[]> curve = config.getCurve();
         assertArrayEquals(LUX_LEVELS, curve.first, "lux");
@@ -58,45 +58,33 @@
 
     @Test(expected = IllegalArgumentException.class)
     public void testCurveMustHaveZeroLuxPoint() {
-        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
         float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
         lux[0] = 1f;
-        builder.setCurve(lux, NITS_LEVELS);
-    }
-
-    @Test(expected = IllegalStateException.class)
-    public void testCurveMustBeSet() {
-        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
-        builder.build();
+        new BrightnessConfiguration.Builder(lux, NITS_LEVELS);
     }
 
     @Test(expected = NullPointerException.class)
     public void testCurveMustNotHaveNullArrays() {
-        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
-        builder.setCurve(null, null);
+        new BrightnessConfiguration.Builder(null, null);
     }
 
     @Test(expected = IllegalArgumentException.class)
     public void testCurveMustNotHaveEmptyArrays() {
-        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
-        builder.setCurve(new float[0], new float[0]);
+        new BrightnessConfiguration.Builder(new float[0], new float[0]);
     }
 
     @Test
     public void testCurveMustNotHaveArraysOfDifferentLengths() {
         assertThrows(IllegalArgumentException.class, () -> {
-            BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
             float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length + 1);
             lux[lux.length - 1] = lux[lux.length - 2] + 1;
-            boolean exceptionThrown = false;
-            builder.setCurve(lux, NITS_LEVELS);
+            new BrightnessConfiguration.Builder(lux, NITS_LEVELS);
         });
 
         assertThrows(IllegalArgumentException.class, () -> {
-            BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
             float[] nits = Arrays.copyOf(NITS_LEVELS, NITS_LEVELS.length + 1);
             nits[nits.length - 1] = nits[nits.length - 2] + 1;
-            builder.setCurve(LUX_LEVELS, nits);
+            new BrightnessConfiguration.Builder(LUX_LEVELS, nits);
         });
     }
 
@@ -105,23 +93,21 @@
         assertThrows(IllegalArgumentException.class, () -> {
             float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
             lux[lux.length - 1] = Float.NaN;
-            BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
-            builder.setCurve(lux, NITS_LEVELS);
+            new BrightnessConfiguration.Builder(lux, NITS_LEVELS);
         });
 
         assertThrows(IllegalArgumentException.class, () -> {
             float[] nits = Arrays.copyOf(NITS_LEVELS, NITS_LEVELS.length);
             nits[nits.length - 1] = Float.NaN;
-            BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
-            builder.setCurve(LUX_LEVELS, nits);
+            new BrightnessConfiguration.Builder(LUX_LEVELS, nits);
         });
     }
 
 
     @Test
     public void testParceledConfigIsEquivalent() {
-        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
-        builder.setCurve(LUX_LEVELS, NITS_LEVELS);
+        BrightnessConfiguration.Builder builder =
+                new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
         BrightnessConfiguration config = builder.build();
         Parcel p = Parcel.obtain();
         p.writeParcelable(config, 0 /*flags*/);
@@ -133,12 +119,11 @@
 
     @Test
     public void testEquals() {
-        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
-        builder.setCurve(LUX_LEVELS, NITS_LEVELS);
+        BrightnessConfiguration.Builder builder =
+                new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
         BrightnessConfiguration baseConfig = builder.build();
 
-        builder = new BrightnessConfiguration.Builder();
-        builder.setCurve(LUX_LEVELS, NITS_LEVELS);
+        builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
         BrightnessConfiguration identicalConfig = builder.build();
         assertEquals(baseConfig, identicalConfig);
         assertEquals("hashCodes must be equal for identical configs",
@@ -146,15 +131,13 @@
 
         float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
         lux[lux.length - 1] = lux[lux.length - 1] * 2;
-        builder = new BrightnessConfiguration.Builder();
-        builder.setCurve(lux, NITS_LEVELS);
+        builder = new BrightnessConfiguration.Builder(lux, NITS_LEVELS);
         BrightnessConfiguration luxDifferConfig = builder.build();
         assertNotEquals(baseConfig, luxDifferConfig);
 
         float[] nits = Arrays.copyOf(NITS_LEVELS, NITS_LEVELS.length);
         nits[nits.length - 1] = nits[nits.length - 1] * 2;
-        builder = new BrightnessConfiguration.Builder();
-        builder.setCurve(LUX_LEVELS, nits);
+        builder = new BrightnessConfiguration.Builder(LUX_LEVELS, nits);
         BrightnessConfiguration nitsDifferConfig = builder.build();
         assertNotEquals(baseConfig, nitsDifferConfig);
     }
diff --git a/core/tests/coretests/src/android/os/SetPersistentVrThreadTest.java b/core/tests/coretests/src/android/os/SetPersistentVrThreadTest.java
index 920988b..9e44554 100644
--- a/core/tests/coretests/src/android/os/SetPersistentVrThreadTest.java
+++ b/core/tests/coretests/src/android/os/SetPersistentVrThreadTest.java
@@ -24,7 +24,6 @@
 import android.provider.Settings;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
 
 /**
  * Tests ActivityManager#setPersistentVrThread and ActivityManager#setVrThread's
@@ -76,9 +75,11 @@
     }
 
     private void setPersistentVrModeEnabled(boolean enable) throws Throwable {
-        mVrManager.setPersistentVrModeEnabled(enable);
-        // Allow the system time to send out callbacks for persistent VR mode.
-        Thread.sleep(200);
+        if (mVrManager != null) {
+            mVrManager.setPersistentVrModeEnabled(enable);
+            // Allow the system time to send out callbacks for persistent VR mode.
+            Thread.sleep(200);
+        }
     }
 
     @SmallTest
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 339a7ee..7681cc3 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -91,6 +91,7 @@
         "android_media_Media2HTTPConnection.cpp",
         "android_media_Media2HTTPService.cpp",
         "android_media_Media2DataSource.cpp",
+        "android_media_MediaMetricsJNI.cpp",
         "android_media_MediaPlayer2.cpp",
         "android_media_SyncParams.cpp",
     ],
@@ -98,7 +99,6 @@
     shared_libs: [
         "android.hardware.cas@1.0",  // for CasManager. VNDK???
         "android.hardware.cas.native@1.0",  // CasManager. VNDK???
-        "libandroid_runtime",  // ???
         "libaudioclient",  // for use of AudioTrack, AudioSystem. to be removed
         "libbinder",
         "libgui",  // for VideoFrameScheduler
@@ -120,13 +120,9 @@
     header_libs: ["libhardware_headers"],
 
     static_libs: [
-        "libbacktrace",
         "libbase",
-        "libc_malloc_debug_backtrace",
         "libcrypto",
         "libcutils",
-        "libdexfile",
-        "liblzma",
         "libmedia_helper",
         "libmedia_player2_util",
         "libmediadrm",
@@ -135,7 +131,7 @@
         "libmediaplayer2",
         "libmediaplayer2-protos",
         "libmediautils",
-        "libnetd_client",
+        "libnetd_client",  // for setNetworkForUser
         "libprotobuf-cpp-lite",
         "libstagefright_esds",
         "libstagefright_foundation",
@@ -146,9 +142,6 @@
         "libstagefright_player2",
         "libstagefright_rtsp",
         "libstagefright_timedtext2",
-        "libunwindstack",
-        "libutilscallstack",
-        "libziparchive",
     ],
 
     group_static_libs: true,
diff --git a/media/jni/android_media_MediaMetricsJNI.cpp b/media/jni/android_media_MediaMetricsJNI.cpp
new file mode 100644
index 0000000..3ded8c2
--- /dev/null
+++ b/media/jni/android_media_MediaMetricsJNI.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+
+#include "android_media_MediaMetricsJNI.h"
+#include <media/MediaAnalyticsItem.h>
+
+
+// Copeid from core/jni/ (libandroid_runtime.so)
+namespace android {
+
+// place the attributes into a java PersistableBundle object
+jobject MediaMetricsJNI::writeMetricsToBundle(JNIEnv* env, MediaAnalyticsItem *item, jobject mybundle) {
+
+    jclass clazzBundle = env->FindClass("android/os/PersistableBundle");
+    if (clazzBundle==NULL) {
+        ALOGD("can't find android/os/PersistableBundle");
+        return NULL;
+    }
+    // sometimes the caller provides one for us to fill
+    if (mybundle == NULL) {
+        // create the bundle
+        jmethodID constructID = env->GetMethodID(clazzBundle, "<init>", "()V");
+        mybundle = env->NewObject(clazzBundle, constructID);
+        if (mybundle == NULL) {
+            return NULL;
+        }
+    }
+
+    // grab methods that we can invoke
+    jmethodID setIntID = env->GetMethodID(clazzBundle, "putInt", "(Ljava/lang/String;I)V");
+    jmethodID setLongID = env->GetMethodID(clazzBundle, "putLong", "(Ljava/lang/String;J)V");
+    jmethodID setDoubleID = env->GetMethodID(clazzBundle, "putDouble", "(Ljava/lang/String;D)V");
+    jmethodID setStringID = env->GetMethodID(clazzBundle, "putString", "(Ljava/lang/String;Ljava/lang/String;)V");
+
+    // env, class, method, {parms}
+    //env->CallVoidMethod(env, mybundle, setIntID, jstr, jint);
+
+    // iterate through my attributes
+    // -- get name, get type, get value
+    // -- insert appropriately into the bundle
+    for (size_t i = 0 ; i < item->mPropCount; i++ ) {
+            MediaAnalyticsItem::Prop *prop = &item->mProps[i];
+            // build the key parameter from prop->mName
+            jstring keyName = env->NewStringUTF(prop->mName);
+            // invoke the appropriate method to insert
+            switch (prop->mType) {
+                case MediaAnalyticsItem::kTypeInt32:
+                    env->CallVoidMethod(mybundle, setIntID,
+                                        keyName, (jint) prop->u.int32Value);
+                    break;
+                case MediaAnalyticsItem::kTypeInt64:
+                    env->CallVoidMethod(mybundle, setLongID,
+                                        keyName, (jlong) prop->u.int64Value);
+                    break;
+                case MediaAnalyticsItem::kTypeDouble:
+                    env->CallVoidMethod(mybundle, setDoubleID,
+                                        keyName, (jdouble) prop->u.doubleValue);
+                    break;
+                case MediaAnalyticsItem::kTypeCString:
+                    env->CallVoidMethod(mybundle, setStringID, keyName,
+                                        env->NewStringUTF(prop->u.CStringValue));
+                    break;
+                default:
+                        ALOGE("to_String bad item type: %d for %s",
+                              prop->mType, prop->mName);
+                        break;
+            }
+    }
+
+    return mybundle;
+}
+
+};  // namespace android
+
diff --git a/media/jni/android_media_MediaMetricsJNI.h b/media/jni/android_media_MediaMetricsJNI.h
new file mode 100644
index 0000000..fd621ea
--- /dev/null
+++ b/media/jni/android_media_MediaMetricsJNI.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#ifndef _ANDROID_MEDIA_MEDIAMETRICSJNI_H_
+#define _ANDROID_MEDIA_MEDIAMETRICSJNI_H_
+
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <media/MediaAnalyticsItem.h>
+
+// Copeid from core/jni/ (libandroid_runtime.so)
+namespace android {
+
+class MediaMetricsJNI {
+public:
+    static jobject writeMetricsToBundle(JNIEnv* env, MediaAnalyticsItem *item, jobject mybundle);
+};
+
+};  // namespace android
+
+#endif //  _ANDROID_MEDIA_MEDIAMETRICSJNI_H_
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index 801dade..d4c84b5 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -909,7 +909,7 @@
 }
 
 static jboolean
-android_media_MediaPlayer2_setParameter(JNIEnv *env, jobject thiz, jint key, jobject java_request)
+android_media_MediaPlayer2_setParameter(JNIEnv *env, jobject thiz, jint key, jobject)
 {
     ALOGV("setParameter: key %d", key);
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
@@ -918,9 +918,11 @@
         return false;
     }
 
-    // TODO: parcelForJavaObject() shouldn't be used since it's dependent on
-    //       framework's Parcel implementation. This setParameter() is used
-    //       only with AudioAttribute. Can this be used as jobject with JAudioTrack?
+    return false;
+    // TODO: set/getParameter is temporarily disabled to remove android_runtime.so dependency.
+    //       Once JAudioTrack migration is done, the AudioAttribute jobject
+    //       should be directly passed to AudioTrack without native parcel conversion.
+    /*
     Parcel *request = parcelForJavaObject(env, java_request);
     status_t err = mp->setParameter(key, *request);
     if (err == OK) {
@@ -928,6 +930,7 @@
     } else {
         return false;
     }
+    */
 }
 
 static jobject
@@ -940,6 +943,11 @@
         return NULL;
     }
 
+    return NULL;
+    // TODO: set/getParameter is temporarily disabled to remove android_runtime.so dependency.
+    //       Once JAudioTrack migration is done, the AudioAttribute jobject
+    //       should be directly passed to AudioTrack without native parcel conversion.
+    /*
     jobject jParcel = createJavaParcelObject(env);
     if (jParcel != NULL) {
         Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
@@ -950,6 +958,7 @@
         }
     }
     return jParcel;
+    */
 }
 
 static void
@@ -1005,7 +1014,11 @@
     PlayerMessage response;
     request.ParseFromArray(pData, pDataLen);
 
-    media_player->invoke(request, &response);
+    process_media_player_call( env, thiz, media_player->invoke(request, &response),
+            "java.lang.RuntimeException", NULL );
+    if (env->ExceptionCheck()) {
+        return NULL;
+    }
 
     int size = response.ByteSize();
     jbyte* temp = new jbyte[size];
@@ -1019,55 +1032,6 @@
     return out;
 }
 
-// Sends the new filter to the client.
-static jint
-android_media_MediaPlayer2_setMetadataFilter(JNIEnv *env, jobject thiz, jobject request)
-{
-    sp<MediaPlayer2> media_player = getMediaPlayer(env, thiz);
-    if (media_player == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return UNKNOWN_ERROR;
-    }
-
-    Parcel *filter = parcelForJavaObject(env, request);
-
-    if (filter == NULL ) {
-        jniThrowException(env, "java/lang/RuntimeException", "Filter is null");
-        return UNKNOWN_ERROR;
-    }
-
-    return (jint) media_player->setMetadataFilter(*filter);
-}
-
-static jboolean
-android_media_MediaPlayer2_getMetadata(JNIEnv *env, jobject thiz, jboolean update_only,
-                                      jboolean apply_filter, jobject reply)
-{
-    sp<MediaPlayer2> media_player = getMediaPlayer(env, thiz);
-    if (media_player == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return JNI_FALSE;
-    }
-
-    Parcel *metadata = parcelForJavaObject(env, reply);
-
-    if (metadata == NULL ) {
-        jniThrowException(env, "java/lang/RuntimeException", "Reply parcel is null");
-        return JNI_FALSE;
-    }
-
-    metadata->freeData();
-    // On return metadata is positioned at the beginning of the
-    // metadata. Note however that the parcel actually starts with the
-    // return code so you should not rewind the parcel using
-    // setDataPosition(0).
-    if (media_player->getMetadata(update_only, apply_filter, metadata) == OK) {
-        return JNI_TRUE;
-    } else {
-        return JNI_FALSE;
-    }
-}
-
 // This function gets some field IDs, which in turn causes class initialization.
 // It is called from a static block in MediaPlayer2, which won't run until the
 // first time an instance of this class is used.
@@ -1532,8 +1496,6 @@
     {"isLooping",           "()Z",                              (void *)android_media_MediaPlayer2_isLooping},
     {"_setVolume",          "(FF)V",                            (void *)android_media_MediaPlayer2_setVolume},
     {"_invoke",             "([B)[B",                           (void *)android_media_MediaPlayer2_invoke},
-    {"native_setMetadataFilter", "(Landroid/os/Parcel;)I",      (void *)android_media_MediaPlayer2_setMetadataFilter},
-    {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer2_getMetadata},
     {"native_init",         "()V",                              (void *)android_media_MediaPlayer2_native_init},
     {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer2_native_setup},
     {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer2_native_finalize},
diff --git a/packages/CarSystemUI/Android.bp b/packages/CarSystemUI/Android.bp
index f908595..86f9032 100644
--- a/packages/CarSystemUI/Android.bp
+++ b/packages/CarSystemUI/Android.bp
@@ -51,6 +51,7 @@
     libs: [
         "telephony-common",
         "android.car",
+        "android.car.user",
     ],
 
     manifest: "AndroidManifest.xml",
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
index 0c4e02b..e13e566 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
@@ -33,7 +33,6 @@
 
 final class A2dpSinkProfile implements LocalBluetoothProfile {
     private static final String TAG = "A2dpSinkProfile";
-    private static boolean V = true;
 
     private BluetoothA2dpSink mService;
     private boolean mIsProfileReady;
@@ -56,7 +55,7 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (V) Log.d(TAG,"Bluetooth service connected");
+            Log.d(TAG, "Bluetooth service connected");
             mService = (BluetoothA2dpSink) proxy;
             // We just bound to the service, so refresh the UI for any connected A2DP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -75,7 +74,7 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            if (V) Log.d(TAG,"Bluetooth service disconnected");
+            Log.d(TAG, "Bluetooth service disconnected");
             mIsProfileReady=false;
         }
     }
@@ -106,7 +105,9 @@
     }
 
     public List<BluetoothDevice> getConnectedDevices() {
-        if (mService == null) return new ArrayList<BluetoothDevice>(0);
+        if (mService == null) {
+            return new ArrayList<BluetoothDevice>(0);
+        }
         return mService.getDevicesMatchingConnectionStates(
               new int[] {BluetoothProfile.STATE_CONNECTED,
                          BluetoothProfile.STATE_CONNECTING,
@@ -114,24 +115,18 @@
     }
 
     public boolean connect(BluetoothDevice device) {
-        if (mService == null) return false;
-        List<BluetoothDevice> srcs = getConnectedDevices();
-        if (srcs != null) {
-            for (BluetoothDevice src : srcs) {
-                if (src.equals(device)) {
-                    // Connect to same device, Ignore it
-                    Log.d(TAG,"Ignoring Connect");
-                    return true;
-                }
-            }
+        if (mService == null) {
+            return false;
         }
         return mService.connect(device);
     }
 
     public boolean disconnect(BluetoothDevice device) {
-        if (mService == null) return false;
+        if (mService == null) {
+            return false;
+        }
         // Downgrade priority as user is disconnecting the headset.
-        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
+        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
             mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
         }
         return mService.disconnect(device);
@@ -145,17 +140,23 @@
     }
 
     public boolean isPreferred(BluetoothDevice device) {
-        if (mService == null) return false;
+        if (mService == null) {
+            return false;
+        }
         return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
     }
 
     public int getPreferred(BluetoothDevice device) {
-        if (mService == null) return BluetoothProfile.PRIORITY_OFF;
+        if (mService == null) {
+            return BluetoothProfile.PRIORITY_OFF;
+        }
         return mService.getPriority(device);
     }
 
     public void setPreferred(BluetoothDevice device, boolean preferred) {
-        if (mService == null) return;
+        if (mService == null) {
+            return;
+        }
         if (preferred) {
             if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
                 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
@@ -166,7 +167,9 @@
     }
 
     boolean isA2dpPlaying() {
-        if (mService == null) return false;
+        if (mService == null) {
+            return false;
+        }
         List<BluetoothDevice> srcs = mService.getConnectedDevices();
         if (!srcs.isEmpty()) {
             if (mService.isA2dpPlaying(srcs.get(0))) {
@@ -208,7 +211,7 @@
     }
 
     protected void finalize() {
-        if (V) Log.d(TAG, "finalize()");
+        Log.d(TAG, "finalize()");
         if (mService != null) {
             try {
                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.A2DP_SINK,
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 649900b..b9f7323 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -78,12 +78,6 @@
 
     private final static String MESSAGE_REJECTION_COUNT_PREFS_NAME = "bluetooth_message_reject";
 
-    /**
-     * When we connect to multiple profiles, we only want to display a single
-     * error even if they all fail. This tracks that state.
-     */
-    private boolean mIsConnectingErrorPossible;
-
     public long getHiSyncId() {
         return mHiSyncId;
     }
@@ -230,9 +224,6 @@
             return;
         }
 
-        // Reset the only-show-one-error-dialog tracking variable
-        mIsConnectingErrorPossible = true;
-
         int preferredProfiles = 0;
         for (LocalBluetoothProfile profile : mProfiles) {
             if (connectAllProfiles ? profile.isConnectable() : profile.isAutoConnectable()) {
@@ -253,8 +244,6 @@
         if (!ensurePaired()) {
             return;
         }
-        // Reset the only-show-one-error-dialog tracking variable
-        mIsConnectingErrorPossible = true;
 
         for (LocalBluetoothProfile profile : mProfiles) {
             if (profile.isAutoConnectable()) {
@@ -271,8 +260,6 @@
      */
     public void connectProfile(LocalBluetoothProfile profile) {
         mConnectAttempted = SystemClock.elapsedRealtime();
-        // Reset the only-show-one-error-dialog tracking variable
-        mIsConnectingErrorPossible = true;
         connectInt(profile);
         // Refresh the UI based on profile.connect() call
         refresh();
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
index f9f6233..4b6a22c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
@@ -36,7 +36,6 @@
  */
 final class HfpClientProfile implements LocalBluetoothProfile {
     private static final String TAG = "HfpClientProfile";
-    private static boolean V = false;
 
     private BluetoothHeadsetClient mService;
     private boolean mIsProfileReady;
@@ -60,7 +59,7 @@
 
         @Override
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (V) Log.d(TAG,"Bluetooth service connected");
+            Log.d(TAG, "Bluetooth service connected");
             mService = (BluetoothHeadsetClient) proxy;
             // We just bound to the service, so refresh the UI for any connected HFP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -81,7 +80,7 @@
 
         @Override
         public void onServiceDisconnected(int profile) {
-            if (V) Log.d(TAG,"Bluetooth service disconnected");
+            Log.d(TAG, "Bluetooth service disconnected");
             mIsProfileReady=false;
         }
     }
@@ -115,7 +114,9 @@
     }
 
     public List<BluetoothDevice> getConnectedDevices() {
-        if (mService == null) return new ArrayList<BluetoothDevice>(0);
+        if (mService == null) {
+            return new ArrayList<BluetoothDevice>(0);
+        }
         return mService.getDevicesMatchingConnectionStates(
               new int[] {BluetoothProfile.STATE_CONNECTED,
                          BluetoothProfile.STATE_CONNECTING,
@@ -124,23 +125,17 @@
 
     @Override
     public boolean connect(BluetoothDevice device) {
-        if (mService == null) return false;
-        List<BluetoothDevice> srcs = getConnectedDevices();
-        if (srcs != null) {
-            for (BluetoothDevice src : srcs) {
-                if (src.equals(device)) {
-                    // Connect to same device, Ignore it
-                    Log.d(TAG,"Ignoring Connect");
-                    return true;
-                }
-            }
+        if (mService == null) {
+            return false;
         }
         return mService.connect(device);
     }
 
     @Override
     public boolean disconnect(BluetoothDevice device) {
-        if (mService == null) return false;
+        if (mService == null) {
+            return false;
+        }
         // Downgrade priority as user is disconnecting the headset.
         if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
             mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
@@ -158,19 +153,25 @@
 
     @Override
     public boolean isPreferred(BluetoothDevice device) {
-        if (mService == null) return false;
+        if (mService == null) {
+            return false;
+        }
         return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
     }
 
     @Override
     public int getPreferred(BluetoothDevice device) {
-        if (mService == null) return BluetoothProfile.PRIORITY_OFF;
+        if (mService == null) {
+            return BluetoothProfile.PRIORITY_OFF;
+        }
         return mService.getPriority(device);
     }
 
     @Override
     public void setPreferred(BluetoothDevice device, boolean preferred) {
-        if (mService == null) return;
+        if (mService == null) {
+            return;
+        }
         if (preferred) {
             if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
                 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
@@ -216,7 +217,7 @@
     }
 
     protected void finalize() {
-        if (V) Log.d(TAG, "finalize()");
+        Log.d(TAG, "finalize()");
         if (mService != null) {
             try {
                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(
diff --git a/packages/SettingsLib/tests/robotests/config/robolectric.properties b/packages/SettingsLib/tests/robotests/config/robolectric.properties
index 34a2a1a..6b5b8e5 100644
--- a/packages/SettingsLib/tests/robotests/config/robolectric.properties
+++ b/packages/SettingsLib/tests/robotests/config/robolectric.properties
@@ -1,2 +1,5 @@
 manifest=frameworks/base/packages/SettingsLib/tests/robotests/AndroidManifest.xml
-sdk=NEWEST_SDK
\ No newline at end of file
+sdk=NEWEST_SDK
+
+shadows=\
+   com.android.settingslib.testutils.shadow.ShadowXmlUtils
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpSinkProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpSinkProfileTest.java
new file mode 100644
index 0000000..274fff8
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpSinkProfileTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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 com.android.settingslib.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothA2dpSink;
+import android.bluetooth.BluetoothProfile;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
+public class A2dpSinkProfileTest {
+
+    @Mock
+    private CachedBluetoothDeviceManager mDeviceManager;
+    @Mock
+    private LocalBluetoothProfileManager mProfileManager;
+    @Mock
+    private BluetoothA2dpSink mService;
+    @Mock
+    private CachedBluetoothDevice mCachedBluetoothDevice;
+    @Mock
+    private BluetoothDevice mBluetoothDevice;
+    private BluetoothProfile.ServiceListener mServiceListener;
+    private A2dpSinkProfile mProfile;
+    private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+        mProfile = new A2dpSinkProfile(RuntimeEnvironment.application,
+                mDeviceManager, mProfileManager);
+        mServiceListener = mShadowBluetoothAdapter.getServiceListener();
+        mServiceListener.onServiceConnected(BluetoothProfile.A2DP_SINK, mService);
+    }
+
+    @Test
+    public void connect_shouldConnectBluetoothA2dpSink() {
+        mProfile.connect(mBluetoothDevice);
+        verify(mService).connect(mBluetoothDevice);
+    }
+
+    @Test
+    public void disconnect_shouldDisconnectBluetoothA2dpSink() {
+        mProfile.disconnect(mBluetoothDevice);
+        verify(mService).disconnect(mBluetoothDevice);
+    }
+
+    @Test
+    public void getConnectionStatus_shouldReturnConnectionState() {
+        when(mService.getConnectionState(mBluetoothDevice)).
+                thenReturn(BluetoothProfile.STATE_CONNECTED);
+        assertThat(mProfile.getConnectionStatus(mBluetoothDevice)).
+                isEqualTo(BluetoothProfile.STATE_CONNECTED);
+    }
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HfpClientProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HfpClientProfileTest.java
new file mode 100644
index 0000000..187be0b
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HfpClientProfileTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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 com.android.settingslib.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadsetClient;
+import android.bluetooth.BluetoothProfile;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
+public class HfpClientProfileTest {
+
+    @Mock
+    private CachedBluetoothDeviceManager mDeviceManager;
+    @Mock
+    private LocalBluetoothProfileManager mProfileManager;
+    @Mock
+    private BluetoothHeadsetClient mService;
+    @Mock
+    private CachedBluetoothDevice mCachedBluetoothDevice;
+    @Mock
+    private BluetoothDevice mBluetoothDevice;
+    private BluetoothProfile.ServiceListener mServiceListener;
+    private HfpClientProfile mProfile;
+    private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+        mProfile = new HfpClientProfile(RuntimeEnvironment.application,
+                mDeviceManager, mProfileManager);
+        mServiceListener = mShadowBluetoothAdapter.getServiceListener();
+        mServiceListener.onServiceConnected(BluetoothProfile.HEADSET_CLIENT, mService);
+    }
+
+    @Test
+    public void connect_shouldConnectBluetoothHeadsetClient() {
+        mProfile.connect(mBluetoothDevice);
+        verify(mService).connect(mBluetoothDevice);
+    }
+
+    @Test
+    public void disconnect_shouldDisconnectBluetoothHeadsetClient() {
+        mProfile.disconnect(mBluetoothDevice);
+        verify(mService).disconnect(mBluetoothDevice);
+    }
+
+    @Test
+    public void getConnectionStatus_shouldReturnConnectionState() {
+        when(mService.getConnectionState(mBluetoothDevice)).
+                thenReturn(BluetoothProfile.STATE_CONNECTED);
+        assertThat(mProfile.getConnectionStatus(mBluetoothDevice)).
+                isEqualTo(BluetoothProfile.STATE_CONNECTED);
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowXmlUtils.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowXmlUtils.java
new file mode 100644
index 0000000..3455765
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowXmlUtils.java
@@ -0,0 +1,43 @@
+/*
+ * 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 com.android.settingslib.testutils.shadow;
+
+import static org.robolectric.shadow.api.Shadow.directlyOn;
+
+import com.android.internal.util.XmlUtils;
+
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.util.ReflectionHelpers;
+
+@Implements(XmlUtils.class)
+public class ShadowXmlUtils {
+
+    @Implementation
+    public static final int convertValueToInt(CharSequence charSeq, int defaultValue) {
+        final Class<?> xmlUtilsClass = ReflectionHelpers.loadClass(
+                Robolectric.class.getClassLoader(), "com.android.internal.util.XmlUtils");
+        try {
+            return directlyOn(xmlUtilsClass, "convertValueToInt",
+                    ReflectionHelpers.ClassParameter.from(CharSequence.class, charSeq),
+                    ReflectionHelpers.ClassParameter.from(int.class, new Integer(defaultValue)));
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 4fc190d..ec35b3d 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -16,6 +16,8 @@
 
 package com.android.shell;
 
+import static android.content.pm.PackageManager.FEATURE_LEANBACK;
+import static android.content.pm.PackageManager.FEATURE_TELEVISION;
 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
 
 import static com.android.shell.BugreportPrefs.STATE_HIDE;
@@ -235,6 +237,7 @@
     private static final Bundle sNotificationBundle = new Bundle();
 
     private boolean mIsWatch;
+    private boolean mIsTv;
 
     private int mLastProgressPercent;
 
@@ -255,6 +258,9 @@
         final Configuration conf = mContext.getResources().getConfiguration();
         mIsWatch = (conf.uiMode & Configuration.UI_MODE_TYPE_MASK) ==
                 Configuration.UI_MODE_TYPE_WATCH;
+        PackageManager packageManager = getPackageManager();
+        mIsTv = packageManager.hasSystemFeature(FEATURE_LEANBACK)
+                || packageManager.hasSystemFeature(FEATURE_TELEVISION);
         NotificationManager nm = NotificationManager.from(mContext);
         nm.createNotificationChannel(
                 new NotificationChannel(NOTIFICATION_CHANNEL_ID,
@@ -500,8 +506,8 @@
                 .setProgress(info.max, info.progress, false)
                 .setOngoing(true);
 
-        // Wear bugreport doesn't need the bug info dialog, screenshot and cancel action.
-        if (!mIsWatch) {
+        // Wear and ATV bugreport doesn't need the bug info dialog, screenshot and cancel action.
+        if (!(mIsWatch || mIsTv)) {
             final Action cancelAction = new Action.Builder(null, mContext.getString(
                     com.android.internal.R.string.cancel), newCancelIntent(mContext, info)).build();
             final Intent infoIntent = new Intent(mContext, BugreportProgressService.class);
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 0913503..9c33116 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -66,6 +66,7 @@
     libs: [
         "telephony-common",
         "android.car",
+        "android.car.user",
     ],
 
     aaptflags: [
@@ -119,6 +120,7 @@
         "android.test.runner",
         "telephony-common",
         "android.car",
+        "android.car.user",
         "android.test.base",
     ],
     aaptflags: [
@@ -144,6 +146,7 @@
     libs: [
         "telephony-common",
         "android.car",
+        "android.car.user",
     ],
 
     dxflags: ["--multi-dex"],
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
index 2cbb78a..3744105 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -356,10 +356,11 @@
     if (supplementalIconId != 0) {
       Drawable supplementalIcon = mContext.getResources().getDrawable(supplementalIconId);
       supplementalIcon.mutate().setTint(color);
-      listItem.setSupplementalIcon(supplementalIcon, true,
-          supplementalIconOnClickListener);
+      listItem.setSupplementalIcon(supplementalIcon, true);
+      listItem.setSupplementalIconListener(supplementalIconOnClickListener);
     } else {
       listItem.setSupplementalEmptyIcon(true);
+      listItem.setSupplementalIconListener(null);
     }
 
     mVolumeLineItems.add(listItem);
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 6057614..aac37a2 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -38,7 +38,8 @@
     android.test.runner \
     telephony-common \
     android.test.base \
-    android.car
+    android.car \
+    android.car.user
 
 LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui:com.android.keyguard
 
diff --git a/proto/src/metrics_constants/OWNERS b/proto/src/metrics_constants/OWNERS
index 9c70a5e..7009282 100644
--- a/proto/src/metrics_constants/OWNERS
+++ b/proto/src/metrics_constants/OWNERS
@@ -1,3 +1,4 @@
+cwren@android.com
 yanglu@google.com
 yaochen@google.com
 yro@google.com
diff --git a/services/backup/java/com/android/server/backup/encryption/chunk/ChunkHash.java b/services/backup/java/com/android/server/backup/encryption/chunk/ChunkHash.java
new file mode 100644
index 0000000..1ae598e
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunk/ChunkHash.java
@@ -0,0 +1,89 @@
+/*
+ * 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 com.android.server.backup.encryption.chunk;
+
+import com.android.internal.util.Preconditions;
+import java.util.Arrays;
+import java.util.Base64;
+
+/**
+ * Represents the SHA-256 hash of the plaintext of a chunk, which is frequently used as a key.
+ *
+ * <p>This class is {@link Comparable} and implements {@link #equals(Object)} and {@link
+ * #hashCode()}.
+ */
+public class ChunkHash implements Comparable<ChunkHash> {
+    /** The length of the hash in bytes. The hash is a SHA-256, so this is 256 bits. */
+    public static final int HASH_LENGTH_BYTES = 256 / 8;
+
+    private static final int UNSIGNED_MASK = 0xFF;
+
+    private final byte[] mHash;
+
+    /** Constructs a new instance which wraps the given SHA-256 hash bytes. */
+    public ChunkHash(byte[] hash) {
+        Preconditions.checkArgument(hash.length == HASH_LENGTH_BYTES, "Hash must have 256 bits");
+        mHash = hash;
+    }
+
+    public byte[] getHash() {
+        return mHash;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof ChunkHash)) {
+            return false;
+        }
+
+        ChunkHash chunkHash = (ChunkHash) o;
+        return Arrays.equals(mHash, chunkHash.mHash);
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(mHash);
+    }
+
+    @Override
+    public int compareTo(ChunkHash other) {
+        return lexicographicalCompareUnsignedBytes(getHash(), other.getHash());
+    }
+
+    @Override
+    public String toString() {
+        return Base64.getEncoder().encodeToString(mHash);
+    }
+
+    private static int lexicographicalCompareUnsignedBytes(byte[] left, byte[] right) {
+        int minLength = Math.min(left.length, right.length);
+        for (int i = 0; i < minLength; i++) {
+            int result = toInt(left[i]) - toInt(right[i]);
+            if (result != 0) {
+                return result;
+            }
+        }
+        return left.length - right.length;
+    }
+
+    private static int toInt(byte value) {
+        return value & UNSIGNED_MASK;
+    }
+}
diff --git a/services/core/java/com/android/server/HardwarePropertiesManagerService.java b/services/core/java/com/android/server/HardwarePropertiesManagerService.java
index 4016d29..e21a3d7 100644
--- a/services/core/java/com/android/server/HardwarePropertiesManagerService.java
+++ b/services/core/java/com/android/server/HardwarePropertiesManagerService.java
@@ -26,7 +26,6 @@
 import static android.os.HardwarePropertiesManager.TEMPERATURE_THROTTLING_BELOW_VR_MIN;
 
 import android.Manifest;
-import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
@@ -34,8 +33,8 @@
 import android.os.Binder;
 import android.os.CpuUsageInfo;
 import android.os.IHardwarePropertiesManager;
-import android.os.Process;
 import android.os.UserHandle;
+
 import com.android.internal.util.DumpUtils;
 import com.android.server.vr.VrManagerInternal;
 
@@ -166,11 +165,11 @@
         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
         final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
         if (!dpm.isDeviceOwnerApp(callingPackage)
-                && !vrService.isCurrentVrListener(callingPackage, userId)
                 && mContext.checkCallingOrSelfPermission(Manifest.permission.DEVICE_POWER)
-                        != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("The caller is not a device owner, bound VrListenerService"
-                + ", or holding the DEVICE_POWER permission.");
+                        != PackageManager.PERMISSION_GRANTED
+                && (vrService == null || !vrService.isCurrentVrListener(callingPackage, userId))) {
+            throw new SecurityException("The caller is neither a device owner"
+                + ", nor holding the DEVICE_POWER permission, nor the current VrListener.");
         }
     }
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2ee598f..b64e8b8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2382,7 +2382,7 @@
                 }
             }
             int logSampleRate = Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, -1);
+                    Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, 0x200);
             if (logSampleRate < 0 || logSampleRate > 0x10000) {
                 logSampleRate = -1;
             }
@@ -11941,7 +11941,9 @@
                         printed = true;
                     }
                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
-                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
+                    pw.print(" "); pw.print(reg.pkg);
+                    final IUidObserver observer = mUidObservers.getRegisteredCallbackItem(i);
+                    pw.print(" "); pw.print(observer.getClass().getTypeName()); pw.print(":");
                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
                         pw.print(" IDLE");
                     }
diff --git a/services/core/java/com/android/server/am/BaseErrorDialog.java b/services/core/java/com/android/server/am/BaseErrorDialog.java
index 347a357..cd4d6a3 100644
--- a/services/core/java/com/android/server/am/BaseErrorDialog.java
+++ b/services/core/java/com/android/server/am/BaseErrorDialog.java
@@ -33,7 +33,7 @@
     private boolean mConsuming = true;
 
     public BaseErrorDialog(Context context) {
-        super(context, com.android.internal.R.style.Theme_Dialog_AppError);
+        super(context, com.android.internal.R.style.Theme_DeviceDefault_Dialog_AppError);
         context.assertRuntimeOverlayThemable();
 
         getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index 1b688a6..76c191d 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -26,8 +26,8 @@
 import android.util.Slog;
 import android.util.Spline;
 
-import com.android.internal.util.Preconditions;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
 import com.android.server.display.utils.Plog;
 
 import java.io.PrintWriter;
@@ -77,8 +77,8 @@
                 Slog.w(TAG, "Screen brightness mapping does not cover whole range of available " +
                         "backlight values, autobrightness functionality may be impaired.");
             }
-            BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
-            builder.setCurve(luxLevels, brightnessLevelsNits);
+            BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder(
+                    luxLevels, brightnessLevelsNits);
             return new PhysicalMappingStrategy(builder.build(), nitsRange, backlightRange,
                     autoBrightnessAdjustmentMaxGamma);
         } else if (isValidMapping(luxLevels, brightnessLevelsBacklight)) {
diff --git a/services/core/java/com/android/server/InputContentUriTokenHandler.java b/services/core/java/com/android/server/inputmethod/InputContentUriTokenHandler.java
similarity index 97%
rename from services/core/java/com/android/server/InputContentUriTokenHandler.java
rename to services/core/java/com/android/server/inputmethod/InputContentUriTokenHandler.java
index 6338b2f..845fca1 100644
--- a/services/core/java/com/android/server/InputContentUriTokenHandler.java
+++ b/services/core/java/com/android/server/inputmethod/InputContentUriTokenHandler.java
@@ -14,11 +14,10 @@
 ** limitations under the License.
 */
 
-package com.android.server;
+package com.android.server.inputmethod;
 
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
-import android.app.ActivityManager;
 import android.app.UriGrantsManager;
 import android.content.Intent;
 import android.net.Uri;
@@ -28,6 +27,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.inputmethod.IInputContentUriToken;
+import com.android.server.LocalServices;
 import com.android.server.uri.UriGrantsManagerInternal;
 
 final class InputContentUriTokenHandler extends IInputContentUriToken.Stub {
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
similarity index 99%
rename from services/core/java/com/android/server/InputMethodManagerService.java
rename to services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index e435a4f..49f33e0 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -13,7 +13,7 @@
  * the License.
  */
 
-package com.android.server;
+package com.android.server.inputmethod;
 
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
@@ -149,7 +149,9 @@
 import com.android.internal.view.IInputSessionCallback;
 import com.android.internal.view.InputBindResult;
 import com.android.internal.view.InputMethodClient;
-import com.android.server.inputmethod.InputMethodManagerInternal;
+import com.android.server.EventLogTags;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
 import com.android.server.statusbar.StatusBarManagerService;
 import com.android.server.wm.WindowManagerInternal;
 
@@ -253,7 +255,7 @@
      * the notification.
      */
     private static final String ACTION_SHOW_INPUT_METHOD_PICKER =
-            "com.android.server.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER";
+            "com.android.server.inputmethod.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER";
 
     /**
      * Debug flag for overriding runtime {@link SystemProperties}.
diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
index b4bc7f5..452b699 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
@@ -46,9 +46,9 @@
     static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
 
     private static final int MAX_LOG_SIZE =
-            ActivityManager.isLowRamDeviceStatic() ? 20 : 50;
+            ActivityManager.isLowRamDeviceStatic() ? 100 : 400;
     private static final int MAX_NETWORK_BLOCKED_LOG_SIZE =
-            ActivityManager.isLowRamDeviceStatic() ? 50 : 100;
+            ActivityManager.isLowRamDeviceStatic() ? 100 : 400;
 
     private static final int EVENT_TYPE_GENERIC = 0;
     private static final int EVENT_NETWORK_BLOCKED = 1;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 76f9695..48e09d7 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -796,7 +796,7 @@
             try {
                 mActivityManager.registerUidObserver(mUidObserver,
                         ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE,
-                        ActivityManager.PROCESS_STATE_UNKNOWN, null);
+                        NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE, "android");
                 mNetworkManager.registerObserver(mAlertObserver);
             } catch (RemoteException e) {
                 // ignored; both services live in system_server
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 340ae0a..7751f5f 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -694,7 +694,8 @@
 
             for (int userId : userIds) {
                 if (enabled) {
-                    if (isPackageOrComponentAllowed(component.toString(), userId)) {
+                    if (isPackageOrComponentAllowed(component.toString(), userId)
+                            || isPackageOrComponentAllowed(component.getPackageName(), userId)) {
                         registerServiceLocked(component, userId);
                     } else {
                         Slog.d(TAG, component + " no longer has permission to be bound");
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 593e7cd..13ff6e8 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -107,7 +107,7 @@
     }
 
     // pkg|uid => PackagePreferences
-    private final ArrayMap<String, PackagePreferences> mPackagePreferencess = new ArrayMap<>();
+    private final ArrayMap<String, PackagePreferences> mPackagePreferences = new ArrayMap<>();
     // pkg => PackagePreferences
     private final ArrayMap<String, PackagePreferences> mRestoredWithoutUids = new ArrayMap<>();
 
@@ -142,109 +142,117 @@
         if (type != XmlPullParser.START_TAG) return;
         String tag = parser.getName();
         if (!TAG_RANKING.equals(tag)) return;
-        // Clobber groups and channels with the xml, but don't delete other data that wasn't present
-        // at the time of serialization.
-        mRestoredWithoutUids.clear();
-        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
-            tag = parser.getName();
-            if (type == XmlPullParser.END_TAG && TAG_RANKING.equals(tag)) {
-                return;
-            }
-            if (type == XmlPullParser.START_TAG) {
-                if (TAG_PACKAGE.equals(tag)) {
-                    int uid = XmlUtils.readIntAttribute(parser, ATT_UID, UNKNOWN_UID);
-                    String name = parser.getAttributeValue(null, ATT_NAME);
-                    if (!TextUtils.isEmpty(name)) {
-                        if (forRestore) {
-                            try {
-                                //TODO: http://b/22388012
-                                uid = mPm.getPackageUidAsUser(name,
-                                        UserHandle.USER_SYSTEM);
-                            } catch (PackageManager.NameNotFoundException e) {
-                                // noop
-                            }
-                        }
+        synchronized (mPackagePreferences) {
+            // Clobber groups and channels with the xml, but don't delete other data that wasn't present
 
-                        PackagePreferences r = getOrCreatePackagePreferences(name, uid,
-                                XmlUtils.readIntAttribute(
-                                        parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE),
-                                XmlUtils.readIntAttribute(parser, ATT_PRIORITY, DEFAULT_PRIORITY),
-                                XmlUtils.readIntAttribute(
-                                        parser, ATT_VISIBILITY, DEFAULT_VISIBILITY),
-                                XmlUtils.readBooleanAttribute(
-                                        parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE));
-                        r.importance = XmlUtils.readIntAttribute(
-                                parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
-                        r.priority = XmlUtils.readIntAttribute(
-                                parser, ATT_PRIORITY, DEFAULT_PRIORITY);
-                        r.visibility = XmlUtils.readIntAttribute(
-                                parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
-                        r.showBadge = XmlUtils.readBooleanAttribute(
-                                parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE);
-                        r.lockedAppFields = XmlUtils.readIntAttribute(parser,
-                                ATT_APP_USER_LOCKED_FIELDS, DEFAULT_LOCKED_APP_FIELDS);
-
-                        final int innerDepth = parser.getDepth();
-                        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
-                                && (type != XmlPullParser.END_TAG
-                                || parser.getDepth() > innerDepth)) {
-                            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
-                                continue;
-                            }
-
-                            String tagName = parser.getName();
-                            // Channel groups
-                            if (TAG_GROUP.equals(tagName)) {
-                                String id = parser.getAttributeValue(null, ATT_ID);
-                                CharSequence groupName = parser.getAttributeValue(null, ATT_NAME);
-                                if (!TextUtils.isEmpty(id)) {
-                                    NotificationChannelGroup group
-                                            = new NotificationChannelGroup(id, groupName);
-                                    group.populateFromXml(parser);
-                                    r.groups.put(id, group);
+            // at the time of serialization.
+            mRestoredWithoutUids.clear();
+            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+                tag = parser.getName();
+                if (type == XmlPullParser.END_TAG && TAG_RANKING.equals(tag)) {
+                    return;
+                }
+                if (type == XmlPullParser.START_TAG) {
+                    if (TAG_PACKAGE.equals(tag)) {
+                        int uid = XmlUtils.readIntAttribute(parser, ATT_UID, UNKNOWN_UID);
+                        String name = parser.getAttributeValue(null, ATT_NAME);
+                        if (!TextUtils.isEmpty(name)) {
+                            if (forRestore) {
+                                try {
+                                    //TODO: http://b/22388012
+                                    uid = mPm.getPackageUidAsUser(name,
+                                            UserHandle.USER_SYSTEM);
+                                } catch (PackageManager.NameNotFoundException e) {
+                                    // noop
                                 }
                             }
-                            // Channels
-                            if (TAG_CHANNEL.equals(tagName)) {
-                                String id = parser.getAttributeValue(null, ATT_ID);
-                                String channelName = parser.getAttributeValue(null, ATT_NAME);
-                                int channelImportance = XmlUtils.readIntAttribute(
-                                        parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
-                                if (!TextUtils.isEmpty(id) && !TextUtils.isEmpty(channelName)) {
-                                    NotificationChannel channel = new NotificationChannel(id,
-                                            channelName, channelImportance);
-                                    if (forRestore) {
-                                        channel.populateFromXmlForRestore(parser, mContext);
-                                    } else {
-                                        channel.populateFromXml(parser);
+
+                            PackagePreferences r = getOrCreatePackagePreferences(name, uid,
+                                    XmlUtils.readIntAttribute(
+                                            parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE),
+                                    XmlUtils.readIntAttribute(parser, ATT_PRIORITY,
+                                            DEFAULT_PRIORITY),
+                                    XmlUtils.readIntAttribute(
+                                            parser, ATT_VISIBILITY, DEFAULT_VISIBILITY),
+                                    XmlUtils.readBooleanAttribute(
+                                            parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE));
+                            r.importance = XmlUtils.readIntAttribute(
+                                    parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
+                            r.priority = XmlUtils.readIntAttribute(
+                                    parser, ATT_PRIORITY, DEFAULT_PRIORITY);
+                            r.visibility = XmlUtils.readIntAttribute(
+                                    parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
+                            r.showBadge = XmlUtils.readBooleanAttribute(
+                                    parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE);
+                            r.lockedAppFields = XmlUtils.readIntAttribute(parser,
+                                    ATT_APP_USER_LOCKED_FIELDS, DEFAULT_LOCKED_APP_FIELDS);
+
+                            final int innerDepth = parser.getDepth();
+                            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                                    && (type != XmlPullParser.END_TAG
+                                    || parser.getDepth() > innerDepth)) {
+                                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                                    continue;
+                                }
+
+                                String tagName = parser.getName();
+                                // Channel groups
+                                if (TAG_GROUP.equals(tagName)) {
+                                    String id = parser.getAttributeValue(null, ATT_ID);
+                                    CharSequence groupName = parser.getAttributeValue(null,
+                                            ATT_NAME);
+                                    if (!TextUtils.isEmpty(id)) {
+                                        NotificationChannelGroup group
+                                                = new NotificationChannelGroup(id, groupName);
+                                        group.populateFromXml(parser);
+                                        r.groups.put(id, group);
                                     }
-                                    r.channels.put(id, channel);
                                 }
-                            }
-                            // Delegate
-                            if (TAG_DELEGATE.equals(tagName)) {
-                                int delegateId =
-                                        XmlUtils.readIntAttribute(parser, ATT_UID, UNKNOWN_UID);
-                                String delegateName =
-                                        XmlUtils.readStringAttribute(parser, ATT_NAME);
-                                boolean delegateEnabled = XmlUtils.readBooleanAttribute(
-                                        parser, ATT_ENABLED, Delegate.DEFAULT_ENABLED);
-                                boolean userAllowed = XmlUtils.readBooleanAttribute(
-                                        parser, ATT_USER_ALLOWED, Delegate.DEFAULT_USER_ALLOWED);
-                                Delegate d = null;
-                                if (delegateId != UNKNOWN_UID && !TextUtils.isEmpty(delegateName)) {
-                                    d = new Delegate(
-                                            delegateName, delegateId, delegateEnabled, userAllowed);
+                                // Channels
+                                if (TAG_CHANNEL.equals(tagName)) {
+                                    String id = parser.getAttributeValue(null, ATT_ID);
+                                    String channelName = parser.getAttributeValue(null, ATT_NAME);
+                                    int channelImportance = XmlUtils.readIntAttribute(
+                                            parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
+                                    if (!TextUtils.isEmpty(id) && !TextUtils.isEmpty(channelName)) {
+                                        NotificationChannel channel = new NotificationChannel(id,
+                                                channelName, channelImportance);
+                                        if (forRestore) {
+                                            channel.populateFromXmlForRestore(parser, mContext);
+                                        } else {
+                                            channel.populateFromXml(parser);
+                                        }
+                                        r.channels.put(id, channel);
+                                    }
                                 }
-                                r.delegate = d;
+                                // Delegate
+                                if (TAG_DELEGATE.equals(tagName)) {
+                                    int delegateId =
+                                            XmlUtils.readIntAttribute(parser, ATT_UID, UNKNOWN_UID);
+                                    String delegateName =
+                                            XmlUtils.readStringAttribute(parser, ATT_NAME);
+                                    boolean delegateEnabled = XmlUtils.readBooleanAttribute(
+                                            parser, ATT_ENABLED, Delegate.DEFAULT_ENABLED);
+                                    boolean userAllowed = XmlUtils.readBooleanAttribute(
+                                            parser, ATT_USER_ALLOWED,
+                                            Delegate.DEFAULT_USER_ALLOWED);
+                                    Delegate d = null;
+                                    if (delegateId != UNKNOWN_UID && !TextUtils.isEmpty(
+                                            delegateName)) {
+                                        d = new Delegate(
+                                                delegateName, delegateId, delegateEnabled,
+                                                userAllowed);
+                                    }
+                                    r.delegate = d;
+                                }
+
                             }
 
-                        }
-
-                        try {
-                            deleteDefaultChannelIfNeeded(r);
-                        } catch (PackageManager.NameNotFoundException e) {
-                            Slog.e(TAG, "deleteDefaultChannelIfNeeded - Exception: " + e);
+                            try {
+                                deleteDefaultChannelIfNeeded(r);
+                            } catch (PackageManager.NameNotFoundException e) {
+                                Slog.e(TAG, "deleteDefaultChannelIfNeeded - Exception: " + e);
+                            }
                         }
                     }
                 }
@@ -255,8 +263,8 @@
 
     private PackagePreferences getPackagePreferences(String pkg, int uid) {
         final String key = packagePreferencesKey(pkg, uid);
-        synchronized (mPackagePreferencess) {
-            return mPackagePreferencess.get(key);
+        synchronized (mPackagePreferences) {
+            return mPackagePreferences.get(key);
         }
     }
 
@@ -268,10 +276,10 @@
     private PackagePreferences getOrCreatePackagePreferences(String pkg, int uid, int importance,
             int priority, int visibility, boolean showBadge) {
         final String key = packagePreferencesKey(pkg, uid);
-        synchronized (mPackagePreferencess) {
+        synchronized (mPackagePreferences) {
             PackagePreferences
                     r = (uid == UNKNOWN_UID) ? mRestoredWithoutUids.get(pkg)
-                    : mPackagePreferencess.get(key);
+                    : mPackagePreferences.get(key);
             if (r == null) {
                 r = new PackagePreferences();
                 r.pkg = pkg;
@@ -290,7 +298,7 @@
                 if (r.uid == UNKNOWN_UID) {
                     mRestoredWithoutUids.put(pkg, r);
                 } else {
-                    mPackagePreferencess.put(key, r);
+                    mPackagePreferences.put(key, r);
                 }
             }
             return r;
@@ -364,10 +372,10 @@
         out.startTag(null, TAG_RANKING);
         out.attribute(null, ATT_VERSION, Integer.toString(XML_VERSION));
 
-        synchronized (mPackagePreferencess) {
-            final int N = mPackagePreferencess.size();
+        synchronized (mPackagePreferences) {
+            final int N = mPackagePreferences.size();
             for (int i = 0; i < N; i++) {
-                final PackagePreferences r = mPackagePreferencess.valueAt(i);
+                final PackagePreferences r = mPackagePreferences.valueAt(i);
                 //TODO: http://b/22388012
                 if (forBackup && UserHandle.getUserId(r.uid) != UserHandle.USER_SYSTEM) {
                     continue;
@@ -882,10 +890,10 @@
 
     public int getBlockedAppCount(int userId) {
         int count = 0;
-        synchronized (mPackagePreferencess) {
-            final int N = mPackagePreferencess.size();
+        synchronized (mPackagePreferences) {
+            final int N = mPackagePreferences.size();
             for (int i = 0; i < N; i++) {
-                final PackagePreferences r = mPackagePreferencess.valueAt(i);
+                final PackagePreferences r = mPackagePreferences.valueAt(i);
                 if (userId == UserHandle.getUserId(r.uid)
                         && r.importance == IMPORTANCE_NONE) {
                     count++;
@@ -896,11 +904,11 @@
     }
 
     public void updateChannelsBypassingDnd() {
-        synchronized (mPackagePreferencess) {
-            final int numPackagePreferencess = mPackagePreferencess.size();
+        synchronized (mPackagePreferences) {
+            final int numPackagePreferencess = mPackagePreferences.size();
             for (int PackagePreferencesIndex = 0; PackagePreferencesIndex < numPackagePreferencess;
                     PackagePreferencesIndex++) {
-                final PackagePreferences r = mPackagePreferencess.valueAt(PackagePreferencesIndex);
+                final PackagePreferences r = mPackagePreferences.valueAt(PackagePreferencesIndex);
                 final int numChannels = r.channels.size();
 
                 for (int channelIndex = 0; channelIndex < numChannels; channelIndex++) {
@@ -1064,8 +1072,8 @@
         pw.println("per-package config:");
 
         pw.println("PackagePreferencess:");
-        synchronized (mPackagePreferencess) {
-            dumpPackagePreferencess(pw, prefix, filter, mPackagePreferencess);
+        synchronized (mPackagePreferences) {
+            dumpPackagePreferencess(pw, prefix, filter, mPackagePreferences);
         }
         pw.println("Restored without uid:");
         dumpPackagePreferencess(pw, prefix, filter, mRestoredWithoutUids);
@@ -1073,9 +1081,9 @@
 
     public void dump(ProtoOutputStream proto,
             @NonNull NotificationManagerService.DumpFilter filter) {
-        synchronized (mPackagePreferencess) {
+        synchronized (mPackagePreferences) {
             dumpPackagePreferencess(proto, RankingHelperProto.RECORDS, filter,
-                    mPackagePreferencess);
+                    mPackagePreferences);
         }
         dumpPackagePreferencess(proto, RankingHelperProto.RECORDS_RESTORED_WITHOUT_UID, filter,
                 mRestoredWithoutUids);
@@ -1160,10 +1168,10 @@
         } catch (JSONException e) {
             // pass
         }
-        synchronized (mPackagePreferencess) {
-            final int N = mPackagePreferencess.size();
+        synchronized (mPackagePreferences) {
+            final int N = mPackagePreferences.size();
             for (int i = 0; i < N; i++) {
-                final PackagePreferences r = mPackagePreferencess.valueAt(i);
+                final PackagePreferences r = mPackagePreferences.valueAt(i);
                 if (filter == null || filter.matches(r.pkg)) {
                     JSONObject PackagePreferences = new JSONObject();
                     try {
@@ -1240,11 +1248,11 @@
     }
 
     public Map<Integer, String> getPackageBans() {
-        synchronized (mPackagePreferencess) {
-            final int N = mPackagePreferencess.size();
+        synchronized (mPackagePreferences) {
+            final int N = mPackagePreferences.size();
             ArrayMap<Integer, String> packageBans = new ArrayMap<>(N);
             for (int i = 0; i < N; i++) {
-                final PackagePreferences r = mPackagePreferencess.valueAt(i);
+                final PackagePreferences r = mPackagePreferences.valueAt(i);
                 if (r.importance == IMPORTANCE_NONE) {
                     packageBans.put(r.uid, r.pkg);
                 }
@@ -1284,9 +1292,9 @@
 
     private Map<String, Integer> getPackageChannels() {
         ArrayMap<String, Integer> packageChannels = new ArrayMap<>();
-        synchronized (mPackagePreferencess) {
-            for (int i = 0; i < mPackagePreferencess.size(); i++) {
-                final PackagePreferences r = mPackagePreferencess.valueAt(i);
+        synchronized (mPackagePreferences) {
+            for (int i = 0; i < mPackagePreferences.size(); i++) {
+                final PackagePreferences r = mPackagePreferences.valueAt(i);
                 int channelCount = 0;
                 for (int j = 0; j < r.channels.size(); j++) {
                     if (!r.channels.valueAt(j).isDeleted()) {
@@ -1300,22 +1308,22 @@
     }
 
     public void onUserRemoved(int userId) {
-        synchronized (mPackagePreferencess) {
-            int N = mPackagePreferencess.size();
+        synchronized (mPackagePreferences) {
+            int N = mPackagePreferences.size();
             for (int i = N - 1; i >= 0; i--) {
-                PackagePreferences PackagePreferences = mPackagePreferencess.valueAt(i);
+                PackagePreferences PackagePreferences = mPackagePreferences.valueAt(i);
                 if (UserHandle.getUserId(PackagePreferences.uid) == userId) {
-                    mPackagePreferencess.removeAt(i);
+                    mPackagePreferences.removeAt(i);
                 }
             }
         }
     }
 
     protected void onLocaleChanged(Context context, int userId) {
-        synchronized (mPackagePreferencess) {
-            int N = mPackagePreferencess.size();
+        synchronized (mPackagePreferences) {
+            int N = mPackagePreferences.size();
             for (int i = 0; i < N; i++) {
-                PackagePreferences PackagePreferences = mPackagePreferencess.valueAt(i);
+                PackagePreferences PackagePreferences = mPackagePreferences.valueAt(i);
                 if (UserHandle.getUserId(PackagePreferences.uid) == userId) {
                     if (PackagePreferences.channels.containsKey(
                             NotificationChannel.DEFAULT_CHANNEL_ID)) {
@@ -1341,8 +1349,8 @@
             for (int i = 0; i < size; i++) {
                 final String pkg = pkgList[i];
                 final int uid = uidList[i];
-                synchronized (mPackagePreferencess) {
-                    mPackagePreferencess.remove(packagePreferencesKey(pkg, uid));
+                synchronized (mPackagePreferences) {
+                    mPackagePreferences.remove(packagePreferencesKey(pkg, uid));
                 }
                 mRestoredWithoutUids.remove(pkg);
                 updated = true;
@@ -1355,8 +1363,8 @@
                     try {
                         r.uid = mPm.getPackageUidAsUser(r.pkg, changeUserId);
                         mRestoredWithoutUids.remove(pkg);
-                        synchronized (mPackagePreferencess) {
-                            mPackagePreferencess.put(packagePreferencesKey(r.pkg, r.uid), r);
+                        synchronized (mPackagePreferences) {
+                            mPackagePreferences.put(packagePreferencesKey(r.pkg, r.uid), r);
                         }
                         updated = true;
                     } catch (PackageManager.NameNotFoundException e) {
@@ -1365,11 +1373,13 @@
                 }
                 // Package upgrade
                 try {
-                    PackagePreferences fullPackagePreferences = getPackagePreferences(pkg,
-                            mPm.getPackageUidAsUser(pkg, changeUserId));
-                    if (fullPackagePreferences != null) {
-                        createDefaultChannelIfNeeded(fullPackagePreferences);
-                        deleteDefaultChannelIfNeeded(fullPackagePreferences);
+                    synchronized (mPackagePreferences) {
+                        PackagePreferences fullPackagePreferences = getPackagePreferences(pkg,
+                                mPm.getPackageUidAsUser(pkg, changeUserId));
+                        if (fullPackagePreferences != null) {
+                            createDefaultChannelIfNeeded(fullPackagePreferences);
+                            deleteDefaultChannelIfNeeded(fullPackagePreferences);
+                        }
                     }
                 } catch (PackageManager.NameNotFoundException e) {
                 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index df680f2..ac496a8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -356,8 +356,8 @@
     /**
      * Notifies WindowManagerService that the current IME window status is being changed.
      *
-     * <p>Only {@link com.android.server.InputMethodManagerService} is the expected and tested
-     * caller of this method.</p>
+     * <p>Only {@link com.android.server.inputmethod.InputMethodManagerService} is the expected and
+     * tested caller of this method.</p>
      *
      * @param imeToken token to track the active input method. Corresponding IME windows can be
      *                 identified by checking {@link android.view.WindowManager.LayoutParams#token}.
@@ -376,8 +376,8 @@
     /**
      * Notifies WindowManagerService that the current IME window status is being changed.
      *
-     * <p>Only {@link com.android.server.InputMethodManagerService} is the expected and tested
-     * caller of this method.</p>
+     * <p>Only {@link com.android.server.inputmethod.InputMethodManagerService} is the expected and
+     * tested caller of this method.</p>
      *
      * @param imeToken token to track the active input method. Corresponding IME windows can be
      *                 identified by checking {@link android.view.WindowManager.LayoutParams#token}.
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0b6a33f..c80b9d8 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -82,6 +82,7 @@
 import com.android.server.biometrics.fingerprint.FingerprintService;
 import com.android.server.hdmi.HdmiControlService;
 import com.android.server.input.InputManagerService;
+import com.android.server.inputmethod.InputMethodManagerService;
 import com.android.server.job.JobSchedulerService;
 import com.android.server.lights.LightsService;
 import com.android.server.media.MediaResourceMonitorService;
diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java
index ccc092d..0176dd4 100644
--- a/services/net/java/android/net/ip/IpClient.java
+++ b/services/net/java/android/net/ip/IpClient.java
@@ -228,6 +228,9 @@
     //       Encourages logging of any available arguments, and all call sites
     //       are necessarily logged identically.
     //
+    // NOTE: Log first because passed objects may or may not be thread-safe and
+    // once passed on to the callback they may be modified by another thread.
+    //
     // TODO: Find an lighter weight approach.
     private class LoggingCallbackWrapper extends Callback {
         private static final String PREFIX = "INVOKE ";
@@ -243,63 +246,63 @@
 
         @Override
         public void onPreDhcpAction() {
-            mCallback.onPreDhcpAction();
             log("onPreDhcpAction()");
+            mCallback.onPreDhcpAction();
         }
         @Override
         public void onPostDhcpAction() {
-            mCallback.onPostDhcpAction();
             log("onPostDhcpAction()");
+            mCallback.onPostDhcpAction();
         }
         @Override
         public void onNewDhcpResults(DhcpResults dhcpResults) {
-            mCallback.onNewDhcpResults(dhcpResults);
             log("onNewDhcpResults({" + dhcpResults + "})");
+            mCallback.onNewDhcpResults(dhcpResults);
         }
         @Override
         public void onProvisioningSuccess(LinkProperties newLp) {
-            mCallback.onProvisioningSuccess(newLp);
             log("onProvisioningSuccess({" + newLp + "})");
+            mCallback.onProvisioningSuccess(newLp);
         }
         @Override
         public void onProvisioningFailure(LinkProperties newLp) {
-            mCallback.onProvisioningFailure(newLp);
             log("onProvisioningFailure({" + newLp + "})");
+            mCallback.onProvisioningFailure(newLp);
         }
         @Override
         public void onLinkPropertiesChange(LinkProperties newLp) {
-            mCallback.onLinkPropertiesChange(newLp);
             log("onLinkPropertiesChange({" + newLp + "})");
+            mCallback.onLinkPropertiesChange(newLp);
         }
         @Override
         public void onReachabilityLost(String logMsg) {
-            mCallback.onReachabilityLost(logMsg);
             log("onReachabilityLost(" + logMsg + ")");
+            mCallback.onReachabilityLost(logMsg);
         }
         @Override
         public void onQuit() {
-            mCallback.onQuit();
             log("onQuit()");
+            mCallback.onQuit();
         }
         @Override
         public void installPacketFilter(byte[] filter) {
-            mCallback.installPacketFilter(filter);
             log("installPacketFilter(byte[" + filter.length + "])");
+            mCallback.installPacketFilter(filter);
         }
         @Override
         public void startReadPacketFilter() {
-            mCallback.startReadPacketFilter();
             log("startReadPacketFilter()");
+            mCallback.startReadPacketFilter();
         }
         @Override
         public void setFallbackMulticastFilter(boolean enabled) {
-            mCallback.setFallbackMulticastFilter(enabled);
             log("setFallbackMulticastFilter(" + enabled + ")");
+            mCallback.setFallbackMulticastFilter(enabled);
         }
         @Override
         public void setNeighborDiscoveryOffload(boolean enable) {
-            mCallback.setNeighborDiscoveryOffload(enable);
             log("setNeighborDiscoveryOffload(" + enable + ")");
+            mCallback.setNeighborDiscoveryOffload(enable);
         }
     }
 
diff --git a/services/robotests/Android.mk b/services/robotests/Android.mk
index 2691701..8b59771 100644
--- a/services/robotests/Android.mk
+++ b/services/robotests/Android.mk
@@ -75,6 +75,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
     platform-robolectric-android-all-stubs \
     android-support-test \
+    guava \
     mockito-robolectric-prebuilt \
     platform-test-annotations \
     truth-prebuilt \
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java
new file mode 100644
index 0000000..3b6e038
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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 com.android.server.backup.encryption.chunk;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+import com.google.common.primitives.Bytes;
+import java.util.Arrays;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class ChunkHashTest {
+    private static final int HASH_LENGTH_BYTES = 256 / 8;
+    private static final byte[] TEST_HASH_1 = Arrays.copyOf(new byte[] {1}, HASH_LENGTH_BYTES);
+    private static final byte[] TEST_HASH_2 = Arrays.copyOf(new byte[] {2}, HASH_LENGTH_BYTES);
+
+    @Test
+    public void testGetHash_returnsHash() {
+        ChunkHash chunkHash = new ChunkHash(TEST_HASH_1);
+
+        byte[] hash = chunkHash.getHash();
+
+        assertThat(hash).asList().containsExactlyElementsIn(Bytes.asList(TEST_HASH_1)).inOrder();
+    }
+
+    @Test
+    public void testEquals() {
+        ChunkHash chunkHash1 = new ChunkHash(TEST_HASH_1);
+        ChunkHash equalChunkHash1 = new ChunkHash(TEST_HASH_1);
+        ChunkHash chunkHash2 = new ChunkHash(TEST_HASH_2);
+
+        assertThat(chunkHash1).isEqualTo(equalChunkHash1);
+        assertThat(chunkHash1).isNotEqualTo(chunkHash2);
+    }
+
+    @Test
+    public void testHashCode() {
+        ChunkHash chunkHash1 = new ChunkHash(TEST_HASH_1);
+        ChunkHash equalChunkHash1 = new ChunkHash(TEST_HASH_1);
+        ChunkHash chunkHash2 = new ChunkHash(TEST_HASH_2);
+
+        int hash1 = chunkHash1.hashCode();
+        int equalHash1 = equalChunkHash1.hashCode();
+        int hash2 = chunkHash2.hashCode();
+
+        assertThat(hash1).isEqualTo(equalHash1);
+        assertThat(hash1).isNotEqualTo(hash2);
+    }
+
+    @Test
+    public void testCompareTo_whenEqual_returnsZero() {
+        ChunkHash chunkHash = new ChunkHash(TEST_HASH_1);
+        ChunkHash equalChunkHash = new ChunkHash(TEST_HASH_1);
+
+        int result = chunkHash.compareTo(equalChunkHash);
+
+        assertThat(result).isEqualTo(0);
+    }
+
+    @Test
+    public void testCompareTo_whenArgumentGreater_returnsNegative() {
+        ChunkHash chunkHash1 = new ChunkHash(TEST_HASH_1);
+        ChunkHash chunkHash2 = new ChunkHash(TEST_HASH_2);
+
+        int result = chunkHash1.compareTo(chunkHash2);
+
+        assertThat(result).isLessThan(0);
+    }
+
+    @Test
+    public void testCompareTo_whenArgumentSmaller_returnsPositive() {
+        ChunkHash chunkHash1 = new ChunkHash(TEST_HASH_1);
+        ChunkHash chunkHash2 = new ChunkHash(TEST_HASH_2);
+
+        int result = chunkHash2.compareTo(chunkHash1);
+
+        assertThat(result).isGreaterThan(0);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index eb28e1a..1eb88ba 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -100,6 +100,7 @@
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
 import android.net.NetworkState;
 import android.net.NetworkStats;
 import android.net.NetworkStatsHistory;
@@ -365,7 +366,7 @@
                 return null;
             }
         }).when(mActivityManager).registerUidObserver(any(), anyInt(),
-                eq(ActivityManager.PROCESS_STATE_UNKNOWN), isNull(String.class));
+                eq(NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE), isNull(String.class));
 
         mFutureIntent = newRestrictBackgroundChangedFuture();
         mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager,
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
index e6ca03b..48dda01 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
@@ -152,8 +152,7 @@
         final float[] lux = { 0f, 1f };
         final float[] nits = { 0, PowerManager.BRIGHTNESS_ON };
 
-        BrightnessConfiguration config = new BrightnessConfiguration.Builder()
-                .setCurve(lux, nits)
+        BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits)
                 .build();
         strategy.setBrightnessConfiguration(config);
         assertNotEquals(1.0f, strategy.getBrightness(1f), 0.01 /*tolerance*/);
@@ -214,8 +213,7 @@
                 DISPLAY_RANGE_NITS[DISPLAY_RANGE_NITS.length - 1]
         };
 
-        BrightnessConfiguration config = new BrightnessConfiguration.Builder()
-                .setCurve(lux, nits)
+        BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits)
                 .build();
         strategy.setBrightnessConfiguration(config);
         assertEquals(1.0f, strategy.getBrightness(1f), 0.01 /*tolerance*/);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 1d9e605..8ebfec4 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1589,12 +1589,14 @@
     }
 
     /**
-     * @return true if a valid subId else false
-     * @hide
+     * Checks if the supplied subscription ID is valid.
+     * Note: a valid subscription ID does not necessarily correspond to an active subscription.
+     *
+     * @param subscriptionId The subscription ID.
+     * @return true if the supplied subscriptionId is valid; false otherwise.
      */
-    @UnsupportedAppUsage
-    public static boolean isValidSubscriptionId(int subId) {
-        return subId > INVALID_SUBSCRIPTION_ID ;
+    public static boolean isValidSubscriptionId(int subscriptionId) {
+        return subscriptionId > INVALID_SUBSCRIPTION_ID;
     }
 
     /**
diff --git a/tools/aosp/aosp_sha.sh b/tools/aosp/aosp_sha.sh
index 29bf74c..e50c70d 100755
--- a/tools/aosp/aosp_sha.sh
+++ b/tools/aosp/aosp_sha.sh
@@ -1,18 +1,24 @@
 #!/bin/bash
-LOCAL_DIR="$( dirname ${BASH_SOURCE} )"
+LOCAL_DIR="$( dirname "${BASH_SOURCE}" )"
 
-if git branch -vv | grep "^*" | grep "\[aosp/master" > /dev/null; then
+if git branch -vv | grep -q -P "^\*[^\[]+\[aosp/"; then
     # Change appears to be in AOSP
     exit 0
 else
     # Change appears to be non-AOSP; search for files
-    git show --name-only --pretty=format: $1 | grep $2 | while read file; do
-        echo
+    count=0
+    while read -r file ; do
+        if (( count == 0 )); then
+            echo
+        fi
         echo -e "\033[0;31mThe source of truth for '$file' is in AOSP.\033[0m"
+        (( count++ ))
+    done < <(git show --name-only --pretty=format: $1 | grep -- "$2")
+    if (( count != 0 )); then
         echo
-        echo "If your change contains no confidential details, please upload and merge"
-        echo "this change at https://android-review.googlesource.com/."
+        echo "If your change contains no confidential details (such as security fixes), please"
+        echo "upload and merge this change at https://android-review.googlesource.com/."
         echo
         exit 77
-    done
+    fi
 fi